xref: /plan9-contrib/sys/src/cmd/venti/srv/round.c (revision 368c31ab13393dea083228fdd1c3445076f83a4b)
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