round.c (1576B)
1 #include "stdinc.h" 2 #include "dat.h" 3 #include "fns.h" 4 5 void 6 waitforkick(Round *r) 7 { 8 int n; 9 10 qlock(&r->lock); 11 r->last = r->current; 12 assert(r->current+1 == r->next); 13 rwakeupall(&r->finish); 14 while(!r->doanother) 15 rsleep(&r->start); 16 n = r->next++; 17 r->current = n; 18 r->doanother = 0; 19 qunlock(&r->lock); 20 } 21 22 static void 23 _kickround(Round *r, int wait) 24 { 25 int n; 26 27 if(!r->doanother) 28 trace(TraceProc, "kick %s", r->name); 29 r->doanother = 1; 30 rwakeup(&r->start); 31 if(wait){ 32 n = r->next; 33 while((int)(n - r->last) > 0){ 34 r->doanother = 1; 35 rwakeup(&r->start); 36 rsleep(&r->finish); 37 } 38 } 39 } 40 41 void 42 kickround(Round *r, int wait) 43 { 44 qlock(&r->lock); 45 _kickround(r, wait); 46 qunlock(&r->lock); 47 } 48 49 void 50 initround(Round *r, char *name, int delay) 51 { 52 memset(r, 0, sizeof *r); 53 r->name = name; 54 r->start.l = &r->lock; 55 r->finish.l = &r->lock; 56 r->delaywait.l = &r->lock; 57 r->last = 0; 58 r->current = 0; 59 r->next = 1; 60 r->doanother = 0; 61 r->delaytime = delay; 62 } 63 64 void 65 delaykickround(Round *r) 66 { 67 qlock(&r->lock); 68 r->delaykick = 1; 69 rwakeup(&r->delaywait); 70 qunlock(&r->lock); 71 } 72 73 void 74 delaykickroundproc(void *v) 75 { 76 Round *r = v; 77 int n; 78 79 threadsetname("delaykickproc %s", r->name); 80 qlock(&r->lock); 81 for(;;){ 82 while(r->delaykick == 0){ 83 trace(TraceProc, "sleep"); 84 rsleep(&r->delaywait); 85 } 86 87 n = r->next; 88 qunlock(&r->lock); 89 90 trace(TraceProc, "waitround 0x%ux", (uint)n); 91 sleep(r->delaytime); 92 93 qlock(&r->lock); 94 if(n == r->next){ 95 trace(TraceProc, "kickround 0x%ux", (uint)n); 96 _kickround(r, 1); 97 } 98 99 trace(TraceProc, "finishround 0x%ux", (uint)n); 100 } 101 }