1 #include "stdinc.h"
2 #include "dat.h"
3 #include "fns.h"
4
5 void
waitforkick(Round * r)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
_kickround(Round * r,int wait)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
kickround(Round * r,int wait)42 kickround(Round *r, int wait)
43 {
44 qlock(&r->lock);
45 _kickround(r, wait);
46 qunlock(&r->lock);
47 }
48
49 void
initround(Round * r,char * name,int delay)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
delaykickround(Round * r)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
delaykickroundproc(void * v)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 }
102