1*9a747e4fSDavid du Colombier #include <u.h> 2*9a747e4fSDavid du Colombier #include <libc.h> 3*9a747e4fSDavid du Colombier #include <thread.h> 4*9a747e4fSDavid du Colombier #include "threadimpl.h" 5*9a747e4fSDavid du Colombier 6*9a747e4fSDavid du Colombier Rgrp _threadrgrp; 7*9a747e4fSDavid du Colombier static int isdirty; 8*9a747e4fSDavid du Colombier 9*9a747e4fSDavid du Colombier static ulong 10*9a747e4fSDavid du Colombier finish(Thread *t, ulong val) 11*9a747e4fSDavid du Colombier { 12*9a747e4fSDavid du Colombier ulong ret; 13*9a747e4fSDavid du Colombier 14*9a747e4fSDavid du Colombier ret = t->rendval; 15*9a747e4fSDavid du Colombier t->rendval = val; 16*9a747e4fSDavid du Colombier while(t->state == Running) 17*9a747e4fSDavid du Colombier sleep(0); 18*9a747e4fSDavid du Colombier lock(&t->proc->lock); 19*9a747e4fSDavid du Colombier if(t->state == Rendezvous){ /* not always true: might be Dead */ 20*9a747e4fSDavid du Colombier t->state = Ready; 21*9a747e4fSDavid du Colombier _threadready(t); 22*9a747e4fSDavid du Colombier } 23*9a747e4fSDavid du Colombier unlock(&t->proc->lock); 24*9a747e4fSDavid du Colombier return ret; 25*9a747e4fSDavid du Colombier } 26*9a747e4fSDavid du Colombier 27*9a747e4fSDavid du Colombier ulong 28*9a747e4fSDavid du Colombier _threadrendezvous(ulong tag, ulong val) 29*9a747e4fSDavid du Colombier { 30*9a747e4fSDavid du Colombier ulong ret; 31*9a747e4fSDavid du Colombier Thread *t, **l; 32*9a747e4fSDavid du Colombier 33*9a747e4fSDavid du Colombier lock(&_threadrgrp.lock); 34*9a747e4fSDavid du Colombier l = &_threadrgrp.hash[tag%nelem(_threadrgrp.hash)]; 35*9a747e4fSDavid du Colombier for(t=*l; t; l=&t->rendhash, t=*l){ 36*9a747e4fSDavid du Colombier if(t->rendtag==tag){ 37*9a747e4fSDavid du Colombier _threaddebug(DBGREND, "Rendezvous with thread %d.%d", t->proc->pid, t->id); 38*9a747e4fSDavid du Colombier *l = t->rendhash; 39*9a747e4fSDavid du Colombier ret = finish(t, val); 40*9a747e4fSDavid du Colombier unlock(&_threadrgrp.lock); 41*9a747e4fSDavid du Colombier return ret; 42*9a747e4fSDavid du Colombier } 43*9a747e4fSDavid du Colombier } 44*9a747e4fSDavid du Colombier 45*9a747e4fSDavid du Colombier /* Going to sleep here. */ 46*9a747e4fSDavid du Colombier t = _threadgetproc()->thread; 47*9a747e4fSDavid du Colombier t->rendbreak = 0; 48*9a747e4fSDavid du Colombier t->inrendez = 1; 49*9a747e4fSDavid du Colombier t->rendtag = tag; 50*9a747e4fSDavid du Colombier t->rendval = val; 51*9a747e4fSDavid du Colombier t->rendhash = *l; 52*9a747e4fSDavid du Colombier *l = t; 53*9a747e4fSDavid du Colombier t->nextstate = Rendezvous; 54*9a747e4fSDavid du Colombier _threaddebug(DBGREND, "Rendezvous for tag %lud", t->rendtag); 55*9a747e4fSDavid du Colombier unlock(&_threadrgrp.lock); 56*9a747e4fSDavid du Colombier _sched(); 57*9a747e4fSDavid du Colombier t->inrendez = 0; 58*9a747e4fSDavid du Colombier _threaddebug(DBGREND, "Woke after rendezvous; val is %lud", t->rendval); 59*9a747e4fSDavid du Colombier return t->rendval; 60*9a747e4fSDavid du Colombier } 61*9a747e4fSDavid du Colombier 62*9a747e4fSDavid du Colombier /* 63*9a747e4fSDavid du Colombier * This is called while holding _threadpq.lock and p->lock, 64*9a747e4fSDavid du Colombier * so we can't lock _threadrgrp.lock. Instead our caller has 65*9a747e4fSDavid du Colombier * to call _threadbreakrendez after dropping those locks. 66*9a747e4fSDavid du Colombier */ 67*9a747e4fSDavid du Colombier void 68*9a747e4fSDavid du Colombier _threadflagrendez(Thread *t) 69*9a747e4fSDavid du Colombier { 70*9a747e4fSDavid du Colombier t->rendbreak = 1; 71*9a747e4fSDavid du Colombier isdirty = 1; 72*9a747e4fSDavid du Colombier } 73*9a747e4fSDavid du Colombier 74*9a747e4fSDavid du Colombier void 75*9a747e4fSDavid du Colombier _threadbreakrendez(void) 76*9a747e4fSDavid du Colombier { 77*9a747e4fSDavid du Colombier int i; 78*9a747e4fSDavid du Colombier Thread *t, **l; 79*9a747e4fSDavid du Colombier 80*9a747e4fSDavid du Colombier if(isdirty == 0) 81*9a747e4fSDavid du Colombier return; 82*9a747e4fSDavid du Colombier lock(&_threadrgrp.lock); 83*9a747e4fSDavid du Colombier if(isdirty == 0){ 84*9a747e4fSDavid du Colombier unlock(&_threadrgrp.lock); 85*9a747e4fSDavid du Colombier return; 86*9a747e4fSDavid du Colombier } 87*9a747e4fSDavid du Colombier isdirty = 0; 88*9a747e4fSDavid du Colombier for(i=0; i<nelem(_threadrgrp.hash); i++){ 89*9a747e4fSDavid du Colombier l = &_threadrgrp.hash[i]; 90*9a747e4fSDavid du Colombier for(t=*l; t; t=*l){ 91*9a747e4fSDavid du Colombier if(t->rendbreak){ 92*9a747e4fSDavid du Colombier *l = t->rendhash; 93*9a747e4fSDavid du Colombier finish(t, ~0); 94*9a747e4fSDavid du Colombier }else 95*9a747e4fSDavid du Colombier l=&t->rendhash; 96*9a747e4fSDavid du Colombier } 97*9a747e4fSDavid du Colombier } 98*9a747e4fSDavid du Colombier unlock(&_threadrgrp.lock); 99*9a747e4fSDavid du Colombier } 100