1 76193d7c 2003-09-30 devnull #include "threadimpl.h"
3 76193d7c 2003-09-30 devnull Rgrp _threadrgrp;
4 76193d7c 2003-09-30 devnull static int isdirty;
5 76193d7c 2003-09-30 devnull int _threadhighnrendez;
6 76193d7c 2003-09-30 devnull int _threadnrendez;
7 76193d7c 2003-09-30 devnull static int nrendez;
9 76193d7c 2003-09-30 devnull static ulong
10 76193d7c 2003-09-30 devnull finish(Thread *t, ulong val)
12 76193d7c 2003-09-30 devnull ulong ret;
14 76193d7c 2003-09-30 devnull ret = t->rendval;
15 76193d7c 2003-09-30 devnull t->rendval = val;
16 76193d7c 2003-09-30 devnull while(t->state == Running)
17 76193d7c 2003-09-30 devnull sleep(0);
18 76193d7c 2003-09-30 devnull lock(&t->proc->lock);
19 76193d7c 2003-09-30 devnull if(t->state == Rendezvous){ /* not always true: might be Dead */
20 76193d7c 2003-09-30 devnull t->state = Ready;
21 76193d7c 2003-09-30 devnull _threadready(t);
23 76193d7c 2003-09-30 devnull unlock(&t->proc->lock);
24 76193d7c 2003-09-30 devnull return ret;
28 76193d7c 2003-09-30 devnull _threadrendezvous(ulong tag, ulong val)
30 76193d7c 2003-09-30 devnull ulong ret;
31 76193d7c 2003-09-30 devnull Thread *t, **l;
33 76193d7c 2003-09-30 devnull lock(&_threadrgrp.lock);
34 76193d7c 2003-09-30 devnull _threadnrendez++;
35 76193d7c 2003-09-30 devnull l = &_threadrgrp.hash[tag%nelem(_threadrgrp.hash)];
36 76193d7c 2003-09-30 devnull for(t=*l; t; l=&t->rendhash, t=*l){
37 76193d7c 2003-09-30 devnull if(t->rendtag==tag){
38 76193d7c 2003-09-30 devnull _threaddebug(DBGREND, "Rendezvous with thread %d.%d", t->proc->pid, t->id);
39 76193d7c 2003-09-30 devnull *l = t->rendhash;
40 76193d7c 2003-09-30 devnull ret = finish(t, val);
41 76193d7c 2003-09-30 devnull --nrendez;
42 76193d7c 2003-09-30 devnull unlock(&_threadrgrp.lock);
43 76193d7c 2003-09-30 devnull return ret;
47 76193d7c 2003-09-30 devnull /* Going to sleep here. */
48 76193d7c 2003-09-30 devnull t = _threadgetproc()->thread;
49 76193d7c 2003-09-30 devnull t->rendbreak = 0;
50 76193d7c 2003-09-30 devnull t->inrendez = 1;
51 76193d7c 2003-09-30 devnull t->rendtag = tag;
52 76193d7c 2003-09-30 devnull t->rendval = val;
53 76193d7c 2003-09-30 devnull t->rendhash = *l;
55 76193d7c 2003-09-30 devnull ++nrendez;
56 76193d7c 2003-09-30 devnull if(nrendez > _threadhighnrendez)
57 76193d7c 2003-09-30 devnull _threadhighnrendez = nrendez;
58 912fba95 2003-11-24 devnull _threaddebug(DBGREND, "Rendezvous for tag %lud (m=%d)", t->rendtag, t->moribund);
59 76193d7c 2003-09-30 devnull unlock(&_threadrgrp.lock);
60 912fba95 2003-11-24 devnull t->nextstate = Rendezvous;
61 76193d7c 2003-09-30 devnull _sched();
62 76193d7c 2003-09-30 devnull t->inrendez = 0;
63 76193d7c 2003-09-30 devnull _threaddebug(DBGREND, "Woke after rendezvous; val is %lud", t->rendval);
64 76193d7c 2003-09-30 devnull return t->rendval;
68 76193d7c 2003-09-30 devnull * This is called while holding _threadpq.lock and p->lock,
69 76193d7c 2003-09-30 devnull * so we can't lock _threadrgrp.lock. Instead our caller has
70 76193d7c 2003-09-30 devnull * to call _threadbreakrendez after dropping those locks.
73 76193d7c 2003-09-30 devnull _threadflagrendez(Thread *t)
75 76193d7c 2003-09-30 devnull t->rendbreak = 1;
76 76193d7c 2003-09-30 devnull isdirty = 1;
80 76193d7c 2003-09-30 devnull _threadbreakrendez(void)
83 76193d7c 2003-09-30 devnull Thread *t, **l;
85 76193d7c 2003-09-30 devnull if(isdirty == 0)
87 76193d7c 2003-09-30 devnull lock(&_threadrgrp.lock);
88 76193d7c 2003-09-30 devnull if(isdirty == 0){
89 76193d7c 2003-09-30 devnull unlock(&_threadrgrp.lock);
92 76193d7c 2003-09-30 devnull isdirty = 0;
93 76193d7c 2003-09-30 devnull for(i=0; i<nelem(_threadrgrp.hash); i++){
94 76193d7c 2003-09-30 devnull l = &_threadrgrp.hash[i];
95 76193d7c 2003-09-30 devnull for(t=*l; t; t=*l){
96 76193d7c 2003-09-30 devnull if(t->rendbreak){
97 76193d7c 2003-09-30 devnull *l = t->rendhash;
98 76193d7c 2003-09-30 devnull finish(t, ~0);
100 76193d7c 2003-09-30 devnull l=&t->rendhash;
103 76193d7c 2003-09-30 devnull unlock(&_threadrgrp.lock);