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