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