19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <thread.h>
49a747e4fSDavid du Colombier #include "threadimpl.h"
59a747e4fSDavid du Colombier
69a747e4fSDavid du Colombier int _threadnopasser;
79a747e4fSDavid du Colombier
89a747e4fSDavid du Colombier #define NFN 33
99a747e4fSDavid du Colombier #define ERRLEN 48
109a747e4fSDavid du Colombier typedef struct Note Note;
119a747e4fSDavid du Colombier struct Note
129a747e4fSDavid du Colombier {
139a747e4fSDavid du Colombier Lock inuse;
149a747e4fSDavid du Colombier Proc *proc; /* recipient */
159a747e4fSDavid du Colombier char s[ERRMAX]; /* arg2 */
169a747e4fSDavid du Colombier };
179a747e4fSDavid du Colombier
189a747e4fSDavid du Colombier static Note notes[128];
199a747e4fSDavid du Colombier static Note *enotes = notes+nelem(notes);
209a747e4fSDavid du Colombier static int (*onnote[NFN])(void*, char*);
219a747e4fSDavid du Colombier static int onnotepid[NFN];
229a747e4fSDavid du Colombier static Lock onnotelock;
239a747e4fSDavid du Colombier
249a747e4fSDavid du Colombier int
threadnotify(int (* f)(void *,char *),int in)259a747e4fSDavid du Colombier threadnotify(int (*f)(void*, char*), int in)
269a747e4fSDavid du Colombier {
279a747e4fSDavid du Colombier int i, topid;
289a747e4fSDavid du Colombier int (*from)(void*, char*), (*to)(void*, char*);
299a747e4fSDavid du Colombier
309a747e4fSDavid du Colombier if(in){
319a747e4fSDavid du Colombier from = nil;
329a747e4fSDavid du Colombier to = f;
339a747e4fSDavid du Colombier topid = _threadgetproc()->pid;
349a747e4fSDavid du Colombier }else{
359a747e4fSDavid du Colombier from = f;
369a747e4fSDavid du Colombier to = nil;
379a747e4fSDavid du Colombier topid = 0;
389a747e4fSDavid du Colombier }
399a747e4fSDavid du Colombier lock(&onnotelock);
409a747e4fSDavid du Colombier for(i=0; i<NFN; i++)
419a747e4fSDavid du Colombier if(onnote[i]==from){
429a747e4fSDavid du Colombier onnote[i] = to;
439a747e4fSDavid du Colombier onnotepid[i] = topid;
449a747e4fSDavid du Colombier break;
459a747e4fSDavid du Colombier }
469a747e4fSDavid du Colombier unlock(&onnotelock);
479a747e4fSDavid du Colombier return i<NFN;
489a747e4fSDavid du Colombier }
499a747e4fSDavid du Colombier
509a747e4fSDavid du Colombier static void
delayednotes(Proc * p,void * v)519a747e4fSDavid du Colombier delayednotes(Proc *p, void *v)
529a747e4fSDavid du Colombier {
539a747e4fSDavid du Colombier int i;
549a747e4fSDavid du Colombier Note *n;
559a747e4fSDavid du Colombier int (*fn)(void*, char*);
569a747e4fSDavid du Colombier
579a747e4fSDavid du Colombier if(!p->pending)
589a747e4fSDavid du Colombier return;
599a747e4fSDavid du Colombier
609a747e4fSDavid du Colombier p->pending = 0;
619a747e4fSDavid du Colombier for(n=notes; n<enotes; n++){
629a747e4fSDavid du Colombier if(n->proc == p){
639a747e4fSDavid du Colombier for(i=0; i<NFN; i++){
649a747e4fSDavid du Colombier if(onnotepid[i]!=p->pid || (fn = onnote[i])==nil)
659a747e4fSDavid du Colombier continue;
669a747e4fSDavid du Colombier if((*fn)(v, n->s))
679a747e4fSDavid du Colombier break;
689a747e4fSDavid du Colombier }
699a747e4fSDavid du Colombier if(i==NFN){
709a747e4fSDavid du Colombier _threaddebug(DBGNOTE, "Unhandled note %s, proc %p\n", n->s, p);
719a747e4fSDavid du Colombier if(v != nil)
729a747e4fSDavid du Colombier noted(NDFLT);
739a747e4fSDavid du Colombier else if(strncmp(n->s, "sys:", 4)==0)
749a747e4fSDavid du Colombier abort();
759a747e4fSDavid du Colombier threadexitsall(n->s);
769a747e4fSDavid du Colombier }
779a747e4fSDavid du Colombier n->proc = nil;
789a747e4fSDavid du Colombier unlock(&n->inuse);
799a747e4fSDavid du Colombier }
809a747e4fSDavid du Colombier }
819a747e4fSDavid du Colombier }
829a747e4fSDavid du Colombier
839a747e4fSDavid du Colombier void
_threadnote(void * v,char * s)849a747e4fSDavid du Colombier _threadnote(void *v, char *s)
859a747e4fSDavid du Colombier {
869a747e4fSDavid du Colombier Proc *p;
879a747e4fSDavid du Colombier Note *n;
889a747e4fSDavid du Colombier
899a747e4fSDavid du Colombier _threaddebug(DBGNOTE, "Got note %s", s);
909a747e4fSDavid du Colombier if(strncmp(s, "sys:", 4) == 0)
919a747e4fSDavid du Colombier noted(NDFLT);
929a747e4fSDavid du Colombier
93*dc5a79c1SDavid du Colombier if(_threadexitsallstatus){
94*dc5a79c1SDavid du Colombier _threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'\n", _threadexitsallstatus);
95*dc5a79c1SDavid du Colombier _exits(_threadexitsallstatus);
96*dc5a79c1SDavid du Colombier }
979a747e4fSDavid du Colombier
989a747e4fSDavid du Colombier if(strcmp(s, "threadint")==0)
999a747e4fSDavid du Colombier noted(NCONT);
1009a747e4fSDavid du Colombier
1019a747e4fSDavid du Colombier p = _threadgetproc();
1029a747e4fSDavid du Colombier if(p == nil)
1039a747e4fSDavid du Colombier noted(NDFLT);
1049a747e4fSDavid du Colombier
1059a747e4fSDavid du Colombier for(n=notes; n<enotes; n++)
1069a747e4fSDavid du Colombier if(canlock(&n->inuse))
1079a747e4fSDavid du Colombier break;
1089a747e4fSDavid du Colombier if(n==enotes)
1099a747e4fSDavid du Colombier sysfatal("libthread: too many delayed notes");
1109a747e4fSDavid du Colombier utfecpy(n->s, n->s+ERRMAX, s);
1119a747e4fSDavid du Colombier n->proc = p;
1129a747e4fSDavid du Colombier p->pending = 1;
1139a747e4fSDavid du Colombier if(!p->splhi)
1149a747e4fSDavid du Colombier delayednotes(p, v);
1159a747e4fSDavid du Colombier noted(NCONT);
1169a747e4fSDavid du Colombier }
1179a747e4fSDavid du Colombier
1189a747e4fSDavid du Colombier int
_procsplhi(void)1199a747e4fSDavid du Colombier _procsplhi(void)
1209a747e4fSDavid du Colombier {
1219a747e4fSDavid du Colombier int s;
1229a747e4fSDavid du Colombier Proc *p;
1239a747e4fSDavid du Colombier
1249a747e4fSDavid du Colombier p = _threadgetproc();
1259a747e4fSDavid du Colombier s = p->splhi;
1269a747e4fSDavid du Colombier p->splhi = 1;
1279a747e4fSDavid du Colombier return s;
1289a747e4fSDavid du Colombier }
1299a747e4fSDavid du Colombier
1309a747e4fSDavid du Colombier void
_procsplx(int s)1319a747e4fSDavid du Colombier _procsplx(int s)
1329a747e4fSDavid du Colombier {
1339a747e4fSDavid du Colombier Proc *p;
1349a747e4fSDavid du Colombier
1359a747e4fSDavid du Colombier p = _threadgetproc();
1369a747e4fSDavid du Colombier p->splhi = s;
1379a747e4fSDavid du Colombier if(s)
1389a747e4fSDavid du Colombier return;
1399a747e4fSDavid du Colombier if(p->pending)
1409a747e4fSDavid du Colombier delayednotes(p, nil);
1419a747e4fSDavid du Colombier }
1429a747e4fSDavid du Colombier
143