Blame


1 76193d7c 2003-09-30 devnull #include "threadimpl.h"
2 76193d7c 2003-09-30 devnull
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;
8 76193d7c 2003-09-30 devnull
9 76193d7c 2003-09-30 devnull static ulong
10 76193d7c 2003-09-30 devnull finish(Thread *t, ulong val)
11 76193d7c 2003-09-30 devnull {
12 76193d7c 2003-09-30 devnull ulong ret;
13 76193d7c 2003-09-30 devnull
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);
22 76193d7c 2003-09-30 devnull }
23 76193d7c 2003-09-30 devnull unlock(&t->proc->lock);
24 76193d7c 2003-09-30 devnull return ret;
25 76193d7c 2003-09-30 devnull }
26 76193d7c 2003-09-30 devnull
27 76193d7c 2003-09-30 devnull ulong
28 76193d7c 2003-09-30 devnull _threadrendezvous(ulong tag, ulong val)
29 76193d7c 2003-09-30 devnull {
30 76193d7c 2003-09-30 devnull ulong ret;
31 76193d7c 2003-09-30 devnull Thread *t, **l;
32 76193d7c 2003-09-30 devnull
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;
44 76193d7c 2003-09-30 devnull }
45 76193d7c 2003-09-30 devnull }
46 76193d7c 2003-09-30 devnull
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;
54 76193d7c 2003-09-30 devnull *l = t;
55 76193d7c 2003-09-30 devnull t->nextstate = Rendezvous;
56 76193d7c 2003-09-30 devnull ++nrendez;
57 76193d7c 2003-09-30 devnull if(nrendez > _threadhighnrendez)
58 76193d7c 2003-09-30 devnull _threadhighnrendez = nrendez;
59 76193d7c 2003-09-30 devnull _threaddebug(DBGREND, "Rendezvous for tag %lud", t->rendtag);
60 76193d7c 2003-09-30 devnull unlock(&_threadrgrp.lock);
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;
65 76193d7c 2003-09-30 devnull }
66 76193d7c 2003-09-30 devnull
67 76193d7c 2003-09-30 devnull /*
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.
71 76193d7c 2003-09-30 devnull */
72 76193d7c 2003-09-30 devnull void
73 76193d7c 2003-09-30 devnull _threadflagrendez(Thread *t)
74 76193d7c 2003-09-30 devnull {
75 76193d7c 2003-09-30 devnull t->rendbreak = 1;
76 76193d7c 2003-09-30 devnull isdirty = 1;
77 76193d7c 2003-09-30 devnull }
78 76193d7c 2003-09-30 devnull
79 76193d7c 2003-09-30 devnull void
80 76193d7c 2003-09-30 devnull _threadbreakrendez(void)
81 76193d7c 2003-09-30 devnull {
82 76193d7c 2003-09-30 devnull int i;
83 76193d7c 2003-09-30 devnull Thread *t, **l;
84 76193d7c 2003-09-30 devnull
85 76193d7c 2003-09-30 devnull if(isdirty == 0)
86 76193d7c 2003-09-30 devnull return;
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);
90 76193d7c 2003-09-30 devnull return;
91 76193d7c 2003-09-30 devnull }
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);
99 76193d7c 2003-09-30 devnull }else
100 76193d7c 2003-09-30 devnull l=&t->rendhash;
101 76193d7c 2003-09-30 devnull }
102 76193d7c 2003-09-30 devnull }
103 76193d7c 2003-09-30 devnull unlock(&_threadrgrp.lock);
104 76193d7c 2003-09-30 devnull }