void main(void) { int64_t start, elapsed, res; static Lock l; rfork(RFNOTEG|RFREND); rStart.l = &rl; rCompleted.l = &rl; resInWaiter = 0xff; spawnWaiter(&l); lock(&l); alarm(20000); /* global timeout, FAIL if reached */ if (!atnotify(failOnTimeout, 1)){ fprint(2, "%r\n"); exits("atnotify fails"); } /* verify that lockt returns 0 on timeout */ start = nsec(); res = lockt(&l, 1000); elapsed = (nsec() - start) / (1000 * 1000); if(verbose) print("lockt returned %d, elapsed = %d ms\n", res, elapsed); if(res != 0 || elapsed < 900 || elapsed > 1300){ print("FAIL: lockt timeout\n"); exits("FAIL"); } /* verify that lockt returns 1 if the lock is released and * it can take it */ resInWaiter = -1; qlock(&rl); rwakeupall(&rStart); qunlock(&rl); sleep(1200); unlock(&l); qlock(&rl); while(elapsedInWaiter == 0) rsleep(&rCompleted); qunlock(&rl); if(resInWaiter != 1 || elapsedInWaiter < 1100 || elapsedInWaiter > 1500){ print("FAIL: lockt delayed acquisition\n"); exits("FAIL"); } print("PASS\n"); exits("PASS"); }
void waitforkick(Round *r) { int n; qlock(&r->lock); r->last = r->current; assert(r->current+1 == r->next); rwakeupall(&r->finish); while(!r->doanother) rsleep(&r->start); n = r->next++; r->current = n; r->doanother = 0; qunlock(&r->lock); }
static void queueproc(void *vq) { LumpQueue *q; Lump *u; Packet *p; int creator; uint ms; threadsetname("queueproc"); q = vq; for(;;){ qlock(&q->lock); while(q->w == q->r){ trace(TraceProc, "queueproc sleep empty"); rsleep(&q->empty); } u = q->q[q->r].u; p = q->q[q->r].p; creator = q->q[q->r].creator; ms = q->q[q->r].ms; q->r = (q->r + 1) & (MaxLumpQ - 1); trace(TraceProc, "queueproc wakeup flush"); rwakeupall(&q->flush); trace(TraceProc, "queueproc wakeup full"); rwakeup(&q->full); qunlock(&q->lock); trace(TraceProc, "queueproc writelump %V", u->score); if(writeqlump(u, p, creator, ms) < 0) fprint(2, "failed to write lump for %V: %r", u->score); trace(TraceProc, "queueproc wrotelump %V", u->score); putlump(u); } }
/* * The singly-linked non-circular list of index entries ie * has been written to disk. Move them to the clean list. */ void icacheclean(IEntry *ie) { IEntry *next; trace(TraceProc, "icacheclean enter"); qlock(&icache.lock); for(; ie; ie=next){ assert(ie->state == IEDirty); next = ie->nextdirty; ie->nextdirty = nil; popout(ie); /* from icache.dirty */ icache.ndirty--; ie->state = IEClean; pushfirst(&icache.clean, ie); } setstat(StatIcacheDirty, icache.ndirty); rwakeupall(&icache.full); qunlock(&icache.lock); trace(TraceProc, "icacheclean exit"); }