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