xref: /plan9-contrib/sys/src/libthread/exit.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
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;
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 	lock(&_threadpq.lock);
43 	npid = 0;
44 	for(p=_threadpq.head; p; p=p->next)
45 		npid++;
46 	pid = _threadmalloc(npid*sizeof(pid[0]), 0);
47 	npid = 0;
48 	for(p = _threadpq.head; p; p=p->next)
49 		pid[npid++] = p->pid;
50 	unlock(&_threadpq.lock);
51 	for(i=0; i<npid; i++)
52 		if(pid[i] != mypid)
53 			postnote(PNPROC, pid[i], "threadint");
54 
55 	/* leave */
56 	exits(exitstr);
57 }
58 
59 Channel*
60 threadwaitchan(void)
61 {
62 	if(_threadwaitchan==nil)
63 		_threadwaitchan = chancreate(sizeof(Waitmsg*), 16);
64 	return _threadwaitchan;
65 }
66