xref: /plan9/sys/src/libthread/exit.c (revision d1be6b086622eecc0da76db1fbd64349a5e85293)
19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <thread.h>
49a747e4fSDavid du Colombier #include "threadimpl.h"
5*d1be6b08SDavid du Colombier #include <tos.h>
69a747e4fSDavid du Colombier 
79a747e4fSDavid du Colombier char *_threadexitsallstatus;
89a747e4fSDavid du Colombier Channel *_threadwaitchan;
99a747e4fSDavid du Colombier 
109a747e4fSDavid du Colombier void
threadexits(char * exitstr)119a747e4fSDavid du Colombier threadexits(char *exitstr)
129a747e4fSDavid du Colombier {
139a747e4fSDavid du Colombier 	Proc *p;
149a747e4fSDavid du Colombier 	Thread *t;
159a747e4fSDavid du Colombier 
169a747e4fSDavid du Colombier 	p = _threadgetproc();
179a747e4fSDavid du Colombier 	t = p->thread;
189a747e4fSDavid du Colombier 	t->moribund = 1;
199a747e4fSDavid du Colombier 	if(exitstr==nil)
209a747e4fSDavid du Colombier 		exitstr="";
219a747e4fSDavid du Colombier 	utfecpy(p->exitstr, p->exitstr+ERRMAX, exitstr);
229a747e4fSDavid du Colombier 	_sched();
239a747e4fSDavid du Colombier }
249a747e4fSDavid du Colombier 
259a747e4fSDavid du Colombier void
threadexitsall(char * exitstr)269a747e4fSDavid du Colombier threadexitsall(char *exitstr)
279a747e4fSDavid du Colombier {
289a747e4fSDavid du Colombier 	Proc *p;
29dc5a79c1SDavid du Colombier 	int pid[64];
309a747e4fSDavid du Colombier 	int i, npid, mypid;
319a747e4fSDavid du Colombier 
329a747e4fSDavid du Colombier 	if(exitstr == nil)
339a747e4fSDavid du Colombier 		exitstr = "";
349a747e4fSDavid du Colombier 	_threadexitsallstatus = exitstr;
359a747e4fSDavid du Colombier 	_threaddebug(DBGSCHED, "_threadexitsallstatus set to %p", _threadexitsallstatus);
36*d1be6b08SDavid du Colombier 	mypid = _tos->pid; //getpid();
379a747e4fSDavid du Colombier 
389a747e4fSDavid du Colombier 	/*
399a747e4fSDavid du Colombier 	 * signal others.
409a747e4fSDavid du Colombier 	 * copying all the pids first avoids other threads
419a747e4fSDavid du Colombier 	 * teardown procedures getting in the way.
42dc5a79c1SDavid du Colombier 	 *
43dc5a79c1SDavid du Colombier 	 * avoid mallocs since malloc can post a note which can
44dc5a79c1SDavid du Colombier 	 * call threadexitsall...
459a747e4fSDavid du Colombier 	 */
46dc5a79c1SDavid du Colombier 	for(;;){
479a747e4fSDavid du Colombier 		lock(&_threadpq.lock);
489a747e4fSDavid du Colombier 		npid = 0;
49dc5a79c1SDavid du Colombier 		for(p = _threadpq.head; p && npid < nelem(pid); p=p->next){
50dc5a79c1SDavid du Colombier 			if(p->threadint == 0 && p->pid != mypid){
519a747e4fSDavid du Colombier 				pid[npid++] = p->pid;
52dc5a79c1SDavid du Colombier 				p->threadint = 1;
53dc5a79c1SDavid du Colombier 			}
54dc5a79c1SDavid du Colombier 		}
559a747e4fSDavid du Colombier 		unlock(&_threadpq.lock);
56dc5a79c1SDavid du Colombier 		if(npid == 0)
57dc5a79c1SDavid du Colombier 			break;
589a747e4fSDavid du Colombier 		for(i=0; i<npid; i++)
599a747e4fSDavid du Colombier 			postnote(PNPROC, pid[i], "threadint");
60dc5a79c1SDavid du Colombier 	}
619a747e4fSDavid du Colombier 
629a747e4fSDavid du Colombier 	/* leave */
639a747e4fSDavid du Colombier 	exits(exitstr);
649a747e4fSDavid du Colombier }
659a747e4fSDavid du Colombier 
669a747e4fSDavid du Colombier Channel*
threadwaitchan(void)679a747e4fSDavid du Colombier threadwaitchan(void)
689a747e4fSDavid du Colombier {
699a747e4fSDavid du Colombier 	if(_threadwaitchan==nil)
709a747e4fSDavid du Colombier 		_threadwaitchan = chancreate(sizeof(Waitmsg*), 16);
719a747e4fSDavid du Colombier 	return _threadwaitchan;
729a747e4fSDavid du Colombier }
73