103 lines
1.5 KiB
C
103 lines
1.5 KiB
C
![]() |
#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);
|
||
|
}
|
||
|
}
|
||
|
|