Blame


1 1544f909 2004-12-25 devnull #include "threadimpl.h"
2 1544f909 2004-12-25 devnull
3 b73633b1 2020-12-30 rsc int _threaddebuglevel = 0;
4 1544f909 2004-12-25 devnull
5 1544f909 2004-12-25 devnull static uint threadnproc;
6 1544f909 2004-12-25 devnull static uint threadnsysproc;
7 1544f909 2004-12-25 devnull static Lock threadnproclock;
8 1544f909 2004-12-25 devnull static Ref threadidref;
9 4dbefdd4 2004-12-27 devnull static Proc *threadmainproc;
10 1544f909 2004-12-25 devnull
11 4dbefdd4 2004-12-27 devnull static void addproc(Proc*);
12 4dbefdd4 2004-12-27 devnull static void delproc(Proc*);
13 1544f909 2004-12-25 devnull static void addthread(_Threadlist*, _Thread*);
14 1544f909 2004-12-25 devnull static void delthread(_Threadlist*, _Thread*);
15 df970459 2006-06-26 devnull static int onlist(_Threadlist*, _Thread*);
16 1544f909 2004-12-25 devnull static void addthreadinproc(Proc*, _Thread*);
17 1544f909 2004-12-25 devnull static void delthreadinproc(Proc*, _Thread*);
18 0158bcee 2020-01-12 rsc static void procmain(Proc*);
19 6dde87f8 2005-09-26 devnull static int threadinfo(void*, char*);
20 b73633b1 2020-12-30 rsc static void pthreadscheduler(Proc *p);
21 b73633b1 2020-12-30 rsc static void pthreadsleepschedlocked(Proc *p, _Thread *t);
22 b73633b1 2020-12-30 rsc static void pthreadwakeupschedlocked(Proc *p, _Thread *self, _Thread *t);
23 b73633b1 2020-12-30 rsc static _Thread* procnext(Proc*, _Thread*);
24 1544f909 2004-12-25 devnull
25 2c87dda8 2004-12-28 devnull static void
26 b73633b1 2020-12-30 rsc _threaddebug(_Thread *t, char *fmt, ...)
27 2c87dda8 2004-12-28 devnull {
28 2c87dda8 2004-12-28 devnull va_list arg;
29 2c87dda8 2004-12-28 devnull char buf[128];
30 af89fc10 2005-01-06 devnull char *p;
31 af89fc10 2005-01-06 devnull static int fd = -1;
32 2c87dda8 2004-12-28 devnull
33 5b092791 2005-09-26 devnull if(_threaddebuglevel == 0)
34 5b092791 2005-09-26 devnull return;
35 b8f742db 2005-01-11 devnull
36 af89fc10 2005-01-06 devnull if(fd < 0){
37 af89fc10 2005-01-06 devnull p = strrchr(argv0, '/');
38 af89fc10 2005-01-06 devnull if(p)
39 af89fc10 2005-01-06 devnull p++;
40 af89fc10 2005-01-06 devnull else
41 af89fc10 2005-01-06 devnull p = argv0;
42 af89fc10 2005-01-06 devnull snprint(buf, sizeof buf, "/tmp/%s.tlog", p);
43 af89fc10 2005-01-06 devnull if((fd = create(buf, OWRITE, 0666)) < 0)
44 af89fc10 2005-01-06 devnull fd = open("/dev/null", OWRITE);
45 d93cc14e 2006-06-12 devnull if(fd >= 0 && fd != 2){
46 d93cc14e 2006-06-12 devnull dup(fd, 2);
47 d93cc14e 2006-06-12 devnull close(fd);
48 d93cc14e 2006-06-12 devnull fd = 2;
49 d93cc14e 2006-06-12 devnull }
50 af89fc10 2005-01-06 devnull }
51 2c87dda8 2004-12-28 devnull
52 2c87dda8 2004-12-28 devnull va_start(arg, fmt);
53 2c87dda8 2004-12-28 devnull vsnprint(buf, sizeof buf, fmt, arg);
54 2c87dda8 2004-12-28 devnull va_end(arg);
55 b73633b1 2020-12-30 rsc if(t == nil)
56 b73633b1 2020-12-30 rsc t = proc()->thread;
57 2c87dda8 2004-12-28 devnull if(t)
58 162d0d5c 2020-05-18 rsc fprint(fd, "%p %d.%d: %s\n", proc(), getpid(), t->id, buf);
59 2c87dda8 2004-12-28 devnull else
60 162d0d5c 2020-05-18 rsc fprint(fd, "%p %d._: %s\n", proc(), getpid(), buf);
61 2c87dda8 2004-12-28 devnull }
62 2c87dda8 2004-12-28 devnull
63 1544f909 2004-12-25 devnull static _Thread*
64 1544f909 2004-12-25 devnull getthreadnow(void)
65 1544f909 2004-12-25 devnull {
66 1544f909 2004-12-25 devnull return proc()->thread;
67 1544f909 2004-12-25 devnull }
68 1544f909 2004-12-25 devnull _Thread *(*threadnow)(void) = getthreadnow;
69 1544f909 2004-12-25 devnull
70 1544f909 2004-12-25 devnull static Proc*
71 1544f909 2004-12-25 devnull procalloc(void)
72 1544f909 2004-12-25 devnull {
73 1544f909 2004-12-25 devnull Proc *p;
74 1544f909 2004-12-25 devnull
75 1544f909 2004-12-25 devnull p = malloc(sizeof *p);
76 73722a8b 2004-12-27 devnull if(p == nil)
77 73722a8b 2004-12-27 devnull sysfatal("procalloc malloc: %r");
78 1544f909 2004-12-25 devnull memset(p, 0, sizeof *p);
79 4dbefdd4 2004-12-27 devnull addproc(p);
80 1544f909 2004-12-25 devnull lock(&threadnproclock);
81 1544f909 2004-12-25 devnull threadnproc++;
82 1544f909 2004-12-25 devnull unlock(&threadnproclock);
83 1544f909 2004-12-25 devnull return p;
84 1544f909 2004-12-25 devnull }
85 1544f909 2004-12-25 devnull
86 18571208 2020-12-30 rsc _Thread*
87 18571208 2020-12-30 rsc _threadcreate(Proc *p, void (*fn)(void*), void *arg, uint stack)
88 1544f909 2004-12-25 devnull {
89 1544f909 2004-12-25 devnull _Thread *t;
90 1544f909 2004-12-25 devnull
91 18571208 2020-12-30 rsc USED(stack);
92 8c573cab 2020-01-14 rsc t = malloc(sizeof *t);
93 73722a8b 2004-12-27 devnull if(t == nil)
94 18571208 2020-12-30 rsc sysfatal("threadcreate malloc: %r");
95 1544f909 2004-12-25 devnull memset(t, 0, sizeof *t);
96 1544f909 2004-12-25 devnull t->id = incref(&threadidref);
97 1544f909 2004-12-25 devnull t->startfn = fn;
98 1544f909 2004-12-25 devnull t->startarg = arg;
99 1544f909 2004-12-25 devnull t->proc = p;
100 18571208 2020-12-30 rsc if(p->nthread != 0)
101 18571208 2020-12-30 rsc _threadpthreadstart(p, t);
102 18571208 2020-12-30 rsc else
103 18571208 2020-12-30 rsc t->mainthread = 1;
104 1544f909 2004-12-25 devnull p->nthread++;
105 baef953d 2020-05-18 rsc addthreadinproc(p, t);
106 1544f909 2004-12-25 devnull _threadready(t);
107 1544f909 2004-12-25 devnull return t;
108 1544f909 2004-12-25 devnull }
109 1544f909 2004-12-25 devnull
110 1544f909 2004-12-25 devnull int
111 1544f909 2004-12-25 devnull threadcreate(void (*fn)(void*), void *arg, uint stack)
112 1544f909 2004-12-25 devnull {
113 1544f909 2004-12-25 devnull _Thread *t;
114 1544f909 2004-12-25 devnull
115 1544f909 2004-12-25 devnull t = _threadcreate(proc(), fn, arg, stack);
116 b73633b1 2020-12-30 rsc _threaddebug(nil, "threadcreate %d", t->id);
117 1544f909 2004-12-25 devnull return t->id;
118 1544f909 2004-12-25 devnull }
119 1544f909 2004-12-25 devnull
120 1544f909 2004-12-25 devnull int
121 1544f909 2004-12-25 devnull proccreate(void (*fn)(void*), void *arg, uint stack)
122 1544f909 2004-12-25 devnull {
123 803292c6 2005-01-18 devnull int id;
124 1544f909 2004-12-25 devnull _Thread *t;
125 1544f909 2004-12-25 devnull Proc *p;
126 1544f909 2004-12-25 devnull
127 1544f909 2004-12-25 devnull p = procalloc();
128 1544f909 2004-12-25 devnull t = _threadcreate(p, fn, arg, stack);
129 803292c6 2005-01-18 devnull id = t->id; /* t might be freed after _procstart */
130 b73633b1 2020-12-30 rsc _threaddebug(t, "proccreate %p", p);
131 0158bcee 2020-01-12 rsc _procstart(p, procmain);
132 803292c6 2005-01-18 devnull return id;
133 baef953d 2020-05-18 rsc }
134 baef953d 2020-05-18 rsc
135 1544f909 2004-12-25 devnull void
136 1544f909 2004-12-25 devnull _threadswitch(void)
137 1544f909 2004-12-25 devnull {
138 1544f909 2004-12-25 devnull Proc *p;
139 1544f909 2004-12-25 devnull
140 c8b6342d 2005-01-13 devnull needstack(0);
141 1544f909 2004-12-25 devnull p = proc();
142 cbeb0b26 2006-04-01 devnull /*print("threadswtch %p\n", p); */
143 18571208 2020-12-30 rsc pthreadscheduler(p);
144 1544f909 2004-12-25 devnull }
145 1544f909 2004-12-25 devnull
146 1544f909 2004-12-25 devnull void
147 1544f909 2004-12-25 devnull _threadready(_Thread *t)
148 1544f909 2004-12-25 devnull {
149 1544f909 2004-12-25 devnull Proc *p;
150 1544f909 2004-12-25 devnull
151 1544f909 2004-12-25 devnull p = t->proc;
152 1544f909 2004-12-25 devnull lock(&p->lock);
153 a0a331aa 2005-01-06 devnull p->runrend.l = &p->lock;
154 1544f909 2004-12-25 devnull addthread(&p->runqueue, t);
155 cbeb0b26 2006-04-01 devnull /*print("%d wake for job %d->%d\n", time(0), getpid(), p->osprocid); */
156 8cbd854a 2004-12-27 devnull if(p != proc())
157 a0a331aa 2005-01-06 devnull _procwakeupandunlock(&p->runrend);
158 a0a331aa 2005-01-06 devnull else
159 a0a331aa 2005-01-06 devnull unlock(&p->lock);
160 1544f909 2004-12-25 devnull }
161 1544f909 2004-12-25 devnull
162 8cbd854a 2004-12-27 devnull int
163 615e0f9f 2006-02-07 devnull threadidle(void)
164 615e0f9f 2006-02-07 devnull {
165 615e0f9f 2006-02-07 devnull int n;
166 615e0f9f 2006-02-07 devnull Proc *p;
167 fa325e9b 2020-01-10 cross
168 615e0f9f 2006-02-07 devnull p = proc();
169 615e0f9f 2006-02-07 devnull n = p->nswitch;
170 615e0f9f 2006-02-07 devnull lock(&p->lock);
171 615e0f9f 2006-02-07 devnull p->runrend.l = &p->lock;
172 615e0f9f 2006-02-07 devnull addthread(&p->idlequeue, p->thread);
173 615e0f9f 2006-02-07 devnull unlock(&p->lock);
174 615e0f9f 2006-02-07 devnull _threadswitch();
175 615e0f9f 2006-02-07 devnull return p->nswitch - n;
176 615e0f9f 2006-02-07 devnull }
177 615e0f9f 2006-02-07 devnull
178 615e0f9f 2006-02-07 devnull int
179 1544f909 2004-12-25 devnull threadyield(void)
180 1544f909 2004-12-25 devnull {
181 8cbd854a 2004-12-27 devnull int n;
182 8cbd854a 2004-12-27 devnull Proc *p;
183 8cbd854a 2004-12-27 devnull
184 8cbd854a 2004-12-27 devnull p = proc();
185 8cbd854a 2004-12-27 devnull n = p->nswitch;
186 8cbd854a 2004-12-27 devnull _threadready(p->thread);
187 1544f909 2004-12-25 devnull _threadswitch();
188 8cbd854a 2004-12-27 devnull return p->nswitch - n;
189 1544f909 2004-12-25 devnull }
190 1544f909 2004-12-25 devnull
191 1544f909 2004-12-25 devnull void
192 1544f909 2004-12-25 devnull threadexits(char *msg)
193 1544f909 2004-12-25 devnull {
194 1544f909 2004-12-25 devnull Proc *p;
195 1544f909 2004-12-25 devnull
196 1544f909 2004-12-25 devnull p = proc();
197 4dbefdd4 2004-12-27 devnull if(msg == nil)
198 4dbefdd4 2004-12-27 devnull msg = "";
199 1544f909 2004-12-25 devnull utfecpy(p->msg, p->msg+sizeof p->msg, msg);
200 4dbefdd4 2004-12-27 devnull proc()->thread->exiting = 1;
201 4dbefdd4 2004-12-27 devnull _threadswitch();
202 df970459 2006-06-26 devnull }
203 df970459 2006-06-26 devnull
204 df970459 2006-06-26 devnull void
205 df970459 2006-06-26 devnull threadpin(void)
206 df970459 2006-06-26 devnull {
207 df970459 2006-06-26 devnull Proc *p;
208 df970459 2006-06-26 devnull
209 df970459 2006-06-26 devnull p = proc();
210 df970459 2006-06-26 devnull if(p->pinthread){
211 df970459 2006-06-26 devnull fprint(2, "already pinning a thread - %p %p\n", p->pinthread, p->thread);
212 df970459 2006-06-26 devnull assert(0);
213 df970459 2006-06-26 devnull }
214 df970459 2006-06-26 devnull p->pinthread = p->thread;
215 df970459 2006-06-26 devnull }
216 df970459 2006-06-26 devnull
217 df970459 2006-06-26 devnull void
218 df970459 2006-06-26 devnull threadunpin(void)
219 df970459 2006-06-26 devnull {
220 df970459 2006-06-26 devnull Proc *p;
221 df970459 2006-06-26 devnull
222 df970459 2006-06-26 devnull p = proc();
223 df970459 2006-06-26 devnull if(p->pinthread != p->thread){
224 df970459 2006-06-26 devnull fprint(2, "wrong pinthread - %p %p\n", p->pinthread, p->thread);
225 df970459 2006-06-26 devnull assert(0);
226 df970459 2006-06-26 devnull }
227 df970459 2006-06-26 devnull p->pinthread = nil;
228 69d1259c 2008-07-20 devnull }
229 69d1259c 2008-07-20 devnull
230 69d1259c 2008-07-20 devnull void
231 d19769ae 2008-10-26 rsc threadsysfatal(char *fmt, va_list arg)
232 69d1259c 2008-07-20 devnull {
233 69d1259c 2008-07-20 devnull char buf[256];
234 69d1259c 2008-07-20 devnull
235 69d1259c 2008-07-20 devnull vseprint(buf, buf+sizeof(buf), fmt, arg);
236 69d1259c 2008-07-20 devnull __fixargv0();
237 69d1259c 2008-07-20 devnull fprint(2, "%s: %s\n", argv0 ? argv0 : "<prog>", buf);
238 69d1259c 2008-07-20 devnull threadexitsall(buf);
239 1544f909 2004-12-25 devnull }
240 1544f909 2004-12-25 devnull
241 1544f909 2004-12-25 devnull static void
242 0158bcee 2020-01-12 rsc procmain(Proc *p)
243 0158bcee 2020-01-12 rsc {
244 0158bcee 2020-01-12 rsc _Thread *t;
245 0158bcee 2020-01-12 rsc
246 0158bcee 2020-01-12 rsc _threadsetproc(p);
247 0158bcee 2020-01-12 rsc
248 0158bcee 2020-01-12 rsc /* take out first thread to run on system stack */
249 0158bcee 2020-01-12 rsc t = p->runqueue.head;
250 0158bcee 2020-01-12 rsc delthread(&p->runqueue, t);
251 0158bcee 2020-01-12 rsc
252 0158bcee 2020-01-12 rsc /* run it */
253 0158bcee 2020-01-12 rsc p->thread = t;
254 0158bcee 2020-01-12 rsc t->startfn(t->startarg);
255 0158bcee 2020-01-12 rsc if(p->nthread != 0)
256 0158bcee 2020-01-12 rsc threadexits(nil);
257 0158bcee 2020-01-12 rsc }
258 0158bcee 2020-01-12 rsc
259 baef953d 2020-05-18 rsc void
260 baef953d 2020-05-18 rsc _threadpthreadmain(Proc *p, _Thread *t)
261 baef953d 2020-05-18 rsc {
262 baef953d 2020-05-18 rsc _threadsetproc(p);
263 b73633b1 2020-12-30 rsc lock(&p->lock);
264 b73633b1 2020-12-30 rsc pthreadsleepschedlocked(p, t);
265 b73633b1 2020-12-30 rsc unlock(&p->lock);
266 b73633b1 2020-12-30 rsc _threaddebug(nil, "startfn");
267 baef953d 2020-05-18 rsc t->startfn(t->startarg);
268 baef953d 2020-05-18 rsc threadexits(nil);
269 baef953d 2020-05-18 rsc }
270 baef953d 2020-05-18 rsc
271 0158bcee 2020-01-12 rsc static void
272 b73633b1 2020-12-30 rsc pthreadsleepschedlocked(Proc *p, _Thread *t)
273 b73633b1 2020-12-30 rsc {
274 b73633b1 2020-12-30 rsc _threaddebug(t, "pthreadsleepsched %p %d", p, t->id);;
275 b73633b1 2020-12-30 rsc t->schedrend.l = &p->lock;
276 b73633b1 2020-12-30 rsc while(p->schedthread != t)
277 b73633b1 2020-12-30 rsc _procsleep(&t->schedrend);
278 b73633b1 2020-12-30 rsc }
279 b73633b1 2020-12-30 rsc
280 b73633b1 2020-12-30 rsc static void
281 b73633b1 2020-12-30 rsc pthreadwakeupschedlocked(Proc *p, _Thread *self, _Thread *t)
282 b73633b1 2020-12-30 rsc {
283 b73633b1 2020-12-30 rsc _threaddebug(self, "pthreadwakeupschedlocked %p %d", p, t->id);;
284 91ececc9 2020-12-30 rsc t->schedrend.l = &p->lock;
285 b73633b1 2020-12-30 rsc p->schedthread = t;
286 b73633b1 2020-12-30 rsc _procwakeup(&t->schedrend);
287 b73633b1 2020-12-30 rsc }
288 b73633b1 2020-12-30 rsc
289 b73633b1 2020-12-30 rsc static void
290 b73633b1 2020-12-30 rsc pthreadscheduler(Proc *p)
291 b73633b1 2020-12-30 rsc {
292 b73633b1 2020-12-30 rsc _Thread *self, *t;
293 b73633b1 2020-12-30 rsc
294 b73633b1 2020-12-30 rsc _threaddebug(nil, "scheduler");
295 b73633b1 2020-12-30 rsc lock(&p->lock);
296 b73633b1 2020-12-30 rsc self = p->thread;
297 b73633b1 2020-12-30 rsc p->thread = nil;
298 b73633b1 2020-12-30 rsc _threaddebug(self, "pausing");
299 b73633b1 2020-12-30 rsc
300 b73633b1 2020-12-30 rsc if(self->exiting) {
301 b73633b1 2020-12-30 rsc _threaddebug(self, "exiting");
302 b73633b1 2020-12-30 rsc delthreadinproc(p, self);
303 b73633b1 2020-12-30 rsc p->nthread--;
304 b73633b1 2020-12-30 rsc }
305 b73633b1 2020-12-30 rsc
306 b73633b1 2020-12-30 rsc t = procnext(p, self);
307 b73633b1 2020-12-30 rsc if(t != nil) {
308 b73633b1 2020-12-30 rsc pthreadwakeupschedlocked(p, self, t);
309 b73633b1 2020-12-30 rsc if(!self->exiting) {
310 b73633b1 2020-12-30 rsc pthreadsleepschedlocked(p, self);
311 b73633b1 2020-12-30 rsc _threaddebug(nil, "resume %d", self->id);
312 b73633b1 2020-12-30 rsc unlock(&p->lock);
313 b73633b1 2020-12-30 rsc return;
314 b73633b1 2020-12-30 rsc }
315 b73633b1 2020-12-30 rsc }
316 b73633b1 2020-12-30 rsc
317 b73633b1 2020-12-30 rsc if(t == nil) {
318 b73633b1 2020-12-30 rsc /* Tear down proc bookkeeping. Wait to free p. */
319 b73633b1 2020-12-30 rsc delproc(p);
320 b73633b1 2020-12-30 rsc lock(&threadnproclock);
321 b73633b1 2020-12-30 rsc if(p->sysproc)
322 b73633b1 2020-12-30 rsc --threadnsysproc;
323 b73633b1 2020-12-30 rsc if(--threadnproc == threadnsysproc)
324 b73633b1 2020-12-30 rsc threadexitsall(p->msg);
325 b73633b1 2020-12-30 rsc unlock(&threadnproclock);
326 b73633b1 2020-12-30 rsc }
327 b73633b1 2020-12-30 rsc
328 b73633b1 2020-12-30 rsc /* Tear down pthread. */
329 b73633b1 2020-12-30 rsc if(self->mainthread && p->mainproc) {
330 b73633b1 2020-12-30 rsc _threaddaemonize();
331 b73633b1 2020-12-30 rsc _threaddebug(self, "sleeper");
332 b73633b1 2020-12-30 rsc unlock(&p->lock);
333 b73633b1 2020-12-30 rsc /*
334 b73633b1 2020-12-30 rsc * Avoid bugs with main pthread exiting.
335 b73633b1 2020-12-30 rsc * When all procs are gone, threadexitsall above will happen.
336 b73633b1 2020-12-30 rsc */
337 b73633b1 2020-12-30 rsc for(;;)
338 b73633b1 2020-12-30 rsc sleep(60*60*1000);
339 b73633b1 2020-12-30 rsc }
340 b73633b1 2020-12-30 rsc _threadsetproc(nil);
341 b73633b1 2020-12-30 rsc free(self);
342 b73633b1 2020-12-30 rsc unlock(&p->lock);
343 b73633b1 2020-12-30 rsc if(t == nil)
344 b73633b1 2020-12-30 rsc free(p);
345 481b596d 2020-01-14 rsc _threadpexit();
346 b73633b1 2020-12-30 rsc }
347 b73633b1 2020-12-30 rsc
348 b73633b1 2020-12-30 rsc static _Thread*
349 b73633b1 2020-12-30 rsc procnext(Proc *p, _Thread *self)
350 b73633b1 2020-12-30 rsc {
351 b73633b1 2020-12-30 rsc _Thread *t;
352 b73633b1 2020-12-30 rsc
353 b73633b1 2020-12-30 rsc if((t = p->pinthread) != nil){
354 b73633b1 2020-12-30 rsc while(!onlist(&p->runqueue, t)){
355 b73633b1 2020-12-30 rsc p->runrend.l = &p->lock;
356 b73633b1 2020-12-30 rsc _threaddebug(self, "scheduler sleep (pin)");
357 b73633b1 2020-12-30 rsc _procsleep(&p->runrend);
358 b73633b1 2020-12-30 rsc _threaddebug(self, "scheduler wake (pin)");
359 b73633b1 2020-12-30 rsc }
360 b73633b1 2020-12-30 rsc } else
361 b73633b1 2020-12-30 rsc while((t = p->runqueue.head) == nil){
362 b73633b1 2020-12-30 rsc if(p->nthread == 0)
363 b73633b1 2020-12-30 rsc return nil;
364 b73633b1 2020-12-30 rsc if((t = p->idlequeue.head) != nil){
365 b73633b1 2020-12-30 rsc /*
366 b73633b1 2020-12-30 rsc * Run all the idling threads once.
367 b73633b1 2020-12-30 rsc */
368 b73633b1 2020-12-30 rsc while((t = p->idlequeue.head) != nil){
369 b73633b1 2020-12-30 rsc delthread(&p->idlequeue, t);
370 b73633b1 2020-12-30 rsc addthread(&p->runqueue, t);
371 b73633b1 2020-12-30 rsc }
372 b73633b1 2020-12-30 rsc continue;
373 b73633b1 2020-12-30 rsc }
374 b73633b1 2020-12-30 rsc p->runrend.l = &p->lock;
375 b73633b1 2020-12-30 rsc _threaddebug(self, "scheduler sleep");
376 b73633b1 2020-12-30 rsc _procsleep(&p->runrend);
377 b73633b1 2020-12-30 rsc _threaddebug(self, "scheduler wake");
378 b73633b1 2020-12-30 rsc }
379 b73633b1 2020-12-30 rsc
380 b73633b1 2020-12-30 rsc if(p->pinthread && p->pinthread != t)
381 b73633b1 2020-12-30 rsc fprint(2, "p->pinthread %p t %p\n", p->pinthread, t);
382 b73633b1 2020-12-30 rsc assert(p->pinthread == nil || p->pinthread == t);
383 b73633b1 2020-12-30 rsc delthread(&p->runqueue, t);
384 b73633b1 2020-12-30 rsc
385 b73633b1 2020-12-30 rsc p->thread = t;
386 b73633b1 2020-12-30 rsc p->nswitch++;
387 b73633b1 2020-12-30 rsc return t;
388 1544f909 2004-12-25 devnull }
389 1544f909 2004-12-25 devnull
390 1544f909 2004-12-25 devnull void
391 1544f909 2004-12-25 devnull _threadsetsysproc(void)
392 1544f909 2004-12-25 devnull {
393 1544f909 2004-12-25 devnull lock(&threadnproclock);
394 1544f909 2004-12-25 devnull if(++threadnsysproc == threadnproc)
395 8ee6ad4d 2005-02-14 devnull threadexitsall(nil);
396 1544f909 2004-12-25 devnull unlock(&threadnproclock);
397 1544f909 2004-12-25 devnull proc()->sysproc = 1;
398 1544f909 2004-12-25 devnull }
399 1544f909 2004-12-25 devnull
400 4dbefdd4 2004-12-27 devnull void**
401 4dbefdd4 2004-12-27 devnull procdata(void)
402 4dbefdd4 2004-12-27 devnull {
403 4dbefdd4 2004-12-27 devnull return &proc()->udata;
404 8dd8a81f 2005-03-18 devnull }
405 8dd8a81f 2005-03-18 devnull
406 8dd8a81f 2005-03-18 devnull void**
407 8dd8a81f 2005-03-18 devnull threaddata(void)
408 8dd8a81f 2005-03-18 devnull {
409 8dd8a81f 2005-03-18 devnull return &proc()->thread->udata;
410 4dbefdd4 2004-12-27 devnull }
411 4dbefdd4 2004-12-27 devnull
412 4dbefdd4 2004-12-27 devnull extern Jmp *(*_notejmpbuf)(void);
413 4dbefdd4 2004-12-27 devnull static Jmp*
414 4dbefdd4 2004-12-27 devnull threadnotejmp(void)
415 4dbefdd4 2004-12-27 devnull {
416 4dbefdd4 2004-12-27 devnull return &proc()->sigjmp;
417 4dbefdd4 2004-12-27 devnull }
418 4dbefdd4 2004-12-27 devnull
419 1544f909 2004-12-25 devnull /*
420 1544f909 2004-12-25 devnull * debugging
421 1544f909 2004-12-25 devnull */
422 1544f909 2004-12-25 devnull void
423 1544f909 2004-12-25 devnull threadsetname(char *fmt, ...)
424 1544f909 2004-12-25 devnull {
425 1544f909 2004-12-25 devnull va_list arg;
426 1544f909 2004-12-25 devnull _Thread *t;
427 1544f909 2004-12-25 devnull
428 1544f909 2004-12-25 devnull t = proc()->thread;
429 1544f909 2004-12-25 devnull va_start(arg, fmt);
430 1544f909 2004-12-25 devnull vsnprint(t->name, sizeof t->name, fmt, arg);
431 1544f909 2004-12-25 devnull va_end(arg);
432 515b6e5b 2005-01-18 devnull }
433 515b6e5b 2005-01-18 devnull
434 515b6e5b 2005-01-18 devnull char*
435 515b6e5b 2005-01-18 devnull threadgetname(void)
436 515b6e5b 2005-01-18 devnull {
437 515b6e5b 2005-01-18 devnull return proc()->thread->name;
438 1544f909 2004-12-25 devnull }
439 1544f909 2004-12-25 devnull
440 1544f909 2004-12-25 devnull void
441 1544f909 2004-12-25 devnull threadsetstate(char *fmt, ...)
442 1544f909 2004-12-25 devnull {
443 1544f909 2004-12-25 devnull va_list arg;
444 1544f909 2004-12-25 devnull _Thread *t;
445 1544f909 2004-12-25 devnull
446 1544f909 2004-12-25 devnull t = proc()->thread;
447 1544f909 2004-12-25 devnull va_start(arg, fmt);
448 1544f909 2004-12-25 devnull vsnprint(t->state, sizeof t->name, fmt, arg);
449 1544f909 2004-12-25 devnull va_end(arg);
450 c8b6342d 2005-01-13 devnull }
451 c8b6342d 2005-01-13 devnull
452 9eda38e5 2006-02-05 devnull int
453 9eda38e5 2006-02-05 devnull threadid(void)
454 9eda38e5 2006-02-05 devnull {
455 9eda38e5 2006-02-05 devnull _Thread *t;
456 fa325e9b 2020-01-10 cross
457 9eda38e5 2006-02-05 devnull t = proc()->thread;
458 9eda38e5 2006-02-05 devnull return t->id;
459 9eda38e5 2006-02-05 devnull }
460 9eda38e5 2006-02-05 devnull
461 c8b6342d 2005-01-13 devnull void
462 c8b6342d 2005-01-13 devnull needstack(int n)
463 c8b6342d 2005-01-13 devnull {
464 c8b6342d 2005-01-13 devnull _Thread *t;
465 c8b6342d 2005-01-13 devnull
466 c8b6342d 2005-01-13 devnull t = proc()->thread;
467 8c573cab 2020-01-14 rsc if(t->stk == nil)
468 8c573cab 2020-01-14 rsc return;
469 c8b6342d 2005-01-13 devnull
470 c8b6342d 2005-01-13 devnull if((char*)&t <= (char*)t->stk
471 c8b6342d 2005-01-13 devnull || (char*)&t - (char*)t->stk < 256+n){
472 1fdb4a54 2005-01-23 devnull fprint(2, "thread stack overflow: &t=%p tstk=%p n=%d\n", &t, t->stk, 256+n);
473 c8b6342d 2005-01-13 devnull abort();
474 c8b6342d 2005-01-13 devnull }
475 faf1fb6c 2008-07-09 rsc }
476 faf1fb6c 2008-07-09 rsc
477 faf1fb6c 2008-07-09 rsc static int
478 faf1fb6c 2008-07-09 rsc singlethreaded(void)
479 faf1fb6c 2008-07-09 rsc {
480 faf1fb6c 2008-07-09 rsc return threadnproc == 1 && _threadprocs->nthread == 1;
481 1544f909 2004-12-25 devnull }
482 1544f909 2004-12-25 devnull
483 1544f909 2004-12-25 devnull /*
484 1544f909 2004-12-25 devnull * locking
485 1544f909 2004-12-25 devnull */
486 1544f909 2004-12-25 devnull static int
487 1544f909 2004-12-25 devnull threadqlock(QLock *l, int block, ulong pc)
488 1544f909 2004-12-25 devnull {
489 cbeb0b26 2006-04-01 devnull /*print("threadqlock %p\n", l); */
490 1544f909 2004-12-25 devnull lock(&l->l);
491 1544f909 2004-12-25 devnull if(l->owner == nil){
492 1544f909 2004-12-25 devnull l->owner = (*threadnow)();
493 cbeb0b26 2006-04-01 devnull /*print("qlock %p @%#x by %p\n", l, pc, l->owner); */
494 162d0d5c 2020-05-18 rsc if(l->owner == nil) {
495 162d0d5c 2020-05-18 rsc fprint(2, "%s: qlock uncontended owner=nil oops\n", argv0);
496 162d0d5c 2020-05-18 rsc abort();
497 162d0d5c 2020-05-18 rsc }
498 1544f909 2004-12-25 devnull unlock(&l->l);
499 1544f909 2004-12-25 devnull return 1;
500 1544f909 2004-12-25 devnull }
501 1544f909 2004-12-25 devnull if(!block){
502 1544f909 2004-12-25 devnull unlock(&l->l);
503 1544f909 2004-12-25 devnull return 0;
504 1544f909 2004-12-25 devnull }
505 faf1fb6c 2008-07-09 rsc
506 faf1fb6c 2008-07-09 rsc if(singlethreaded()){
507 faf1fb6c 2008-07-09 rsc fprint(2, "qlock deadlock\n");
508 faf1fb6c 2008-07-09 rsc abort();
509 faf1fb6c 2008-07-09 rsc }
510 faf1fb6c 2008-07-09 rsc
511 cbeb0b26 2006-04-01 devnull /*print("qsleep %p @%#x by %p\n", l, pc, (*threadnow)()); */
512 1544f909 2004-12-25 devnull addthread(&l->waiting, (*threadnow)());
513 1544f909 2004-12-25 devnull unlock(&l->l);
514 1544f909 2004-12-25 devnull
515 1544f909 2004-12-25 devnull _threadswitch();
516 1544f909 2004-12-25 devnull
517 1544f909 2004-12-25 devnull if(l->owner != (*threadnow)()){
518 15cd8255 2005-01-04 devnull fprint(2, "%s: qlock pc=0x%lux owner=%p self=%p oops\n",
519 15cd8255 2005-01-04 devnull argv0, pc, l->owner, (*threadnow)());
520 1544f909 2004-12-25 devnull abort();
521 1544f909 2004-12-25 devnull }
522 162d0d5c 2020-05-18 rsc if(l->owner == nil) {
523 162d0d5c 2020-05-18 rsc fprint(2, "%s: qlock threadswitch owner=nil oops\n", argv0);
524 162d0d5c 2020-05-18 rsc abort();
525 162d0d5c 2020-05-18 rsc }
526 162d0d5c 2020-05-18 rsc
527 cbeb0b26 2006-04-01 devnull /*print("qlock wakeup %p @%#x by %p\n", l, pc, (*threadnow)()); */
528 1544f909 2004-12-25 devnull return 1;
529 1544f909 2004-12-25 devnull }
530 1544f909 2004-12-25 devnull
531 1544f909 2004-12-25 devnull static void
532 1544f909 2004-12-25 devnull threadqunlock(QLock *l, ulong pc)
533 1544f909 2004-12-25 devnull {
534 80b8842f 2005-02-15 devnull _Thread *ready;
535 fa325e9b 2020-01-10 cross
536 1544f909 2004-12-25 devnull lock(&l->l);
537 cbeb0b26 2006-04-01 devnull /*print("qlock unlock %p @%#x by %p (owner %p)\n", l, pc, (*threadnow)(), l->owner); */
538 1aa9c533 2005-01-07 devnull if(l->owner == 0){
539 15cd8255 2005-01-04 devnull fprint(2, "%s: qunlock pc=0x%lux owner=%p self=%p oops\n",
540 15cd8255 2005-01-04 devnull argv0, pc, l->owner, (*threadnow)());
541 1aa9c533 2005-01-07 devnull abort();
542 1544f909 2004-12-25 devnull }
543 80b8842f 2005-02-15 devnull if((l->owner = ready = l->waiting.head) != nil)
544 1544f909 2004-12-25 devnull delthread(&l->waiting, l->owner);
545 80b8842f 2005-02-15 devnull /*
546 80b8842f 2005-02-15 devnull * N.B. Cannot call _threadready() before unlocking l->l,
547 80b8842f 2005-02-15 devnull * because the thread we are readying might:
548 80b8842f 2005-02-15 devnull * - be in another proc
549 80b8842f 2005-02-15 devnull * - start running immediately
550 80b8842f 2005-02-15 devnull * - and free l before we get a chance to run again
551 80b8842f 2005-02-15 devnull */
552 1544f909 2004-12-25 devnull unlock(&l->l);
553 80b8842f 2005-02-15 devnull if(ready)
554 80b8842f 2005-02-15 devnull _threadready(l->owner);
555 1544f909 2004-12-25 devnull }
556 1544f909 2004-12-25 devnull
557 1544f909 2004-12-25 devnull static int
558 1544f909 2004-12-25 devnull threadrlock(RWLock *l, int block, ulong pc)
559 1544f909 2004-12-25 devnull {
560 1544f909 2004-12-25 devnull USED(pc);
561 1544f909 2004-12-25 devnull
562 1544f909 2004-12-25 devnull lock(&l->l);
563 1544f909 2004-12-25 devnull if(l->writer == nil && l->wwaiting.head == nil){
564 1544f909 2004-12-25 devnull l->readers++;
565 1544f909 2004-12-25 devnull unlock(&l->l);
566 1544f909 2004-12-25 devnull return 1;
567 1544f909 2004-12-25 devnull }
568 1544f909 2004-12-25 devnull if(!block){
569 1544f909 2004-12-25 devnull unlock(&l->l);
570 1544f909 2004-12-25 devnull return 0;
571 1544f909 2004-12-25 devnull }
572 faf1fb6c 2008-07-09 rsc if(singlethreaded()){
573 faf1fb6c 2008-07-09 rsc fprint(2, "rlock deadlock\n");
574 faf1fb6c 2008-07-09 rsc abort();
575 faf1fb6c 2008-07-09 rsc }
576 1544f909 2004-12-25 devnull addthread(&l->rwaiting, (*threadnow)());
577 1544f909 2004-12-25 devnull unlock(&l->l);
578 1544f909 2004-12-25 devnull _threadswitch();
579 fa325e9b 2020-01-10 cross return 1;
580 1544f909 2004-12-25 devnull }
581 1544f909 2004-12-25 devnull
582 1544f909 2004-12-25 devnull static int
583 1544f909 2004-12-25 devnull threadwlock(RWLock *l, int block, ulong pc)
584 1544f909 2004-12-25 devnull {
585 1544f909 2004-12-25 devnull USED(pc);
586 1544f909 2004-12-25 devnull
587 1544f909 2004-12-25 devnull lock(&l->l);
588 1544f909 2004-12-25 devnull if(l->writer == nil && l->readers == 0){
589 1544f909 2004-12-25 devnull l->writer = (*threadnow)();
590 1544f909 2004-12-25 devnull unlock(&l->l);
591 1544f909 2004-12-25 devnull return 1;
592 1544f909 2004-12-25 devnull }
593 1544f909 2004-12-25 devnull if(!block){
594 1544f909 2004-12-25 devnull unlock(&l->l);
595 1544f909 2004-12-25 devnull return 0;
596 faf1fb6c 2008-07-09 rsc }
597 faf1fb6c 2008-07-09 rsc if(singlethreaded()){
598 faf1fb6c 2008-07-09 rsc fprint(2, "wlock deadlock\n");
599 faf1fb6c 2008-07-09 rsc abort();
600 1544f909 2004-12-25 devnull }
601 1544f909 2004-12-25 devnull addthread(&l->wwaiting, (*threadnow)());
602 1544f909 2004-12-25 devnull unlock(&l->l);
603 1544f909 2004-12-25 devnull _threadswitch();
604 1544f909 2004-12-25 devnull return 1;
605 1544f909 2004-12-25 devnull }
606 1544f909 2004-12-25 devnull
607 1544f909 2004-12-25 devnull static void
608 1544f909 2004-12-25 devnull threadrunlock(RWLock *l, ulong pc)
609 1544f909 2004-12-25 devnull {
610 1544f909 2004-12-25 devnull _Thread *t;
611 1544f909 2004-12-25 devnull
612 1544f909 2004-12-25 devnull USED(pc);
613 80b8842f 2005-02-15 devnull t = nil;
614 1544f909 2004-12-25 devnull lock(&l->l);
615 1544f909 2004-12-25 devnull --l->readers;
616 1544f909 2004-12-25 devnull if(l->readers == 0 && (t = l->wwaiting.head) != nil){
617 1544f909 2004-12-25 devnull delthread(&l->wwaiting, t);
618 1544f909 2004-12-25 devnull l->writer = t;
619 1544f909 2004-12-25 devnull }
620 1544f909 2004-12-25 devnull unlock(&l->l);
621 80b8842f 2005-02-15 devnull if(t)
622 80b8842f 2005-02-15 devnull _threadready(t);
623 80b8842f 2005-02-15 devnull
624 1544f909 2004-12-25 devnull }
625 1544f909 2004-12-25 devnull
626 1544f909 2004-12-25 devnull static void
627 1544f909 2004-12-25 devnull threadwunlock(RWLock *l, ulong pc)
628 1544f909 2004-12-25 devnull {
629 1544f909 2004-12-25 devnull _Thread *t;
630 1544f909 2004-12-25 devnull
631 1544f909 2004-12-25 devnull USED(pc);
632 1544f909 2004-12-25 devnull lock(&l->l);
633 1544f909 2004-12-25 devnull l->writer = nil;
634 1544f909 2004-12-25 devnull assert(l->readers == 0);
635 1544f909 2004-12-25 devnull while((t = l->rwaiting.head) != nil){
636 1544f909 2004-12-25 devnull delthread(&l->rwaiting, t);
637 1544f909 2004-12-25 devnull l->readers++;
638 1544f909 2004-12-25 devnull _threadready(t);
639 1544f909 2004-12-25 devnull }
640 80b8842f 2005-02-15 devnull t = nil;
641 1544f909 2004-12-25 devnull if(l->readers == 0 && (t = l->wwaiting.head) != nil){
642 1544f909 2004-12-25 devnull delthread(&l->wwaiting, t);
643 1544f909 2004-12-25 devnull l->writer = t;
644 1544f909 2004-12-25 devnull }
645 1544f909 2004-12-25 devnull unlock(&l->l);
646 80b8842f 2005-02-15 devnull if(t)
647 80b8842f 2005-02-15 devnull _threadready(t);
648 1544f909 2004-12-25 devnull }
649 1544f909 2004-12-25 devnull
650 1544f909 2004-12-25 devnull /*
651 1544f909 2004-12-25 devnull * sleep and wakeup
652 1544f909 2004-12-25 devnull */
653 1544f909 2004-12-25 devnull static void
654 1544f909 2004-12-25 devnull threadrsleep(Rendez *r, ulong pc)
655 1544f909 2004-12-25 devnull {
656 faf1fb6c 2008-07-09 rsc if(singlethreaded()){
657 faf1fb6c 2008-07-09 rsc fprint(2, "rsleep deadlock\n");
658 faf1fb6c 2008-07-09 rsc abort();
659 faf1fb6c 2008-07-09 rsc }
660 1544f909 2004-12-25 devnull addthread(&r->waiting, proc()->thread);
661 1544f909 2004-12-25 devnull qunlock(r->l);
662 1544f909 2004-12-25 devnull _threadswitch();
663 1544f909 2004-12-25 devnull qlock(r->l);
664 1544f909 2004-12-25 devnull }
665 1544f909 2004-12-25 devnull
666 1544f909 2004-12-25 devnull static int
667 1544f909 2004-12-25 devnull threadrwakeup(Rendez *r, int all, ulong pc)
668 1544f909 2004-12-25 devnull {
669 1544f909 2004-12-25 devnull int i;
670 1544f909 2004-12-25 devnull _Thread *t;
671 1544f909 2004-12-25 devnull
672 b73633b1 2020-12-30 rsc _threaddebug(nil, "rwakeup %p %d", r, all);
673 1544f909 2004-12-25 devnull for(i=0;; i++){
674 1544f909 2004-12-25 devnull if(i==1 && !all)
675 1544f909 2004-12-25 devnull break;
676 1544f909 2004-12-25 devnull if((t = r->waiting.head) == nil)
677 1544f909 2004-12-25 devnull break;
678 b73633b1 2020-12-30 rsc _threaddebug(nil, "rwakeup %p %d -> wake %d", r, all, t->id);
679 1544f909 2004-12-25 devnull delthread(&r->waiting, t);
680 fa325e9b 2020-01-10 cross _threadready(t);
681 b73633b1 2020-12-30 rsc _threaddebug(nil, "rwakeup %p %d -> loop", r, all);
682 1544f909 2004-12-25 devnull }
683 b73633b1 2020-12-30 rsc _threaddebug(nil, "rwakeup %p %d -> total %d", r, all, i);
684 1544f909 2004-12-25 devnull return i;
685 1544f909 2004-12-25 devnull }
686 1544f909 2004-12-25 devnull
687 1544f909 2004-12-25 devnull /*
688 4dbefdd4 2004-12-27 devnull * startup
689 4dbefdd4 2004-12-27 devnull */
690 4dbefdd4 2004-12-27 devnull
691 4dbefdd4 2004-12-27 devnull static int threadargc;
692 4dbefdd4 2004-12-27 devnull static char **threadargv;
693 4dbefdd4 2004-12-27 devnull int mainstacksize;
694 d93cc14e 2006-06-12 devnull extern int _p9usepwlibrary; /* getgrgid etc. smash the stack - tell _p9dir just say no */
695 4dbefdd4 2004-12-27 devnull static void
696 4dbefdd4 2004-12-27 devnull threadmainstart(void *v)
697 4dbefdd4 2004-12-27 devnull {
698 4dbefdd4 2004-12-27 devnull USED(v);
699 0b561695 2005-01-16 devnull
700 0b561695 2005-01-16 devnull /*
701 0b561695 2005-01-16 devnull * N.B. This call to proc() is a program's first call (indirectly) to a
702 0b561695 2005-01-16 devnull * pthreads function while executing on a non-pthreads-allocated
703 0b561695 2005-01-16 devnull * stack. If the pthreads implementation is using the stack pointer
704 0b561695 2005-01-16 devnull * to locate the per-thread data, then this call will blow up.
705 0b561695 2005-01-16 devnull * This means the pthread implementation is not suitable for
706 0b561695 2005-01-16 devnull * running under libthread. Time to write your own. Sorry.
707 0b561695 2005-01-16 devnull */
708 d93cc14e 2006-06-12 devnull _p9usepwlibrary = 0;
709 4dbefdd4 2004-12-27 devnull threadmainproc = proc();
710 4dbefdd4 2004-12-27 devnull threadmain(threadargc, threadargv);
711 2c87dda8 2004-12-28 devnull }
712 2c87dda8 2004-12-28 devnull
713 d19769ae 2008-10-26 rsc extern void (*_sysfatal)(char*, va_list);
714 69d1259c 2008-07-20 devnull
715 4dbefdd4 2004-12-27 devnull int
716 4dbefdd4 2004-12-27 devnull main(int argc, char **argv)
717 4dbefdd4 2004-12-27 devnull {
718 4dbefdd4 2004-12-27 devnull Proc *p;
719 b73633b1 2020-12-30 rsc _Thread *t;
720 baef953d 2020-05-18 rsc char *opts;
721 1d2533d0 2004-12-28 devnull
722 1d2533d0 2004-12-28 devnull argv0 = argv[0];
723 4dbefdd4 2004-12-27 devnull
724 baef953d 2020-05-18 rsc opts = getenv("LIBTHREAD");
725 baef953d 2020-05-18 rsc if(opts == nil)
726 baef953d 2020-05-18 rsc opts = "";
727 baef953d 2020-05-18 rsc
728 b3a20a96 2020-12-30 rsc if(threadmaybackground() && strstr(opts, "nodaemon") == nil && getenv("NOLIBTHREADDAEMONIZE") == nil)
729 615e0f9f 2006-02-07 devnull _threadsetupdaemonize();
730 2c87dda8 2004-12-28 devnull
731 4dbefdd4 2004-12-27 devnull threadargc = argc;
732 4dbefdd4 2004-12-27 devnull threadargv = argv;
733 4dbefdd4 2004-12-27 devnull
734 4dbefdd4 2004-12-27 devnull /*
735 4dbefdd4 2004-12-27 devnull * Install locking routines into C library.
736 4dbefdd4 2004-12-27 devnull */
737 4dbefdd4 2004-12-27 devnull _lock = _threadlock;
738 4dbefdd4 2004-12-27 devnull _unlock = _threadunlock;
739 4dbefdd4 2004-12-27 devnull _qlock = threadqlock;
740 4dbefdd4 2004-12-27 devnull _qunlock = threadqunlock;
741 4dbefdd4 2004-12-27 devnull _rlock = threadrlock;
742 4dbefdd4 2004-12-27 devnull _runlock = threadrunlock;
743 4dbefdd4 2004-12-27 devnull _wlock = threadwlock;
744 4dbefdd4 2004-12-27 devnull _wunlock = threadwunlock;
745 4dbefdd4 2004-12-27 devnull _rsleep = threadrsleep;
746 4dbefdd4 2004-12-27 devnull _rwakeup = threadrwakeup;
747 4dbefdd4 2004-12-27 devnull _notejmpbuf = threadnotejmp;
748 df970459 2006-06-26 devnull _pin = threadpin;
749 df970459 2006-06-26 devnull _unpin = threadunpin;
750 69d1259c 2008-07-20 devnull _sysfatal = threadsysfatal;
751 4dbefdd4 2004-12-27 devnull
752 4dbefdd4 2004-12-27 devnull _pthreadinit();
753 4dbefdd4 2004-12-27 devnull p = procalloc();
754 8ee6ad4d 2005-02-14 devnull p->mainproc = 1;
755 4dbefdd4 2004-12-27 devnull _threadsetproc(p);
756 4dbefdd4 2004-12-27 devnull if(mainstacksize == 0)
757 a0e8d02d 2005-01-23 devnull mainstacksize = 256*1024;
758 af6e459f 2006-04-21 devnull atnotify(threadinfo, 1);
759 b73633b1 2020-12-30 rsc t = _threadcreate(p, threadmainstart, nil, mainstacksize);
760 b73633b1 2020-12-30 rsc t->mainthread = 1;
761 0158bcee 2020-01-12 rsc procmain(p);
762 18571208 2020-12-30 rsc sysfatal("procmain returned in libthread");
763 8ee6ad4d 2005-02-14 devnull /* does not return */
764 15cd8255 2005-01-04 devnull return 0;
765 4dbefdd4 2004-12-27 devnull }
766 4dbefdd4 2004-12-27 devnull
767 4dbefdd4 2004-12-27 devnull /*
768 1544f909 2004-12-25 devnull * hooray for linked lists
769 1544f909 2004-12-25 devnull */
770 1544f909 2004-12-25 devnull static void
771 1544f909 2004-12-25 devnull addthread(_Threadlist *l, _Thread *t)
772 1544f909 2004-12-25 devnull {
773 1544f909 2004-12-25 devnull if(l->tail){
774 1544f909 2004-12-25 devnull l->tail->next = t;
775 1544f909 2004-12-25 devnull t->prev = l->tail;
776 1544f909 2004-12-25 devnull }else{
777 1544f909 2004-12-25 devnull l->head = t;
778 1544f909 2004-12-25 devnull t->prev = nil;
779 1544f909 2004-12-25 devnull }
780 1544f909 2004-12-25 devnull l->tail = t;
781 1544f909 2004-12-25 devnull t->next = nil;
782 1544f909 2004-12-25 devnull }
783 1544f909 2004-12-25 devnull
784 1544f909 2004-12-25 devnull static void
785 1544f909 2004-12-25 devnull delthread(_Threadlist *l, _Thread *t)
786 1544f909 2004-12-25 devnull {
787 1544f909 2004-12-25 devnull if(t->prev)
788 1544f909 2004-12-25 devnull t->prev->next = t->next;
789 1544f909 2004-12-25 devnull else
790 1544f909 2004-12-25 devnull l->head = t->next;
791 1544f909 2004-12-25 devnull if(t->next)
792 1544f909 2004-12-25 devnull t->next->prev = t->prev;
793 1544f909 2004-12-25 devnull else
794 1544f909 2004-12-25 devnull l->tail = t->prev;
795 1544f909 2004-12-25 devnull }
796 1544f909 2004-12-25 devnull
797 df970459 2006-06-26 devnull /* inefficient but rarely used */
798 df970459 2006-06-26 devnull static int
799 df970459 2006-06-26 devnull onlist(_Threadlist *l, _Thread *t)
800 df970459 2006-06-26 devnull {
801 df970459 2006-06-26 devnull _Thread *tt;
802 df970459 2006-06-26 devnull
803 df970459 2006-06-26 devnull for(tt = l->head; tt; tt=tt->next)
804 df970459 2006-06-26 devnull if(tt == t)
805 df970459 2006-06-26 devnull return 1;
806 df970459 2006-06-26 devnull return 0;
807 df970459 2006-06-26 devnull }
808 df970459 2006-06-26 devnull
809 1544f909 2004-12-25 devnull static void
810 1544f909 2004-12-25 devnull addthreadinproc(Proc *p, _Thread *t)
811 1544f909 2004-12-25 devnull {
812 1544f909 2004-12-25 devnull _Threadlist *l;
813 1544f909 2004-12-25 devnull
814 1544f909 2004-12-25 devnull l = &p->allthreads;
815 1544f909 2004-12-25 devnull if(l->tail){
816 1544f909 2004-12-25 devnull l->tail->allnext = t;
817 1544f909 2004-12-25 devnull t->allprev = l->tail;
818 1544f909 2004-12-25 devnull }else{
819 1544f909 2004-12-25 devnull l->head = t;
820 1544f909 2004-12-25 devnull t->allprev = nil;
821 1544f909 2004-12-25 devnull }
822 1544f909 2004-12-25 devnull l->tail = t;
823 1544f909 2004-12-25 devnull t->allnext = nil;
824 1544f909 2004-12-25 devnull }
825 1544f909 2004-12-25 devnull
826 1544f909 2004-12-25 devnull static void
827 1544f909 2004-12-25 devnull delthreadinproc(Proc *p, _Thread *t)
828 1544f909 2004-12-25 devnull {
829 1544f909 2004-12-25 devnull _Threadlist *l;
830 1544f909 2004-12-25 devnull
831 1544f909 2004-12-25 devnull l = &p->allthreads;
832 1544f909 2004-12-25 devnull if(t->allprev)
833 1544f909 2004-12-25 devnull t->allprev->allnext = t->allnext;
834 1544f909 2004-12-25 devnull else
835 1544f909 2004-12-25 devnull l->head = t->allnext;
836 1544f909 2004-12-25 devnull if(t->allnext)
837 1544f909 2004-12-25 devnull t->allnext->allprev = t->allprev;
838 1544f909 2004-12-25 devnull else
839 1544f909 2004-12-25 devnull l->tail = t->allprev;
840 1544f909 2004-12-25 devnull }
841 1544f909 2004-12-25 devnull
842 4dbefdd4 2004-12-27 devnull Proc *_threadprocs;
843 4dbefdd4 2004-12-27 devnull Lock _threadprocslock;
844 4dbefdd4 2004-12-27 devnull static Proc *_threadprocstail;
845 1544f909 2004-12-25 devnull
846 1544f909 2004-12-25 devnull static void
847 4dbefdd4 2004-12-27 devnull addproc(Proc *p)
848 1544f909 2004-12-25 devnull {
849 4dbefdd4 2004-12-27 devnull lock(&_threadprocslock);
850 4dbefdd4 2004-12-27 devnull if(_threadprocstail){
851 4dbefdd4 2004-12-27 devnull _threadprocstail->next = p;
852 4dbefdd4 2004-12-27 devnull p->prev = _threadprocstail;
853 4dbefdd4 2004-12-27 devnull }else{
854 4dbefdd4 2004-12-27 devnull _threadprocs = p;
855 4dbefdd4 2004-12-27 devnull p->prev = nil;
856 4dbefdd4 2004-12-27 devnull }
857 4dbefdd4 2004-12-27 devnull _threadprocstail = p;
858 4dbefdd4 2004-12-27 devnull p->next = nil;
859 4dbefdd4 2004-12-27 devnull unlock(&_threadprocslock);
860 e1dc7e45 2004-12-27 devnull }
861 e1dc7e45 2004-12-27 devnull
862 4dbefdd4 2004-12-27 devnull static void
863 4dbefdd4 2004-12-27 devnull delproc(Proc *p)
864 e1dc7e45 2004-12-27 devnull {
865 4dbefdd4 2004-12-27 devnull lock(&_threadprocslock);
866 4dbefdd4 2004-12-27 devnull if(p->prev)
867 4dbefdd4 2004-12-27 devnull p->prev->next = p->next;
868 4dbefdd4 2004-12-27 devnull else
869 4dbefdd4 2004-12-27 devnull _threadprocs = p->next;
870 4dbefdd4 2004-12-27 devnull if(p->next)
871 4dbefdd4 2004-12-27 devnull p->next->prev = p->prev;
872 4dbefdd4 2004-12-27 devnull else
873 4dbefdd4 2004-12-27 devnull _threadprocstail = p->prev;
874 4dbefdd4 2004-12-27 devnull unlock(&_threadprocslock);
875 1544f909 2004-12-25 devnull }
876 15cd8255 2005-01-04 devnull
877 fa325e9b 2020-01-10 cross /*
878 15cd8255 2005-01-04 devnull * notify - for now just use the usual mechanisms
879 15cd8255 2005-01-04 devnull */
880 15cd8255 2005-01-04 devnull void
881 15cd8255 2005-01-04 devnull threadnotify(int (*f)(void*, char*), int in)
882 15cd8255 2005-01-04 devnull {
883 15cd8255 2005-01-04 devnull atnotify(f, in);
884 6dde87f8 2005-09-26 devnull }
885 6dde87f8 2005-09-26 devnull
886 6dde87f8 2005-09-26 devnull static int
887 6dde87f8 2005-09-26 devnull onrunqueue(Proc *p, _Thread *t)
888 6dde87f8 2005-09-26 devnull {
889 6dde87f8 2005-09-26 devnull _Thread *tt;
890 6dde87f8 2005-09-26 devnull
891 6dde87f8 2005-09-26 devnull for(tt=p->runqueue.head; tt; tt=tt->next)
892 6dde87f8 2005-09-26 devnull if(tt == t)
893 6dde87f8 2005-09-26 devnull return 1;
894 6dde87f8 2005-09-26 devnull return 0;
895 15cd8255 2005-01-04 devnull }
896 6dde87f8 2005-09-26 devnull
897 6dde87f8 2005-09-26 devnull /*
898 6dde87f8 2005-09-26 devnull * print state - called from SIGINFO
899 6dde87f8 2005-09-26 devnull */
900 6dde87f8 2005-09-26 devnull static int
901 6dde87f8 2005-09-26 devnull threadinfo(void *v, char *s)
902 6dde87f8 2005-09-26 devnull {
903 6dde87f8 2005-09-26 devnull Proc *p;
904 6dde87f8 2005-09-26 devnull _Thread *t;
905 6dde87f8 2005-09-26 devnull
906 6dde87f8 2005-09-26 devnull if(strcmp(s, "quit") != 0 && strcmp(s, "sys: status request") != 0)
907 6dde87f8 2005-09-26 devnull return 0;
908 6dde87f8 2005-09-26 devnull
909 6dde87f8 2005-09-26 devnull for(p=_threadprocs; p; p=p->next){
910 6dde87f8 2005-09-26 devnull fprint(2, "proc %p %s%s\n", (void*)p->osprocid, p->msg,
911 6dde87f8 2005-09-26 devnull p->sysproc ? " (sysproc)": "");
912 6dde87f8 2005-09-26 devnull for(t=p->allthreads.head; t; t=t->allnext){
913 fa325e9b 2020-01-10 cross fprint(2, "\tthread %d %s: %s %s\n",
914 fa325e9b 2020-01-10 cross t->id,
915 fa325e9b 2020-01-10 cross t == p->thread ? "Running" :
916 6dde87f8 2005-09-26 devnull onrunqueue(p, t) ? "Ready" : "Sleeping",
917 6dde87f8 2005-09-26 devnull t->state, t->name);
918 6dde87f8 2005-09-26 devnull }
919 6dde87f8 2005-09-26 devnull }
920 6dde87f8 2005-09-26 devnull return 1;
921 6dde87f8 2005-09-26 devnull }