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 7966faa9 2004-09-23 devnull * while holding p->lock; in procs other than p, the
11 7966faa9 2004-09-23 devnull * pointers are only guaranteed to be live while the lock
12 7966faa9 2004-09-23 devnull * 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
20 7966faa9 2004-09-23 devnull #include <u.h>
21 76193d7c 2003-09-30 devnull #include <assert.h>
22 7966faa9 2004-09-23 devnull #include <libc.h>
23 76193d7c 2003-09-30 devnull #include <thread.h>
24 76193d7c 2003-09-30 devnull #include "label.h"
25 76193d7c 2003-09-30 devnull
26 76193d7c 2003-09-30 devnull typedef struct Thread Thread;
27 7966faa9 2004-09-23 devnull typedef struct Proc Proc;
28 76193d7c 2003-09-30 devnull typedef struct Tqueue Tqueue;
29 76193d7c 2003-09-30 devnull typedef struct Pqueue Pqueue;
30 76193d7c 2003-09-30 devnull typedef struct Execargs Execargs;
31 76193d7c 2003-09-30 devnull
32 76193d7c 2003-09-30 devnull typedef enum
33 76193d7c 2003-09-30 devnull {
34 76193d7c 2003-09-30 devnull Dead,
35 76193d7c 2003-09-30 devnull Running,
36 76193d7c 2003-09-30 devnull Ready,
37 76193d7c 2003-09-30 devnull Rendezvous,
38 76193d7c 2003-09-30 devnull } State;
39 76193d7c 2003-09-30 devnull
40 76193d7c 2003-09-30 devnull typedef enum
41 76193d7c 2003-09-30 devnull {
42 76193d7c 2003-09-30 devnull Channone,
43 76193d7c 2003-09-30 devnull Chanalt,
44 76193d7c 2003-09-30 devnull Chansend,
45 76193d7c 2003-09-30 devnull Chanrecv,
46 76193d7c 2003-09-30 devnull } Chanstate;
47 76193d7c 2003-09-30 devnull
48 76193d7c 2003-09-30 devnull enum
49 76193d7c 2003-09-30 devnull {
50 76193d7c 2003-09-30 devnull NPRIV = 8,
51 76193d7c 2003-09-30 devnull };
52 76193d7c 2003-09-30 devnull
53 76193d7c 2003-09-30 devnull struct Tqueue /* Thread queue */
54 76193d7c 2003-09-30 devnull {
55 76193d7c 2003-09-30 devnull int asleep;
56 76193d7c 2003-09-30 devnull Thread *head;
57 76193d7c 2003-09-30 devnull Thread *tail;
58 76193d7c 2003-09-30 devnull };
59 76193d7c 2003-09-30 devnull
60 7966faa9 2004-09-23 devnull struct Pqueue { /* Proc queue */
61 7966faa9 2004-09-23 devnull Lock lock;
62 7966faa9 2004-09-23 devnull Proc *head;
63 7966faa9 2004-09-23 devnull Proc **tail;
64 7966faa9 2004-09-23 devnull };
65 7966faa9 2004-09-23 devnull
66 76193d7c 2003-09-30 devnull struct Thread
67 76193d7c 2003-09-30 devnull {
68 76193d7c 2003-09-30 devnull Lock lock; /* protects thread data structure */
69 7966faa9 2004-09-23 devnull
70 7966faa9 2004-09-23 devnull int asleep; /* thread is in _threadsleep */
71 7966faa9 2004-09-23 devnull Label context; /* for context switches */
72 76193d7c 2003-09-30 devnull int grp; /* thread group */
73 7966faa9 2004-09-23 devnull int id; /* thread id */
74 76193d7c 2003-09-30 devnull int moribund; /* thread needs to die */
75 7966faa9 2004-09-23 devnull char *name; /* name of thread */
76 76193d7c 2003-09-30 devnull Thread *next; /* next on ready queue */
77 76193d7c 2003-09-30 devnull Thread *nextt; /* next on list of threads in this proc */
78 7966faa9 2004-09-23 devnull State nextstate; /* next run state */
79 7966faa9 2004-09-23 devnull Proc *proc; /* proc of this thread */
80 76193d7c 2003-09-30 devnull Thread *prevt; /* prev on list of threads in this proc */
81 76193d7c 2003-09-30 devnull int ret; /* return value for Exec, Fork */
82 7966faa9 2004-09-23 devnull State state; /* run state */
83 7966faa9 2004-09-23 devnull uchar *stk; /* top of stack (lowest address of stack) */
84 7966faa9 2004-09-23 devnull uint stksize; /* stack size */
85 7966faa9 2004-09-23 devnull void* udata[NPRIV]; /* User per-thread data pointer */
86 76193d7c 2003-09-30 devnull
87 7966faa9 2004-09-23 devnull /*
88 7966faa9 2004-09-23 devnull * for debugging only
89 7966faa9 2004-09-23 devnull * (could go away without impacting correct behavior):
90 7966faa9 2004-09-23 devnull */
91 76193d7c 2003-09-30 devnull
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 76193d7c 2003-09-30 devnull
100 76193d7c 2003-09-30 devnull };
101 76193d7c 2003-09-30 devnull
102 76193d7c 2003-09-30 devnull struct Execargs
103 76193d7c 2003-09-30 devnull {
104 76193d7c 2003-09-30 devnull char *prog;
105 76193d7c 2003-09-30 devnull char **args;
106 76193d7c 2003-09-30 devnull int fd[2];
107 32f69c36 2003-12-11 devnull int *stdfd;
108 76193d7c 2003-09-30 devnull };
109 76193d7c 2003-09-30 devnull
110 76193d7c 2003-09-30 devnull struct Proc
111 76193d7c 2003-09-30 devnull {
112 76193d7c 2003-09-30 devnull Lock lock;
113 7966faa9 2004-09-23 devnull
114 7966faa9 2004-09-23 devnull Label context; /* for context switches */
115 7966faa9 2004-09-23 devnull Proc *link; /* in ptab */
116 76193d7c 2003-09-30 devnull int splhi; /* delay notes */
117 76193d7c 2003-09-30 devnull Thread *thread; /* running thread */
118 e97ceade 2003-12-06 devnull Thread *idle; /* idle thread */
119 7966faa9 2004-09-23 devnull int id;
120 76193d7c 2003-09-30 devnull
121 76193d7c 2003-09-30 devnull int needexec;
122 76193d7c 2003-09-30 devnull Execargs exec; /* exec argument */
123 76193d7c 2003-09-30 devnull Proc *newproc; /* fork argument */
124 76193d7c 2003-09-30 devnull char exitstr[ERRMAX]; /* exit status */
125 76193d7c 2003-09-30 devnull
126 76193d7c 2003-09-30 devnull int rforkflag;
127 76193d7c 2003-09-30 devnull int nthreads;
128 76193d7c 2003-09-30 devnull Tqueue threads; /* All threads of this proc */
129 76193d7c 2003-09-30 devnull Tqueue ready; /* Runnable threads */
130 76193d7c 2003-09-30 devnull Lock readylock;
131 76193d7c 2003-09-30 devnull
132 76193d7c 2003-09-30 devnull int blocked; /* In a rendezvous */
133 76193d7c 2003-09-30 devnull int pending; /* delayed note pending */
134 76193d7c 2003-09-30 devnull int nonotes; /* delay notes */
135 76193d7c 2003-09-30 devnull uint nextID; /* ID of most recently created thread */
136 76193d7c 2003-09-30 devnull Proc *next; /* linked list of Procs */
137 76193d7c 2003-09-30 devnull
138 7966faa9 2004-09-23 devnull
139 7966faa9 2004-09-23 devnull void (*schedfn)(Proc*); /* function to call in scheduler */
140 7966faa9 2004-09-23 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 7966faa9 2004-09-23 devnull /*
152 7966faa9 2004-09-23 devnull * for debugging only
153 7966faa9 2004-09-23 devnull */
154 7966faa9 2004-09-23 devnull int pid; /* process id */
155 7966faa9 2004-09-23 devnull int pthreadid; /* pthread id */
156 76193d7c 2003-09-30 devnull };
157 76193d7c 2003-09-30 devnull
158 c6687d45 2004-09-21 devnull void _swaplabel(Label*, Label*);
159 7966faa9 2004-09-23 devnull Proc* _newproc(void);
160 7966faa9 2004-09-23 devnull int _newthread(Proc*, void(*)(void*), void*, uint, char*, int);
161 76193d7c 2003-09-30 devnull int _procsplhi(void);
162 76193d7c 2003-09-30 devnull void _procsplx(int);
163 c4097c29 2004-05-11 devnull int _sched(void);
164 76193d7c 2003-09-30 devnull int _schedexec(Execargs*);
165 76193d7c 2003-09-30 devnull void _schedexecwait(void);
166 76193d7c 2003-09-30 devnull void _schedexit(Proc*);
167 76193d7c 2003-09-30 devnull int _schedfork(Proc*);
168 7966faa9 2004-09-23 devnull void _threadfree(Thread*);
169 7966faa9 2004-09-23 devnull void _threadscheduler(void*);
170 76193d7c 2003-09-30 devnull void _systhreadinit(void);
171 76193d7c 2003-09-30 devnull void _threadassert(char*);
172 76193d7c 2003-09-30 devnull void __threaddebug(ulong, char*, ...);
173 76193d7c 2003-09-30 devnull #define _threaddebug if(!_threaddebuglevel){}else __threaddebug
174 76193d7c 2003-09-30 devnull void _threadexitsall(char*);
175 76193d7c 2003-09-30 devnull Proc* _threadgetproc(void);
176 5a8e63b2 2004-02-29 devnull extern void _threadmultiproc(void);
177 76193d7c 2003-09-30 devnull Proc* _threaddelproc(void);
178 7966faa9 2004-09-23 devnull void _threadinitproc(Proc*);
179 7966faa9 2004-09-23 devnull void _threadwaitkids(Proc*);
180 76193d7c 2003-09-30 devnull void _threadsetproc(Proc*);
181 76193d7c 2003-09-30 devnull void _threadinitstack(Thread*, void(*)(void*), void*);
182 7966faa9 2004-09-23 devnull void _threadlinkmain(void);
183 76193d7c 2003-09-30 devnull void* _threadmalloc(long, int);
184 76193d7c 2003-09-30 devnull void _threadnote(void*, char*);
185 76193d7c 2003-09-30 devnull void _threadready(Thread*);
186 7966faa9 2004-09-23 devnull void _threadsetidle(int);
187 06bb4ed2 2004-09-17 devnull void _threadsleep(_Procrend*);
188 06bb4ed2 2004-09-17 devnull void _threadwakeup(_Procrend*);
189 76193d7c 2003-09-30 devnull void _threadsignal(void);
190 76193d7c 2003-09-30 devnull void _threadsysfatal(char*, va_list);
191 76193d7c 2003-09-30 devnull long _xdec(long*);
192 76193d7c 2003-09-30 devnull void _xinc(long*);
193 76193d7c 2003-09-30 devnull void _threadremove(Proc*, Thread*);
194 d49a2e48 2004-03-09 devnull void threadstatus(void);
195 7966faa9 2004-09-23 devnull void _threadstartproc(Proc*);
196 7966faa9 2004-09-23 devnull void _threadexitproc(char*);
197 7966faa9 2004-09-23 devnull void _threadexitallproc(char*);
198 76193d7c 2003-09-30 devnull
199 7966faa9 2004-09-23 devnull extern int _threadnprocs;
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
205 76193d7c 2003-09-30 devnull #define DBGAPPL (1 << 0)
206 76193d7c 2003-09-30 devnull #define DBGSCHED (1 << 16)
207 76193d7c 2003-09-30 devnull #define DBGCHAN (1 << 17)
208 76193d7c 2003-09-30 devnull #define DBGREND (1 << 18)
209 76193d7c 2003-09-30 devnull /* #define DBGKILL (1 << 19) */
210 76193d7c 2003-09-30 devnull #define DBGNOTE (1 << 20)
211 76193d7c 2003-09-30 devnull #define DBGEXEC (1 << 21)
212 76193d7c 2003-09-30 devnull
213 76193d7c 2003-09-30 devnull extern void _threadmemset(void*, int, int);
214 76193d7c 2003-09-30 devnull extern void _threaddebugmemset(void*, int, int);
215 32f69c36 2003-12-11 devnull extern int _threadprocs;
216 c4097c29 2004-05-11 devnull extern void _threadstacklimit(void*, void*);