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