1*9a747e4fSDavid du Colombier /* BUG BUG BUG */
2*9a747e4fSDavid du Colombier
3*9a747e4fSDavid du Colombier #include <u.h>
4*9a747e4fSDavid du Colombier #include <libc.h>
5*9a747e4fSDavid du Colombier #include <thread.h>
6*9a747e4fSDavid du Colombier #include "/sys/src/libthread/threadimpl.h"
7*9a747e4fSDavid du Colombier
8*9a747e4fSDavid du Colombier int _threadnopasser;
9*9a747e4fSDavid du Colombier
10*9a747e4fSDavid du Colombier #define NFN 33
11*9a747e4fSDavid du Colombier #define ERRLEN 48
12*9a747e4fSDavid du Colombier typedef struct Note Note;
13*9a747e4fSDavid du Colombier struct Note
14*9a747e4fSDavid du Colombier {
15*9a747e4fSDavid du Colombier Lock inuse;
16*9a747e4fSDavid du Colombier Proc *proc; /* recipient */
17*9a747e4fSDavid du Colombier char s[ERRMAX]; /* arg2 */
18*9a747e4fSDavid du Colombier };
19*9a747e4fSDavid du Colombier
20*9a747e4fSDavid du Colombier static Note notes[128];
21*9a747e4fSDavid du Colombier static Note *enotes = notes+nelem(notes);
22*9a747e4fSDavid du Colombier static int (*onnote[NFN])(void*, char*);
23*9a747e4fSDavid du Colombier static int onnotepid[NFN];
24*9a747e4fSDavid du Colombier static Lock onnotelock;
25*9a747e4fSDavid du Colombier
26*9a747e4fSDavid du Colombier int
threadnotify(int (* f)(void *,char *),int in)27*9a747e4fSDavid du Colombier threadnotify(int (*f)(void*, char*), int in)
28*9a747e4fSDavid du Colombier {
29*9a747e4fSDavid du Colombier int i, topid;
30*9a747e4fSDavid du Colombier int (*from)(void*, char*), (*to)(void*, char*);
31*9a747e4fSDavid du Colombier
32*9a747e4fSDavid du Colombier if(in){
33*9a747e4fSDavid du Colombier from = nil;
34*9a747e4fSDavid du Colombier to = f;
35*9a747e4fSDavid du Colombier topid = _threadgetproc()->pid;
36*9a747e4fSDavid du Colombier }else{
37*9a747e4fSDavid du Colombier from = f;
38*9a747e4fSDavid du Colombier to = nil;
39*9a747e4fSDavid du Colombier topid = 0;
40*9a747e4fSDavid du Colombier }
41*9a747e4fSDavid du Colombier lock(&onnotelock);
42*9a747e4fSDavid du Colombier for(i=0; i<NFN; i++)
43*9a747e4fSDavid du Colombier if(onnote[i]==from){
44*9a747e4fSDavid du Colombier onnote[i] = to;
45*9a747e4fSDavid du Colombier onnotepid[i] = topid;
46*9a747e4fSDavid du Colombier break;
47*9a747e4fSDavid du Colombier }
48*9a747e4fSDavid du Colombier unlock(&onnotelock);
49*9a747e4fSDavid du Colombier return i<NFN;
50*9a747e4fSDavid du Colombier }
51*9a747e4fSDavid du Colombier
52*9a747e4fSDavid du Colombier static void
delayednotes(Proc * p,void * v)53*9a747e4fSDavid du Colombier delayednotes(Proc *p, void *v)
54*9a747e4fSDavid du Colombier {
55*9a747e4fSDavid du Colombier int i;
56*9a747e4fSDavid du Colombier Note *n;
57*9a747e4fSDavid du Colombier int (*fn)(void*, char*);
58*9a747e4fSDavid du Colombier
59*9a747e4fSDavid du Colombier if(!p->pending)
60*9a747e4fSDavid du Colombier return;
61*9a747e4fSDavid du Colombier
62*9a747e4fSDavid du Colombier p->pending = 0;
63*9a747e4fSDavid du Colombier for(n=notes; n<enotes; n++){
64*9a747e4fSDavid du Colombier if(n->proc == p){
65*9a747e4fSDavid du Colombier for(i=0; i<NFN; i++){
66*9a747e4fSDavid du Colombier if(onnotepid[i]!=p->pid || (fn = onnote[i])==nil)
67*9a747e4fSDavid du Colombier continue;
68*9a747e4fSDavid du Colombier if((*fn)(v, n->s))
69*9a747e4fSDavid du Colombier break;
70*9a747e4fSDavid du Colombier }
71*9a747e4fSDavid du Colombier if(i==NFN){
72*9a747e4fSDavid du Colombier _threaddebug(DBGNOTE, "Unhandled note %s, proc %p\n", n->s, p);
73*9a747e4fSDavid du Colombier if(v != nil)
74*9a747e4fSDavid du Colombier noted(NDFLT);
75*9a747e4fSDavid du Colombier else if(strncmp(n->s, "sys:", 4)==0)
76*9a747e4fSDavid du Colombier abort();
77*9a747e4fSDavid du Colombier threadexitsall(n->s);
78*9a747e4fSDavid du Colombier }
79*9a747e4fSDavid du Colombier n->proc = nil;
80*9a747e4fSDavid du Colombier unlock(&n->inuse);
81*9a747e4fSDavid du Colombier }
82*9a747e4fSDavid du Colombier }
83*9a747e4fSDavid du Colombier }
84*9a747e4fSDavid du Colombier
85*9a747e4fSDavid du Colombier void
_threadnote(void * v,char * s)86*9a747e4fSDavid du Colombier _threadnote(void *v, char *s)
87*9a747e4fSDavid du Colombier {
88*9a747e4fSDavid du Colombier Proc *p;
89*9a747e4fSDavid du Colombier Note *n;
90*9a747e4fSDavid du Colombier
91*9a747e4fSDavid du Colombier _threaddebug(DBGNOTE, "Got note %s", s);
92*9a747e4fSDavid du Colombier // if(strncmp(s, "sys:", 4) == 0)
93*9a747e4fSDavid du Colombier // noted(NDFLT);
94*9a747e4fSDavid du Colombier
95*9a747e4fSDavid du Colombier // if(_threadexitsallstatus){
96*9a747e4fSDavid du Colombier // _threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'\n", _threadexitsallstatus);
97*9a747e4fSDavid du Colombier // _exits(_threadexitsallstatus);
98*9a747e4fSDavid du Colombier // }
99*9a747e4fSDavid du Colombier
100*9a747e4fSDavid du Colombier if(strcmp(s, "threadint")==0)
101*9a747e4fSDavid du Colombier noted(NCONT);
102*9a747e4fSDavid du Colombier
103*9a747e4fSDavid du Colombier p = _threadgetproc();
104*9a747e4fSDavid du Colombier if(p == nil)
105*9a747e4fSDavid du Colombier noted(NDFLT);
106*9a747e4fSDavid du Colombier
107*9a747e4fSDavid du Colombier for(n=notes; n<enotes; n++)
108*9a747e4fSDavid du Colombier if(canlock(&n->inuse))
109*9a747e4fSDavid du Colombier break;
110*9a747e4fSDavid du Colombier if(n==enotes)
111*9a747e4fSDavid du Colombier sysfatal("libthread: too many delayed notes");
112*9a747e4fSDavid du Colombier utfecpy(n->s, n->s+ERRMAX, s);
113*9a747e4fSDavid du Colombier n->proc = p;
114*9a747e4fSDavid du Colombier p->pending = 1;
115*9a747e4fSDavid du Colombier if(!p->splhi)
116*9a747e4fSDavid du Colombier delayednotes(p, v);
117*9a747e4fSDavid du Colombier noted(NCONT);
118*9a747e4fSDavid du Colombier }
119*9a747e4fSDavid du Colombier
120*9a747e4fSDavid du Colombier int
_procsplhi(void)121*9a747e4fSDavid du Colombier _procsplhi(void)
122*9a747e4fSDavid du Colombier {
123*9a747e4fSDavid du Colombier int s;
124*9a747e4fSDavid du Colombier Proc *p;
125*9a747e4fSDavid du Colombier
126*9a747e4fSDavid du Colombier p = _threadgetproc();
127*9a747e4fSDavid du Colombier s = p->splhi;
128*9a747e4fSDavid du Colombier p->splhi = 1;
129*9a747e4fSDavid du Colombier return s;
130*9a747e4fSDavid du Colombier }
131*9a747e4fSDavid du Colombier
132*9a747e4fSDavid du Colombier void
_procsplx(int s)133*9a747e4fSDavid du Colombier _procsplx(int s)
134*9a747e4fSDavid du Colombier {
135*9a747e4fSDavid du Colombier Proc *p;
136*9a747e4fSDavid du Colombier
137*9a747e4fSDavid du Colombier p = _threadgetproc();
138*9a747e4fSDavid du Colombier p->splhi = s;
139*9a747e4fSDavid du Colombier if(s)
140*9a747e4fSDavid du Colombier return;
141*9a747e4fSDavid du Colombier if(p->pending)
142*9a747e4fSDavid du Colombier delayednotes(p, nil);
143*9a747e4fSDavid du Colombier }
144*9a747e4fSDavid du Colombier
145