Blob


1 #include "stdinc.h"
2 #include "dat.h"
3 #include "fns.h"
5 void
6 waitforkick(Round *r)
7 {
8 int n;
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 }
22 static void
23 _kickround(Round *r, int wait)
24 {
25 int n;
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 }
41 void
42 kickround(Round *r, int wait)
43 {
44 qlock(&r->lock);
45 _kickround(r, wait);
46 qunlock(&r->lock);
47 }
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 }
64 void
65 delaykickround(Round *r)
66 {
67 qlock(&r->lock);
68 r->delaykick = 1;
69 rwakeup(&r->delaywait);
70 qunlock(&r->lock);
71 }
73 void
74 delaykickroundproc(void *v)
75 {
76 Round *r = v;
77 int n;
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 }
87 n = r->next;
88 qunlock(&r->lock);
90 trace(TraceProc, "waitround 0x%ux", (uint)n);
91 sleep(r->delaytime);
93 qlock(&r->lock);
94 if(n == r->next){
95 trace(TraceProc, "kickround 0x%ux", (uint)n);
96 _kickround(r, 1);
97 }
99 trace(TraceProc, "finishround 0x%ux", (uint)n);