Blame


1 76193d7c 2003-09-30 devnull /*
2 76193d7c 2003-09-30 devnull * Some notes on locking:
3 76193d7c 2003-09-30 devnull *
4 76193d7c 2003-09-30 devnull * All the locking woes come from implementing
5 76193d7c 2003-09-30 devnull * threadinterrupt (and threadkill).
6 76193d7c 2003-09-30 devnull *
7 76193d7c 2003-09-30 devnull * _threadgetproc()->thread is always a live pointer.
8 76193d7c 2003-09-30 devnull * p->threads, p->ready, and _threadrgrp also contain
9 76193d7c 2003-09-30 devnull * live thread pointers. These may only be consulted
10 76193d7c 2003-09-30 devnull * while holding p->lock or _threadrgrp.lock; in procs
11 76193d7c 2003-09-30 devnull * other than p, the pointers are only guaranteed to be live
12 76193d7c 2003-09-30 devnull * while the lock is still being held.
13 76193d7c 2003-09-30 devnull *
14 76193d7c 2003-09-30 devnull * Thread structures can only be freed by the proc
15 76193d7c 2003-09-30 devnull * they belong to. Threads marked with t->inrendez
16 76193d7c 2003-09-30 devnull * need to be extracted from the _threadrgrp before
17 76193d7c 2003-09-30 devnull * being freed.
18 76193d7c 2003-09-30 devnull *
19 76193d7c 2003-09-30 devnull * _threadrgrp.lock cannot be acquired while holding p->lock.
20 76193d7c 2003-09-30 devnull */
21 76193d7c 2003-09-30 devnull
22 76193d7c 2003-09-30 devnull #include <assert.h>
23 76193d7c 2003-09-30 devnull #include <lib9.h>
24 76193d7c 2003-09-30 devnull #include <thread.h>
25 76193d7c 2003-09-30 devnull #include "label.h"
26 76193d7c 2003-09-30 devnull
27 76193d7c 2003-09-30 devnull typedef struct Thread Thread;
28 76193d7c 2003-09-30 devnull typedef struct Proc Proc;
29 76193d7c 2003-09-30 devnull typedef struct Tqueue Tqueue;
30 76193d7c 2003-09-30 devnull typedef struct Pqueue Pqueue;
31 76193d7c 2003-09-30 devnull typedef struct Rgrp Rgrp;
32 76193d7c 2003-09-30 devnull typedef struct Execargs Execargs;
33 76193d7c 2003-09-30 devnull
34 76193d7c 2003-09-30 devnull /* must match list in sched.c */
35 76193d7c 2003-09-30 devnull typedef enum
36 76193d7c 2003-09-30 devnull {
37 76193d7c 2003-09-30 devnull Dead,
38 76193d7c 2003-09-30 devnull Running,
39 76193d7c 2003-09-30 devnull Ready,
40 76193d7c 2003-09-30 devnull Rendezvous,
41 76193d7c 2003-09-30 devnull } State;
42 76193d7c 2003-09-30 devnull
43 76193d7c 2003-09-30 devnull typedef enum
44 76193d7c 2003-09-30 devnull {
45 76193d7c 2003-09-30 devnull Channone,
46 76193d7c 2003-09-30 devnull Chanalt,
47 76193d7c 2003-09-30 devnull Chansend,
48 76193d7c 2003-09-30 devnull Chanrecv,
49 76193d7c 2003-09-30 devnull } Chanstate;
50 76193d7c 2003-09-30 devnull
51 76193d7c 2003-09-30 devnull enum
52 76193d7c 2003-09-30 devnull {
53 76193d7c 2003-09-30 devnull RENDHASH = 10009,
54 76193d7c 2003-09-30 devnull Printsize = 2048,
55 76193d7c 2003-09-30 devnull NPRIV = 8,
56 76193d7c 2003-09-30 devnull };
57 76193d7c 2003-09-30 devnull
58 76193d7c 2003-09-30 devnull struct Rgrp
59 76193d7c 2003-09-30 devnull {
60 76193d7c 2003-09-30 devnull Lock lock;
61 76193d7c 2003-09-30 devnull Thread *hash[RENDHASH];
62 76193d7c 2003-09-30 devnull };
63 76193d7c 2003-09-30 devnull
64 76193d7c 2003-09-30 devnull struct Tqueue /* Thread queue */
65 76193d7c 2003-09-30 devnull {
66 76193d7c 2003-09-30 devnull int asleep;
67 76193d7c 2003-09-30 devnull Thread *head;
68 76193d7c 2003-09-30 devnull Thread *tail;
69 76193d7c 2003-09-30 devnull };
70 76193d7c 2003-09-30 devnull
71 76193d7c 2003-09-30 devnull struct Thread
72 76193d7c 2003-09-30 devnull {
73 76193d7c 2003-09-30 devnull Lock lock; /* protects thread data structure */
74 76193d7c 2003-09-30 devnull Label sched; /* for context switches */
75 76193d7c 2003-09-30 devnull int id; /* thread id */
76 76193d7c 2003-09-30 devnull int grp; /* thread group */
77 76193d7c 2003-09-30 devnull int moribund; /* thread needs to die */
78 76193d7c 2003-09-30 devnull State state; /* run state */
79 76193d7c 2003-09-30 devnull State nextstate; /* next run state */
80 76193d7c 2003-09-30 devnull uchar *stk; /* top of stack (lowest address of stack) */
81 76193d7c 2003-09-30 devnull uint stksize; /* stack size */
82 76193d7c 2003-09-30 devnull Thread *next; /* next on ready queue */
83 76193d7c 2003-09-30 devnull
84 76193d7c 2003-09-30 devnull Proc *proc; /* proc of this thread */
85 76193d7c 2003-09-30 devnull Thread *nextt; /* next on list of threads in this proc */
86 76193d7c 2003-09-30 devnull Thread *prevt; /* prev on list of threads in this proc */
87 76193d7c 2003-09-30 devnull int ret; /* return value for Exec, Fork */
88 76193d7c 2003-09-30 devnull
89 76193d7c 2003-09-30 devnull char *cmdname; /* ptr to name of thread */
90 76193d7c 2003-09-30 devnull
91 06bb4ed2 2004-09-17 devnull int inrendez;
92 06bb4ed2 2004-09-17 devnull Channel *altc;
93 06bb4ed2 2004-09-17 devnull _Procrend altrend;
94 76193d7c 2003-09-30 devnull
95 76193d7c 2003-09-30 devnull Chanstate chan; /* which channel operation is current */
96 76193d7c 2003-09-30 devnull Alt *alt; /* pointer to current alt structure (debugging) */
97 02a1a5c1 2004-03-05 devnull ulong userpc;
98 bcf527a9 2004-09-17 devnull Channel *c;
99 bcf527a9 2004-09-17 devnull pthread_cond_t cond;
100 76193d7c 2003-09-30 devnull
101 76193d7c 2003-09-30 devnull void* udata[NPRIV]; /* User per-thread data pointer */
102 c4097c29 2004-05-11 devnull int lastfd;
103 76193d7c 2003-09-30 devnull };
104 76193d7c 2003-09-30 devnull
105 76193d7c 2003-09-30 devnull struct Execargs
106 76193d7c 2003-09-30 devnull {
107 76193d7c 2003-09-30 devnull char *prog;
108 76193d7c 2003-09-30 devnull char **args;
109 76193d7c 2003-09-30 devnull int fd[2];
110 32f69c36 2003-12-11 devnull int *stdfd;
111 76193d7c 2003-09-30 devnull };
112 76193d7c 2003-09-30 devnull
113 76193d7c 2003-09-30 devnull struct Proc
114 76193d7c 2003-09-30 devnull {
115 76193d7c 2003-09-30 devnull Lock lock;
116 76193d7c 2003-09-30 devnull Label sched; /* for context switches */
117 76193d7c 2003-09-30 devnull Proc *link; /* in proctab */
118 76193d7c 2003-09-30 devnull int pid; /* process id */
119 76193d7c 2003-09-30 devnull int splhi; /* delay notes */
120 76193d7c 2003-09-30 devnull Thread *thread; /* running thread */
121 e97ceade 2003-12-06 devnull Thread *idle; /* idle thread */
122 76193d7c 2003-09-30 devnull
123 76193d7c 2003-09-30 devnull int needexec;
124 76193d7c 2003-09-30 devnull Execargs exec; /* exec argument */
125 76193d7c 2003-09-30 devnull Proc *newproc; /* fork argument */
126 76193d7c 2003-09-30 devnull char exitstr[ERRMAX]; /* exit status */
127 76193d7c 2003-09-30 devnull
128 76193d7c 2003-09-30 devnull int rforkflag;
129 76193d7c 2003-09-30 devnull int nthreads;
130 76193d7c 2003-09-30 devnull Tqueue threads; /* All threads of this proc */
131 76193d7c 2003-09-30 devnull Tqueue ready; /* Runnable threads */
132 76193d7c 2003-09-30 devnull Lock readylock;
133 76193d7c 2003-09-30 devnull
134 76193d7c 2003-09-30 devnull char printbuf[Printsize];
135 76193d7c 2003-09-30 devnull int blocked; /* In a rendezvous */
136 76193d7c 2003-09-30 devnull int pending; /* delayed note pending */
137 76193d7c 2003-09-30 devnull int nonotes; /* delay notes */
138 76193d7c 2003-09-30 devnull uint nextID; /* ID of most recently created thread */
139 76193d7c 2003-09-30 devnull Proc *next; /* linked list of Procs */
140 76193d7c 2003-09-30 devnull
141 bcf527a9 2004-09-17 devnull _Procrend rend; /* sleep here for more ready threads */
142 bcf527a9 2004-09-17 devnull
143 76193d7c 2003-09-30 devnull void *arg; /* passed between shared and unshared stk */
144 76193d7c 2003-09-30 devnull char str[ERRMAX]; /* used by threadexits to avoid malloc */
145 76193d7c 2003-09-30 devnull char errbuf[ERRMAX]; /* errstr */
146 5a8e63b2 2004-02-29 devnull Waitmsg *waitmsg;
147 76193d7c 2003-09-30 devnull
148 76193d7c 2003-09-30 devnull void* udata; /* User per-proc data pointer */
149 c4097c29 2004-05-11 devnull int nsched;
150 76193d7c 2003-09-30 devnull };
151 76193d7c 2003-09-30 devnull
152 76193d7c 2003-09-30 devnull struct Pqueue { /* Proc queue */
153 76193d7c 2003-09-30 devnull Lock lock;
154 76193d7c 2003-09-30 devnull Proc *head;
155 76193d7c 2003-09-30 devnull Proc **tail;
156 76193d7c 2003-09-30 devnull };
157 76193d7c 2003-09-30 devnull
158 76193d7c 2003-09-30 devnull struct Ioproc
159 76193d7c 2003-09-30 devnull {
160 76193d7c 2003-09-30 devnull int tid;
161 76193d7c 2003-09-30 devnull Channel *c, *creply;
162 76193d7c 2003-09-30 devnull int inuse;
163 76193d7c 2003-09-30 devnull long (*op)(va_list*);
164 76193d7c 2003-09-30 devnull va_list arg;
165 76193d7c 2003-09-30 devnull long ret;
166 76193d7c 2003-09-30 devnull char err[ERRMAX];
167 76193d7c 2003-09-30 devnull Ioproc *next;
168 76193d7c 2003-09-30 devnull };
169 76193d7c 2003-09-30 devnull
170 c6687d45 2004-09-21 devnull void _swaplabel(Label*, Label*);
171 76193d7c 2003-09-30 devnull void _freeproc(Proc*);
172 76193d7c 2003-09-30 devnull Proc* _newproc(void(*)(void*), void*, uint, char*, int, int);
173 76193d7c 2003-09-30 devnull int _procsplhi(void);
174 76193d7c 2003-09-30 devnull void _procsplx(int);
175 c4097c29 2004-05-11 devnull int _sched(void);
176 76193d7c 2003-09-30 devnull int _schedexec(Execargs*);
177 76193d7c 2003-09-30 devnull void _schedexecwait(void);
178 76193d7c 2003-09-30 devnull void _schedexit(Proc*);
179 76193d7c 2003-09-30 devnull int _schedfork(Proc*);
180 c6687d45 2004-09-21 devnull void _scheduler(void*);
181 76193d7c 2003-09-30 devnull void _systhreadinit(void);
182 76193d7c 2003-09-30 devnull void _threadassert(char*);
183 76193d7c 2003-09-30 devnull void __threaddebug(ulong, char*, ...);
184 76193d7c 2003-09-30 devnull #define _threaddebug if(!_threaddebuglevel){}else __threaddebug
185 76193d7c 2003-09-30 devnull void _threadexitsall(char*);
186 76193d7c 2003-09-30 devnull Proc* _threadgetproc(void);
187 5a8e63b2 2004-02-29 devnull extern void _threadmultiproc(void);
188 76193d7c 2003-09-30 devnull Proc* _threaddelproc(void);
189 76193d7c 2003-09-30 devnull void _threadsetproc(Proc*);
190 76193d7c 2003-09-30 devnull void _threadinitstack(Thread*, void(*)(void*), void*);
191 76193d7c 2003-09-30 devnull void* _threadmalloc(long, int);
192 76193d7c 2003-09-30 devnull void _threadnote(void*, char*);
193 76193d7c 2003-09-30 devnull void _threadready(Thread*);
194 e97ceade 2003-12-06 devnull void _threadidle(void);
195 06bb4ed2 2004-09-17 devnull void _threadsleep(_Procrend*);
196 06bb4ed2 2004-09-17 devnull void _threadwakeup(_Procrend*);
197 76193d7c 2003-09-30 devnull void _threadsignal(void);
198 76193d7c 2003-09-30 devnull void _threadsysfatal(char*, va_list);
199 76193d7c 2003-09-30 devnull long _xdec(long*);
200 76193d7c 2003-09-30 devnull void _xinc(long*);
201 76193d7c 2003-09-30 devnull void _threadremove(Proc*, Thread*);
202 d49a2e48 2004-03-09 devnull void threadstatus(void);
203 76193d7c 2003-09-30 devnull
204 76193d7c 2003-09-30 devnull extern int _threaddebuglevel;
205 76193d7c 2003-09-30 devnull extern char* _threadexitsallstatus;
206 76193d7c 2003-09-30 devnull extern Pqueue _threadpq;
207 76193d7c 2003-09-30 devnull extern Channel* _threadwaitchan;
208 76193d7c 2003-09-30 devnull extern Rgrp _threadrgrp;
209 76193d7c 2003-09-30 devnull extern void _stackfree(void*);
210 76193d7c 2003-09-30 devnull
211 76193d7c 2003-09-30 devnull #define DBGAPPL (1 << 0)
212 76193d7c 2003-09-30 devnull #define DBGSCHED (1 << 16)
213 76193d7c 2003-09-30 devnull #define DBGCHAN (1 << 17)
214 76193d7c 2003-09-30 devnull #define DBGREND (1 << 18)
215 76193d7c 2003-09-30 devnull /* #define DBGKILL (1 << 19) */
216 76193d7c 2003-09-30 devnull #define DBGNOTE (1 << 20)
217 76193d7c 2003-09-30 devnull #define DBGEXEC (1 << 21)
218 76193d7c 2003-09-30 devnull
219 76193d7c 2003-09-30 devnull #define ioproc_arg(io, type) (va_arg((io)->arg, type))
220 76193d7c 2003-09-30 devnull extern int _threadgetpid(void);
221 76193d7c 2003-09-30 devnull extern void _threadmemset(void*, int, int);
222 76193d7c 2003-09-30 devnull extern void _threaddebugmemset(void*, int, int);
223 32f69c36 2003-12-11 devnull extern int _threadprocs;
224 c4097c29 2004-05-11 devnull extern void _threadstacklimit(void*, void*);