// Puts the current goroutine into a waiting state and unlocks the lock. // The goroutine can be made runnable again by calling runtime·ready(gp). void runtime·park(void (*unlockf)(Lock*), Lock *lock, int8 *reason) { g->status = Gwaiting; g->waitreason = reason; if(unlockf) unlockf(lock); runtime·gosched(); }
static void do_bast(struct lk *lk) { int skip = 0; if (lk->lastop == Op_unlock || lk->lastop == Op_unlockf) { skip = 1; } if (!lk->lksb.sb_lkid) { skip = 1; } if (skip) { bast_skip++; log_bast(" bast: skip %3d\t%x\n", lk->id, lk->lksb.sb_lkid); } else { bast_unlock++; log_bast(" bast: unlockf %3d\t%x\n", lk->id, lk->lksb.sb_lkid); unlockf(lk->id); } lk->bast = 0; }
void tloop(int history) { using_history(); stifle_history(history); lookf(self.next); while(1){ int fail = 0; struct tobj *prev = NULL; struct tobj *noun = NULL; char *input = readline(">> "); char *verbstr = input; char *nounstr = verbstr; add_history(verbstr); /* Blank out spaces and punctuation and set the noun as the last word */ while(*input){ if(!isalpha(*input)){ *input = '\0'; if(isalpha(*(input + 1))){ nounstr = input + 1; } } ++input; } input = verbstr; /* Restore input back to where it was */ /* Do basic substition for shortcut commands */ if(tstrequals(verbstr, 2, "n", "north")){ verbstr = "go"; nounstr = "north"; } else if(tstrequals(verbstr, 2, "ne", "northeast")){ verbstr = "go"; nounstr = "northeast"; } else if(tstrequals(verbstr, 2, "e", "east")){ verbstr = "go"; nounstr = "east"; } else if(tstrequals(verbstr, 2, "se", "southeast")){ verbstr = "go"; nounstr = "southeast"; } else if(tstrequals(verbstr, 2, "s", "south")){ verbstr = "go"; nounstr = "south"; } else if(tstrequals(verbstr, 2, "sw", "southwest")){ verbstr = "go"; nounstr = "southwest"; } else if(tstrequals(verbstr, 2, "w", "west")){ verbstr = "go"; nounstr = "west"; } else if(tstrequals(verbstr, 2, "nw", "northwest")){ verbstr = "go"; nounstr = "northwest"; } else if(tstrequals(verbstr, 1, "out")){ verbstr = "go"; nounstr = "out"; } noun = tfind(&self, &prev, nounstr); if(noun == NULL){ if(verbstr != nounstr){ if(tstrequals(verbstr, 2, "go", "travel")){ printf("You can't go ``%s'' here.\n", nounstr); } else{ printf("You don't see ``%s'' here.\n", nounstr); } fail = 1; } else{ prev = NULL; noun = self.next; } } if(!fail){ if(tstrcmp(verbstr, "look") == 0){ lookf(noun); } else if(tstrequals(verbstr, 2, "i", "inventory")){ lookf(&self); } else if(tstrequals(verbstr, 3, "eat", "consume", "ingest")){ eatf(prev, noun); } else if(tstrequals(verbstr, 2, "go", "travel")){ gof(noun); } else if(tstrequals(verbstr, 3, "drop", "leave", "abandon")){ dropf(prev, noun); } else if(tstrequals(verbstr, 3, "talk", "say", "speak")){ talkf(noun); } else if(tstrequals(verbstr, 6, "break", "smash", "kick", "punch", "headbutt", "kill")){ breakf(noun); } else if(tstrcmp(verbstr, "unlock") == 0){ unlockf(noun); } else if(tstrequals(verbstr, 2, "lock", "bar")){ lockf(noun); } else if(tstrequals(verbstr, 5, "pick", "get", "take", "steal", "pack")){ pickf(prev, noun); } else{ printf("Don't know how to ``%s.''\n", verbstr); fail = 1; } } free(input); } }
static void stress(int num) { int i, o, op, max_op, skip; unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops; struct lk *lk; n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0; sts_eunlock = sts_ecancel = sts_etimedout = sts_edeadlk = sts_eagain = sts_other = sts_zero = 0; bast_unlock = bast_skip = 0; while (!stress_stop) { if (stress_delay) usleep(stress_delay); process_libdlm(); if (++n == num) break; i = rand_int(0, maxn-1); lk = get_lock(i); if (!lk) continue; max_op = 5; if (stress_lock_only) max_op = 2; o = rand_int(0, max_op); switch (o) { case 0: case 1: case 2: op = Op_lock; break; case 3: op = Op_unlock; break; case 4: op = Op_unlockf; break; case 5: op = Op_cancel; break; default: op = 0; } skip = 0; switch (op) { case Op_lock: if (lk->wait_ast) { skip = 1; break; } noqueue = !!o; our_xid = n; lock(i, rand_int(0, 5)); lock_ops++; log_op("%8x: lock %3d\t%x\n", n, i, lk->lksb.sb_lkid); break; case Op_unlock: if (lk->wait_ast) { skip = 1; break; } if (lk->lastop == Op_unlock || lk->lastop == Op_unlockf) { skip = 1; break; } if (!lk->lksb.sb_lkid) { skip = 1; break; } unlock(i); unlock_ops++; log_op("%8x: unlock %3d\t%x\n", n, i, lk->lksb.sb_lkid); break; case Op_unlockf: if (lk->lastop == Op_unlock || lk->lastop == Op_unlockf) { skip = 1; break; } if (!lk->lksb.sb_lkid) { skip = 1; break; } unlockf(i); unlockf_ops++; log_op("%8x: unlockf %3d\t%x\n", n, i, lk->lksb.sb_lkid); break; case Op_cancel: if (!lk->wait_ast) { skip = 1; break; } if (lk->lastop > Op_lock) { skip = 1; break; } cancel(i); cancel_ops++; log_op("%8x: cancel %3d\t%x\n", n, i, lk->lksb.sb_lkid); break; } if (skip) skips++; } printf("ops: skip %d lock %d unlock %d unlockf %d cancel %d\n", skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops); printf("bast: unlock %u skip %u\n", bast_unlock, bast_skip); printf("ast status: eunlock %d ecancel %d etimedout %d edeadlk %d eagain %d\n", sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain); printf("ast status: zero %d other %d\n", sts_zero, sts_other); }
static void process_command(int *quit) { char inbuf[132]; int x = 0, y = 0; if (!opt_cmd) { fgets(inbuf, sizeof(inbuf), stdin); sscanf(inbuf, "%s %d %d", cmd, &x, &y); } if (!strncmp(cmd, "EXIT", 4)) { *quit = 1; unlock_all(); return; } if (!strncmp(cmd, "CLOSE", 5)) { *quit = 1; openclose_ls = 1; unlock_all(); return; } if (!strncmp(cmd, "kill", 4)) { printf("process exiting\n"); exit(0); } if (!strncmp(cmd, "lock", 4) && strlen(cmd) == 4) { lock(x, y); return; } if (!strncmp(cmd, "unlock", 6) && strlen(cmd) == 6) { unlock(x); return; } if (!strncmp(cmd, "unlockf", 7) && strlen(cmd) == 7) { unlockf(x); return; } if (!strncmp(cmd, "cancel", 6) && strlen(cmd) == 6) { cancel(x); return; } if (!strncmp(cmd, "canceld", 7) && strlen(cmd) == 7) { canceld(x, y); return; } if (!strncmp(cmd, "lock_sync", 9) && strlen(cmd) == 9) { lock_sync(x, y); return; } if (!strncmp(cmd, "unlock_sync", 11) && strlen(cmd) == 11) { unlock_sync(x); return; } if (!strncmp(cmd, "lock-kill", 9) && strlen(cmd) == 9) { lock(x, y); printf("process exiting\n"); exit(0); } if (!strncmp(cmd, "unlock-kill", 11) && strlen(cmd) == 11) { unlock(x); printf("process exiting\n"); exit(0); } if (!strncmp(cmd, "lock-cancel", 11) && strlen(cmd) == 11) { lock(x, y); /* usleep(1000 * z); */ cancel(x); return; } if (!strncmp(cmd, "lock-unlockf", 12) && strlen(cmd) == 12) { lock(x, y); /* usleep(1000 * z); */ unlockf(x); return; } if (!strncmp(cmd, "ex", 2)) { lock(x, LKM_EXMODE); return; } if (!strncmp(cmd, "pr", 2)) { lock(x, LKM_PRMODE); return; } if (!strncmp(cmd, "hold", 4) && strlen(cmd) == 4) { lock_all(LKM_PRMODE); return; } if (!strncmp(cmd, "hold-kill", 9) && strlen(cmd) == 9) { lock_all(LKM_PRMODE); exit(0); } if (!strncmp(cmd, "release", 7) && strlen(cmd) == 7) { unlock_all(); return; } if (!strncmp(cmd, "release-kill", 12) && strlen(cmd) == 12) { unlock_all(); exit(0); } if (!strncmp(cmd, "dump", 4) && strlen(cmd) == 4) { dump(); return; } if (!strncmp(cmd, "stress", 6) && strlen(cmd) == 6) { if (iterations && !x) x = iterations; stress(x); return; } if (!strncmp(cmd, "tstress", 7) && strlen(cmd) == 7) { tstress(x); return; } if (!strncmp(cmd, "dstress", 7) && strlen(cmd) == 7) { dstress(x); return; } if (!strncmp(cmd, "stress_delay", 12) && strlen(cmd) == 12) { stress_delay = x; return; } if (!strncmp(cmd, "stress_lock_only", 16) && strlen(cmd) == 16) { stress_lock_only = !stress_lock_only; printf("stress_lock_only is %s\n", stress_lock_only ? "on" : "off"); return; } if (!strncmp(cmd, "stress_stop", 11) && strlen(cmd) == 11) { stress_stop = !stress_stop; printf("stress_stop is %d\n", stress_stop); return; } if (!strncmp(cmd, "ignore_bast", 11) && strlen(cmd) == 11) { ignore_bast = !ignore_bast; printf("ignore_bast is %s\n", ignore_bast ? "on" : "off"); return; } if (!strncmp(cmd, "our_xid", 7) && strlen(cmd) == 7) { our_xid = x; printf("our_xid is %llx\n", (unsigned long long)our_xid); return; } if (!strncmp(cmd, "purge", 5) && strlen(cmd) == 5) { purge(x, y); return; } if (!strncmp(cmd, "purgetest", 9) && strlen(cmd) == 9) { purgetest(x, y); return; } if (!strncmp(cmd, "noqueue", 7)) { noqueue = !noqueue; printf("noqueue is %s\n", noqueue ? "on" : "off"); return; } if (!strncmp(cmd, "persistent", 10)) { persistent = !persistent; printf("persistent is %s\n", persistent ? "on" : "off"); return; } if (!strncmp(cmd, "minhold", 7)) { minhold = x; return; } if (!strncmp(cmd, "timeout", 7)) { timeout = (uint64_t) 100 * x; /* dlm takes it in centiseconds */ printf("timeout is %d\n", x); return; } if (!strncmp(cmd, "quiet", 5)) { quiet = !quiet; printf("quiet is %d\n", quiet); return; } if (!strncmp(cmd, "verbose", 7)) { verbose = !verbose; printf("verbose is %d\n", verbose); return; } if (!strncmp(cmd, "help", 4)) { print_commands(); return; } if (!strncmp(cmd, "settings", 8)) { print_settings(); return; } printf("unknown command %s\n", cmd); }