Blame


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"
4 e7821682 2004-09-23 devnull
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;
8 e7821682 2004-09-23 devnull
9 e7821682 2004-09-23 devnull /*
10 e7821682 2004-09-23 devnull * Called before we go multiprocess.
11 e7821682 2004-09-23 devnull */
12 e7821682 2004-09-23 devnull void
13 e7821682 2004-09-23 devnull _threadmultiproc(void)
14 e7821682 2004-09-23 devnull {
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);
19 e7821682 2004-09-23 devnull }
20 e7821682 2004-09-23 devnull }
21 e7821682 2004-09-23 devnull
22 e7821682 2004-09-23 devnull /*
23 e7821682 2004-09-23 devnull * Set the proc for the current pthread.
24 e7821682 2004-09-23 devnull */
25 e7821682 2004-09-23 devnull void
26 e7821682 2004-09-23 devnull _threadsetproc(Proc *p)
27 e7821682 2004-09-23 devnull {
28 e7821682 2004-09-23 devnull if(!multi){
29 e7821682 2004-09-23 devnull theproc = p;
30 e7821682 2004-09-23 devnull return;
31 e7821682 2004-09-23 devnull }
32 e7821682 2004-09-23 devnull pthread_setspecific(key, p);
33 e7821682 2004-09-23 devnull }
34 e7821682 2004-09-23 devnull
35 e7821682 2004-09-23 devnull /*
36 e7821682 2004-09-23 devnull * Get the proc for the current pthread.
37 e7821682 2004-09-23 devnull */
38 e7821682 2004-09-23 devnull Proc*
39 e7821682 2004-09-23 devnull _threadgetproc(void)
40 e7821682 2004-09-23 devnull {
41 e7821682 2004-09-23 devnull if(!multi)
42 e7821682 2004-09-23 devnull return theproc;
43 e7821682 2004-09-23 devnull
44 e7821682 2004-09-23 devnull return pthread_getspecific(key);
45 e7821682 2004-09-23 devnull }
46 e7821682 2004-09-23 devnull
47 e7821682 2004-09-23 devnull /*
48 e7821682 2004-09-23 devnull * Called to associate p with the current pthread.
49 e7821682 2004-09-23 devnull */
50 e7821682 2004-09-23 devnull void
51 e7821682 2004-09-23 devnull _threadinitproc(Proc *p)
52 e7821682 2004-09-23 devnull {
53 e7821682 2004-09-23 devnull p->pthreadid = pthread_self();
54 e7821682 2004-09-23 devnull _threadsetproc(p);
55 e7821682 2004-09-23 devnull }
56 e7821682 2004-09-23 devnull
57 e7821682 2004-09-23 devnull /*
58 e7821682 2004-09-23 devnull * Called to exit the current pthread.
59 e7821682 2004-09-23 devnull */
60 e7821682 2004-09-23 devnull void
61 e7821682 2004-09-23 devnull _threadexitproc(char *exitstr)
62 e7821682 2004-09-23 devnull {
63 e7821682 2004-09-23 devnull pthread_exit(nil);
64 e7821682 2004-09-23 devnull }
65 e7821682 2004-09-23 devnull
66 e7821682 2004-09-23 devnull /*
67 e7821682 2004-09-23 devnull * Called to exit all pthreads.
68 e7821682 2004-09-23 devnull */
69 e7821682 2004-09-23 devnull void
70 e7821682 2004-09-23 devnull _threadexitallproc(char *exitstr)
71 e7821682 2004-09-23 devnull {
72 e7821682 2004-09-23 devnull exits(0);
73 e7821682 2004-09-23 devnull }
74 e7821682 2004-09-23 devnull
75 e7821682 2004-09-23 devnull /*
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.
80 e7821682 2004-09-23 devnull */
81 e7821682 2004-09-23 devnull void
82 e7821682 2004-09-23 devnull _threadwaitkids(Proc *p)
83 e7821682 2004-09-23 devnull {
84 e7821682 2004-09-23 devnull }
85 e7821682 2004-09-23 devnull
86 e7821682 2004-09-23 devnull /*
87 e7821682 2004-09-23 devnull * Separate process to wait for child messages.
88 e7821682 2004-09-23 devnull */
89 e7821682 2004-09-23 devnull Channel *_threadexecchan;
90 e7821682 2004-09-23 devnull void
91 e7821682 2004-09-23 devnull _threadwaitproc(void *v)
92 e7821682 2004-09-23 devnull {
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;
96 e7821682 2004-09-23 devnull
97 e7821682 2004-09-23 devnull sigemptyset(&none);
98 e7821682 2004-09-23 devnull pthread_sigmask(SIG_SETMASK, &none, 0);
99 e7821682 2004-09-23 devnull
100 e7821682 2004-09-23 devnull USED(v);
101 e7821682 2004-09-23 devnull
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;
108 e7821682 2004-09-23 devnull }
109 e7821682 2004-09-23 devnull if((c = _threadwaitchan) != nil)
110 e7821682 2004-09-23 devnull sendp(c, w);
111 e7821682 2004-09-23 devnull else
112 e7821682 2004-09-23 devnull free(w);
113 e7821682 2004-09-23 devnull }
114 e7821682 2004-09-23 devnull }
115 e7821682 2004-09-23 devnull
116 e7821682 2004-09-23 devnull /*
117 e7821682 2004-09-23 devnull * Called before the first exec.
118 e7821682 2004-09-23 devnull */
119 e7821682 2004-09-23 devnull void
120 e7821682 2004-09-23 devnull _threadfirstexec(void)
121 e7821682 2004-09-23 devnull {
122 e7821682 2004-09-23 devnull }
123 e7821682 2004-09-23 devnull
124 e7821682 2004-09-23 devnull void
125 e7821682 2004-09-23 devnull _threadmaininit(void)
126 e7821682 2004-09-23 devnull {
127 e7821682 2004-09-23 devnull _threadexecchan = chancreate(sizeof(ulong), 1);
128 e7821682 2004-09-23 devnull proccreate(_threadwaitproc, nil, 32*1024);
129 e7821682 2004-09-23 devnull
130 e7821682 2004-09-23 devnull /*
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.
134 e7821682 2004-09-23 devnull */
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);
139 e7821682 2004-09-23 devnull }
140 e7821682 2004-09-23 devnull
141 e7821682 2004-09-23 devnull void
142 e7821682 2004-09-23 devnull _threadafterexec(void)
143 e7821682 2004-09-23 devnull {
144 e7821682 2004-09-23 devnull nbsendul(_threadexecchan, 1);
145 e7821682 2004-09-23 devnull }
146 e7821682 2004-09-23 devnull
147 e7821682 2004-09-23 devnull /*
148 e7821682 2004-09-23 devnull * Called to start a new proc.
149 e7821682 2004-09-23 devnull */
150 e7821682 2004-09-23 devnull void
151 e7821682 2004-09-23 devnull _threadstartproc(Proc *p)
152 e7821682 2004-09-23 devnull {
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;
156 e7821682 2004-09-23 devnull
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;
164 e7821682 2004-09-23 devnull }