1 e7821682 2004-09-23 devnull #include <u.h>
2 e7821682 2004-09-23 devnull #include <errno.h>
3 e7821682 2004-09-23 devnull #include "threadimpl.h"
5 e7821682 2004-09-23 devnull static int multi;
6 e7821682 2004-09-23 devnull static Proc *theproc;
7 e7821682 2004-09-23 devnull static pthread_key_t key;
10 e7821682 2004-09-23 devnull * Called before we go multiprocess.
13 e7821682 2004-09-23 devnull _threadmultiproc(void)
15 e7821682 2004-09-23 devnull if(multi == 0){
16 e7821682 2004-09-23 devnull multi = 1;
17 e7821682 2004-09-23 devnull pthread_key_create(&key, 0);
18 e7821682 2004-09-23 devnull _threadsetproc(theproc);
23 e7821682 2004-09-23 devnull * Set the proc for the current pthread.
26 e7821682 2004-09-23 devnull _threadsetproc(Proc *p)
28 e7821682 2004-09-23 devnull if(!multi){
29 e7821682 2004-09-23 devnull theproc = p;
32 e7821682 2004-09-23 devnull pthread_setspecific(key, p);
36 e7821682 2004-09-23 devnull * Get the proc for the current pthread.
39 e7821682 2004-09-23 devnull _threadgetproc(void)
41 e7821682 2004-09-23 devnull if(!multi)
42 e7821682 2004-09-23 devnull return theproc;
44 e7821682 2004-09-23 devnull return pthread_getspecific(key);
48 e7821682 2004-09-23 devnull * Called to associate p with the current pthread.
51 e7821682 2004-09-23 devnull _threadinitproc(Proc *p)
53 e7821682 2004-09-23 devnull p->pthreadid = pthread_self();
54 e7821682 2004-09-23 devnull _threadsetproc(p);
58 e7821682 2004-09-23 devnull * Called to exit the current pthread.
61 e7821682 2004-09-23 devnull _threadexitproc(char *exitstr)
63 e7821682 2004-09-23 devnull pthread_exit(nil);
67 e7821682 2004-09-23 devnull * Called to exit all pthreads.
70 e7821682 2004-09-23 devnull _threadexitallproc(char *exitstr)
72 e7821682 2004-09-23 devnull exits(0);
76 e7821682 2004-09-23 devnull * Called to poll for any kids of this pthread.
77 e7821682 2004-09-23 devnull * Wait messages aren't restricted to a particular
78 e7821682 2004-09-23 devnull * pthread, so we have a separate proc responsible
79 e7821682 2004-09-23 devnull * for them. So this is a no-op.
82 e7821682 2004-09-23 devnull _threadwaitkids(Proc *p)
87 e7821682 2004-09-23 devnull * Separate process to wait for child messages.
89 e7821682 2004-09-23 devnull Channel *_threadexecchan;
91 e7821682 2004-09-23 devnull _threadwaitproc(void *v)
93 e7821682 2004-09-23 devnull Channel *c;
94 e7821682 2004-09-23 devnull Waitmsg *w;
95 e7821682 2004-09-23 devnull sigset_t none;
97 e7821682 2004-09-23 devnull sigemptyset(&none);
98 e7821682 2004-09-23 devnull pthread_sigmask(SIG_SETMASK, &none, 0);
100 e7821682 2004-09-23 devnull USED(v);
102 e7821682 2004-09-23 devnull for(;;){
103 e7821682 2004-09-23 devnull w = wait();
104 e7821682 2004-09-23 devnull if(w == nil){
105 e7821682 2004-09-23 devnull if(errno == ECHILD)
106 e7821682 2004-09-23 devnull recvul(_threadexecchan);
107 e7821682 2004-09-23 devnull continue;
109 e7821682 2004-09-23 devnull if((c = _threadwaitchan) != nil)
110 e7821682 2004-09-23 devnull sendp(c, w);
112 e7821682 2004-09-23 devnull free(w);
117 e7821682 2004-09-23 devnull * Called before the first exec.
120 e7821682 2004-09-23 devnull _threadfirstexec(void)
125 e7821682 2004-09-23 devnull _threadmaininit(void)
127 e7821682 2004-09-23 devnull _threadexecchan = chancreate(sizeof(ulong), 1);
128 e7821682 2004-09-23 devnull proccreate(_threadwaitproc, nil, 32*1024);
131 e7821682 2004-09-23 devnull * Sleazy: decrement threadnprocs so that
132 e7821682 2004-09-23 devnull * the existence of the _threadwaitproc proc
133 e7821682 2004-09-23 devnull * doesn't keep us from exiting.
135 e7821682 2004-09-23 devnull lock(&_threadpq.lock);
136 e7821682 2004-09-23 devnull --_threadnprocs;
137 e7821682 2004-09-23 devnull /* print("change %d -> %d\n", _threadnprocs+1, _threadnprocs); */
138 e7821682 2004-09-23 devnull unlock(&_threadpq.lock);
142 e7821682 2004-09-23 devnull _threadafterexec(void)
144 e7821682 2004-09-23 devnull nbsendul(_threadexecchan, 1);
148 e7821682 2004-09-23 devnull * Called to start a new proc.
151 e7821682 2004-09-23 devnull _threadstartproc(Proc *p)
153 e7821682 2004-09-23 devnull Proc *np;
154 e7821682 2004-09-23 devnull pthread_t tid;
155 e7821682 2004-09-23 devnull sigset_t all;
157 e7821682 2004-09-23 devnull np = p->newproc;
158 e7821682 2004-09-23 devnull sigfillset(&all);
159 e7821682 2004-09-23 devnull pthread_sigmask(SIG_SETMASK, &all, nil);
160 e7821682 2004-09-23 devnull if(pthread_create(&tid, nil, (void*(*)(void*))_threadscheduler,
161 e7821682 2004-09-23 devnull np) < 0)
162 e7821682 2004-09-23 devnull sysfatal("pthread_create: %r");
163 e7821682 2004-09-23 devnull np->pthreadid = tid;