ref: 17f14bef609f0cd81694f738a851a811dcd5d97d
dir: /sys/src/cmd/venti/srv/round.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);
	}
}