1 #include <u.h> 2 #include <libc.h> 3 #include <thread.h> 4 #include "threadimpl.h" 5 #include <tos.h> 6 7 char *_threadexitsallstatus; 8 Channel *_threadwaitchan; 9 10 void threadexits(char * exitstr)11threadexits(char *exitstr) 12 { 13 Proc *p; 14 Thread *t; 15 16 p = _threadgetproc(); 17 t = p->thread; 18 t->moribund = 1; 19 if(exitstr==nil) 20 exitstr=""; 21 utfecpy(p->exitstr, p->exitstr+ERRMAX, exitstr); 22 _sched(); 23 } 24 25 void threadexitsall(char * exitstr)26threadexitsall(char *exitstr) 27 { 28 Proc *p; 29 int pid[64]; 30 int i, npid, mypid; 31 32 if(exitstr == nil) 33 exitstr = ""; 34 _threadexitsallstatus = exitstr; 35 _threaddebug(DBGSCHED, "_threadexitsallstatus set to %p", _threadexitsallstatus); 36 mypid = _tos->pid; //getpid(); 37 38 /* 39 * signal others. 40 * copying all the pids first avoids other threads 41 * teardown procedures getting in the way. 42 * 43 * avoid mallocs since malloc can post a note which can 44 * call threadexitsall... 45 */ 46 for(;;){ 47 lock(&_threadpq.lock); 48 npid = 0; 49 for(p = _threadpq.head; p && npid < nelem(pid); p=p->next){ 50 if(p->threadint == 0 && p->pid != mypid){ 51 pid[npid++] = p->pid; 52 p->threadint = 1; 53 } 54 } 55 unlock(&_threadpq.lock); 56 if(npid == 0) 57 break; 58 for(i=0; i<npid; i++) 59 postnote(PNPROC, pid[i], "threadint"); 60 } 61 62 /* leave */ 63 exits(exitstr); 64 } 65 66 Channel* threadwaitchan(void)67threadwaitchan(void) 68 { 69 if(_threadwaitchan==nil) 70 _threadwaitchan = chancreate(sizeof(Waitmsg*), 16); 71 return _threadwaitchan; 72 } 73