#include "stdinc.h" #include "dat.h" #include "fns.h" 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 _kickround(Round *r, int wait) { int n; if(!r->doanother) trace(TraceProc, "kick %s", r->name); r->doanother = 1; rwakeup(&r->start); if(wait){ n = r->next; while((int)(n - r->last) > 0){ r->doanother = 1; rwakeup(&r->start); rsleep(&r->finish); } } } void kickround(Round *r, int wait) { qlock(&r->lock); _kickround(r, wait); qunlock(&r->lock); } void initround(Round *r, char *name, int delay) { memset(r, 0, sizeof *r); r->name = name; r->start.l = &r->lock; r->finish.l = &r->lock; r->delaywait.l = &r->lock; r->last = 0; r->current = 0; r->next = 1; r->doanother = 0; r->delaytime = delay; } void delaykickround(Round *r) { qlock(&r->lock); r->delaykick = 1; rwakeup(&r->delaywait); qunlock(&r->lock); } void delaykickroundproc(void *v) { Round *r = v; int n; threadsetname("delaykickproc %s", r->name); qlock(&r->lock); for(;;){ while(r->delaykick == 0){ trace(TraceProc, "sleep"); rsleep(&r->delaywait); } n = r->next; qunlock(&r->lock); trace(TraceProc, "waitround 0x%ux", (uint)n); sleep(r->delaytime); qlock(&r->lock); if(n == r->next){ trace(TraceProc, "kickround 0x%ux", (uint)n); _kickround(r, 1); } trace(TraceProc, "finishround 0x%ux", (uint)n); } }