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 enum{
28 76193d7c 2003-09-30 devnull STKSIZE = 16384,
29 76193d7c 2003-09-30 devnull STKMAGIC = 0xCAFEBEEF
30 76193d7c 2003-09-30 devnull };
31 76193d7c 2003-09-30 devnull
32 76193d7c 2003-09-30 devnull typedef struct Thread Thread;
33 76193d7c 2003-09-30 devnull typedef struct Proc Proc;
34 76193d7c 2003-09-30 devnull typedef struct Tqueue Tqueue;
35 76193d7c 2003-09-30 devnull typedef struct Pqueue Pqueue;
36 76193d7c 2003-09-30 devnull typedef struct Rgrp Rgrp;
37 76193d7c 2003-09-30 devnull typedef struct Execargs Execargs;
38 76193d7c 2003-09-30 devnull
39 76193d7c 2003-09-30 devnull /* must match list in sched.c */
40 76193d7c 2003-09-30 devnull typedef enum
41 76193d7c 2003-09-30 devnull {
42 76193d7c 2003-09-30 devnull Dead,
43 76193d7c 2003-09-30 devnull Running,
44 76193d7c 2003-09-30 devnull Ready,
45 76193d7c 2003-09-30 devnull Rendezvous,
46 76193d7c 2003-09-30 devnull } State;
47 76193d7c 2003-09-30 devnull
48 76193d7c 2003-09-30 devnull typedef enum
49 76193d7c 2003-09-30 devnull {
50 76193d7c 2003-09-30 devnull Channone,
51 76193d7c 2003-09-30 devnull Chanalt,
52 76193d7c 2003-09-30 devnull Chansend,
53 76193d7c 2003-09-30 devnull Chanrecv,
54 76193d7c 2003-09-30 devnull } Chanstate;
55 76193d7c 2003-09-30 devnull
56 76193d7c 2003-09-30 devnull enum
57 76193d7c 2003-09-30 devnull {
58 76193d7c 2003-09-30 devnull RENDHASH = 10009,
59 76193d7c 2003-09-30 devnull Printsize = 2048,
60 76193d7c 2003-09-30 devnull NPRIV = 8,
61 76193d7c 2003-09-30 devnull };
62 76193d7c 2003-09-30 devnull
63 76193d7c 2003-09-30 devnull struct Rgrp
64 76193d7c 2003-09-30 devnull {
65 76193d7c 2003-09-30 devnull Lock lock;
66 76193d7c 2003-09-30 devnull Thread *hash[RENDHASH];
67 76193d7c 2003-09-30 devnull };
68 76193d7c 2003-09-30 devnull
69 76193d7c 2003-09-30 devnull struct Tqueue /* Thread queue */
70 76193d7c 2003-09-30 devnull {
71 76193d7c 2003-09-30 devnull int asleep;
72 76193d7c 2003-09-30 devnull Thread *head;
73 76193d7c 2003-09-30 devnull Thread *tail;
74 76193d7c 2003-09-30 devnull };
75 76193d7c 2003-09-30 devnull
76 76193d7c 2003-09-30 devnull struct Thread
77 76193d7c 2003-09-30 devnull {
78 76193d7c 2003-09-30 devnull Lock lock; /* protects thread data structure */
79 76193d7c 2003-09-30 devnull Label sched; /* for context switches */
80 76193d7c 2003-09-30 devnull int id; /* thread id */
81 76193d7c 2003-09-30 devnull int grp; /* thread group */
82 76193d7c 2003-09-30 devnull int moribund; /* thread needs to die */
83 76193d7c 2003-09-30 devnull State state; /* run state */
84 76193d7c 2003-09-30 devnull State nextstate; /* next run state */
85 76193d7c 2003-09-30 devnull uchar *stk; /* top of stack (lowest address of stack) */
86 76193d7c 2003-09-30 devnull uint stksize; /* stack size */
87 76193d7c 2003-09-30 devnull Thread *next; /* next on ready queue */
88 76193d7c 2003-09-30 devnull
89 76193d7c 2003-09-30 devnull Proc *proc; /* proc of this thread */
90 76193d7c 2003-09-30 devnull Thread *nextt; /* next on list of threads in this proc */
91 76193d7c 2003-09-30 devnull Thread *prevt; /* prev on list of threads in this proc */
92 76193d7c 2003-09-30 devnull int ret; /* return value for Exec, Fork */
93 76193d7c 2003-09-30 devnull
94 76193d7c 2003-09-30 devnull char *cmdname; /* ptr to name of thread */
95 76193d7c 2003-09-30 devnull
96 76193d7c 2003-09-30 devnull int inrendez;
97 76193d7c 2003-09-30 devnull Thread *rendhash; /* Trgrp linked list */
98 76193d7c 2003-09-30 devnull ulong rendtag; /* rendezvous tag */
99 76193d7c 2003-09-30 devnull ulong rendval; /* rendezvous value */
100 76193d7c 2003-09-30 devnull int rendbreak; /* rendezvous has been taken */
101 76193d7c 2003-09-30 devnull
102 76193d7c 2003-09-30 devnull Chanstate chan; /* which channel operation is current */
103 76193d7c 2003-09-30 devnull Alt *alt; /* pointer to current alt structure (debugging) */
104 76193d7c 2003-09-30 devnull
105 76193d7c 2003-09-30 devnull void* udata[NPRIV]; /* User per-thread data pointer */
106 76193d7c 2003-09-30 devnull };
107 76193d7c 2003-09-30 devnull
108 76193d7c 2003-09-30 devnull struct Execargs
109 76193d7c 2003-09-30 devnull {
110 76193d7c 2003-09-30 devnull char *prog;
111 76193d7c 2003-09-30 devnull char **args;
112 76193d7c 2003-09-30 devnull int fd[2];
113 76193d7c 2003-09-30 devnull };
114 76193d7c 2003-09-30 devnull
115 76193d7c 2003-09-30 devnull struct Proc
116 76193d7c 2003-09-30 devnull {
117 76193d7c 2003-09-30 devnull Lock lock;
118 76193d7c 2003-09-30 devnull Label sched; /* for context switches */
119 76193d7c 2003-09-30 devnull Proc *link; /* in proctab */
120 76193d7c 2003-09-30 devnull int pid; /* process id */
121 76193d7c 2003-09-30 devnull int splhi; /* delay notes */
122 76193d7c 2003-09-30 devnull Thread *thread; /* running thread */
123 76193d7c 2003-09-30 devnull
124 76193d7c 2003-09-30 devnull int needexec;
125 76193d7c 2003-09-30 devnull Execargs exec; /* exec argument */
126 76193d7c 2003-09-30 devnull Proc *newproc; /* fork argument */
127 76193d7c 2003-09-30 devnull char exitstr[ERRMAX]; /* exit status */
128 76193d7c 2003-09-30 devnull
129 76193d7c 2003-09-30 devnull int rforkflag;
130 76193d7c 2003-09-30 devnull int nthreads;
131 76193d7c 2003-09-30 devnull Tqueue threads; /* All threads of this proc */
132 76193d7c 2003-09-30 devnull Tqueue ready; /* Runnable threads */
133 76193d7c 2003-09-30 devnull Lock readylock;
134 76193d7c 2003-09-30 devnull
135 76193d7c 2003-09-30 devnull char printbuf[Printsize];
136 76193d7c 2003-09-30 devnull int blocked; /* In a rendezvous */
137 76193d7c 2003-09-30 devnull int pending; /* delayed note pending */
138 76193d7c 2003-09-30 devnull int nonotes; /* delay notes */
139 76193d7c 2003-09-30 devnull uint nextID; /* ID of most recently created thread */
140 76193d7c 2003-09-30 devnull Proc *next; /* linked list of Procs */
141 76193d7c 2003-09-30 devnull
142 76193d7c 2003-09-30 devnull void *arg; /* passed between shared and unshared stk */
143 76193d7c 2003-09-30 devnull char str[ERRMAX]; /* used by threadexits to avoid malloc */
144 76193d7c 2003-09-30 devnull char errbuf[ERRMAX]; /* errstr */
145 76193d7c 2003-09-30 devnull
146 76193d7c 2003-09-30 devnull void* udata; /* User per-proc data pointer */
147 76193d7c 2003-09-30 devnull };
148 76193d7c 2003-09-30 devnull
149 76193d7c 2003-09-30 devnull struct Pqueue { /* Proc queue */
150 76193d7c 2003-09-30 devnull Lock lock;
151 76193d7c 2003-09-30 devnull Proc *head;
152 76193d7c 2003-09-30 devnull Proc **tail;
153 76193d7c 2003-09-30 devnull };
154 76193d7c 2003-09-30 devnull
155 76193d7c 2003-09-30 devnull struct Ioproc
156 76193d7c 2003-09-30 devnull {
157 76193d7c 2003-09-30 devnull int tid;
158 76193d7c 2003-09-30 devnull Channel *c, *creply;
159 76193d7c 2003-09-30 devnull int inuse;
160 76193d7c 2003-09-30 devnull long (*op)(va_list*);
161 76193d7c 2003-09-30 devnull va_list arg;
162 76193d7c 2003-09-30 devnull long ret;
163 76193d7c 2003-09-30 devnull char err[ERRMAX];
164 76193d7c 2003-09-30 devnull Ioproc *next;
165 76193d7c 2003-09-30 devnull };
166 76193d7c 2003-09-30 devnull
167 76193d7c 2003-09-30 devnull void _gotolabel(Label*);
168 76193d7c 2003-09-30 devnull int _setlabel(Label*);
169 76193d7c 2003-09-30 devnull void _freeproc(Proc*);
170 76193d7c 2003-09-30 devnull Proc* _newproc(void(*)(void*), void*, uint, char*, int, int);
171 76193d7c 2003-09-30 devnull int _procsplhi(void);
172 76193d7c 2003-09-30 devnull void _procsplx(int);
173 76193d7c 2003-09-30 devnull void _sched(void);
174 76193d7c 2003-09-30 devnull int _schedexec(Execargs*);
175 76193d7c 2003-09-30 devnull void _schedexecwait(void);
176 76193d7c 2003-09-30 devnull void _schedexit(Proc*);
177 76193d7c 2003-09-30 devnull int _schedfork(Proc*);
178 76193d7c 2003-09-30 devnull void _schedinit(void*);
179 76193d7c 2003-09-30 devnull void _systhreadinit(void);
180 76193d7c 2003-09-30 devnull void _threadassert(char*);
181 76193d7c 2003-09-30 devnull void _threadbreakrendez(void);
182 76193d7c 2003-09-30 devnull void __threaddebug(ulong, char*, ...);
183 76193d7c 2003-09-30 devnull #define _threaddebug if(!_threaddebuglevel){}else __threaddebug
184 76193d7c 2003-09-30 devnull void _threadexitsall(char*);
185 76193d7c 2003-09-30 devnull void _threadflagrendez(Thread*);
186 76193d7c 2003-09-30 devnull Proc* _threadgetproc(void);
187 76193d7c 2003-09-30 devnull Proc* _threaddelproc(void);
188 76193d7c 2003-09-30 devnull void _threadsetproc(Proc*);
189 76193d7c 2003-09-30 devnull void _threadinitstack(Thread*, void(*)(void*), void*);
190 76193d7c 2003-09-30 devnull void* _threadmalloc(long, int);
191 76193d7c 2003-09-30 devnull void _threadnote(void*, char*);
192 76193d7c 2003-09-30 devnull void _threadready(Thread*);
193 76193d7c 2003-09-30 devnull ulong _threadrendezvous(ulong, ulong);
194 76193d7c 2003-09-30 devnull void _threadsignal(void);
195 76193d7c 2003-09-30 devnull void _threadsysfatal(char*, va_list);
196 76193d7c 2003-09-30 devnull long _xdec(long*);
197 76193d7c 2003-09-30 devnull void _xinc(long*);
198 76193d7c 2003-09-30 devnull void _threadremove(Proc*, Thread*);
199 76193d7c 2003-09-30 devnull
200 76193d7c 2003-09-30 devnull extern int _threaddebuglevel;
201 76193d7c 2003-09-30 devnull extern char* _threadexitsallstatus;
202 76193d7c 2003-09-30 devnull extern Pqueue _threadpq;
203 76193d7c 2003-09-30 devnull extern Channel* _threadwaitchan;
204 76193d7c 2003-09-30 devnull extern Rgrp _threadrgrp;
205 76193d7c 2003-09-30 devnull extern void _stackfree(void*);
206 76193d7c 2003-09-30 devnull
207 76193d7c 2003-09-30 devnull #define DBGAPPL (1 << 0)
208 76193d7c 2003-09-30 devnull #define DBGSCHED (1 << 16)
209 76193d7c 2003-09-30 devnull #define DBGCHAN (1 << 17)
210 76193d7c 2003-09-30 devnull #define DBGREND (1 << 18)
211 76193d7c 2003-09-30 devnull /* #define DBGKILL (1 << 19) */
212 76193d7c 2003-09-30 devnull #define DBGNOTE (1 << 20)
213 76193d7c 2003-09-30 devnull #define DBGEXEC (1 << 21)
214 76193d7c 2003-09-30 devnull
215 76193d7c 2003-09-30 devnull #define ioproc_arg(io, type) (va_arg((io)->arg, type))
216 76193d7c 2003-09-30 devnull extern int _threadgetpid(void);
217 76193d7c 2003-09-30 devnull extern void _threadmemset(void*, int, int);
218 76193d7c 2003-09-30 devnull extern void _threaddebugmemset(void*, int, int);
219 76193d7c 2003-09-30 devnull