plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

round.c (1576B)


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