aboutsummaryrefslogtreecommitdiff
path: root/src/libthread/rendez.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libthread/rendez.c')
-rw-r--r--src/libthread/rendez.c104
1 files changed, 19 insertions, 85 deletions
diff --git a/src/libthread/rendez.c b/src/libthread/rendez.c
index 70eb0ae8..4451fa4d 100644
--- a/src/libthread/rendez.c
+++ b/src/libthread/rendez.c
@@ -1,104 +1,38 @@
#include "threadimpl.h"
-Rgrp _threadrgrp;
-static int isdirty;
int _threadhighnrendez;
int _threadnrendez;
-static int nrendez;
-static ulong
-finish(Thread *t, ulong val)
-{
- ulong ret;
-
- ret = t->rendval;
- t->rendval = val;
- while(t->state == Running)
- sleep(0);
- lock(&t->proc->lock);
- if(t->state == Rendezvous){ /* not always true: might be Dead */
- t->state = Ready;
- _threadready(t);
- }
- unlock(&t->proc->lock);
- return ret;
-}
-
-ulong
-_threadrendezvous(ulong tag, ulong val)
+void
+_threadsleep(_Procrend *r)
{
- ulong ret;
- Thread *t, **l;
-
- lock(&_threadrgrp.lock);
-_threadnrendez++;
- l = &_threadrgrp.hash[tag%nelem(_threadrgrp.hash)];
- for(t=*l; t; l=&t->rendhash, t=*l){
- if(t->rendtag==tag){
- _threaddebug(DBGREND, "Rendezvous with thread %d.%d", t->proc->pid, t->id);
- *l = t->rendhash;
- ret = finish(t, val);
- --nrendez;
- unlock(&_threadrgrp.lock);
- return ret;
- }
- }
+ Thread *t;
- /* Going to sleep here. */
t = _threadgetproc()->thread;
- t->rendbreak = 0;
- t->inrendez = 1;
- t->rendtag = tag;
- t->rendval = val;
- t->rendhash = *l;
- *l = t;
- ++nrendez;
- if(nrendez > _threadhighnrendez)
- _threadhighnrendez = nrendez;
- _threaddebug(DBGREND, "Rendezvous for tag %lud (m=%d)", t->rendtag, t->moribund);
- unlock(&_threadrgrp.lock);
+ r->arg = t;
t->nextstate = Rendezvous;
+ t->inrendez = 1;
+ unlock(r->l);
_sched();
t->inrendez = 0;
- _threaddebug(DBGREND, "Woke after rendezvous; val is %lud", t->rendval);
- return t->rendval;
-}
-
-/*
- * This is called while holding _threadpq.lock and p->lock,
- * so we can't lock _threadrgrp.lock. Instead our caller has
- * to call _threadbreakrendez after dropping those locks.
- */
-void
-_threadflagrendez(Thread *t)
-{
- t->rendbreak = 1;
- isdirty = 1;
+ lock(r->l);
}
void
-_threadbreakrendez(void)
+_threadwakeup(_Procrend *r)
{
- int i;
- Thread *t, **l;
+ Thread *t;
- if(isdirty == 0)
- return;
- lock(&_threadrgrp.lock);
- if(isdirty == 0){
- unlock(&_threadrgrp.lock);
+ t = r->arg;
+ while(t->state == Running)
+ sleep(0);
+ lock(&t->proc->lock);
+ if(t->state == Dead){
+ unlock(&t->proc->lock);
return;
}
- isdirty = 0;
- for(i=0; i<nelem(_threadrgrp.hash); i++){
- l = &_threadrgrp.hash[i];
- for(t=*l; t; t=*l){
- if(t->rendbreak){
- *l = t->rendhash;
- finish(t, ~0);
- }else
- l=&t->rendhash;
- }
- }
- unlock(&_threadrgrp.lock);
+ assert(t->state == Rendezvous && t->inrendez);
+ t->state = Ready;
+ _threadready(t);
+ unlock(&t->proc->lock);
}