2 * Some notes on locking:
4 * All the locking woes come from implementing
5 * threadinterrupt (and threadkill).
7 * _threadgetproc()->thread is always a live pointer.
8 * p->threads, p->ready, and _threadrgrp also contain
9 * live thread pointers. These may only be consulted
10 * while holding p->lock or _threadrgrp.lock; in procs
11 * other than p, the pointers are only guaranteed to be live
12 * while the lock is still being held.
14 * Thread structures can only be freed by the proc
15 * they belong to. Threads marked with t->inrendez
16 * need to be extracted from the _threadrgrp before
19 * _threadrgrp.lock cannot be acquired while holding p->lock.
22 typedef struct Pqueue Pqueue;
23 typedef struct Rgrp Rgrp;
24 typedef struct Tqueue Tqueue;
25 typedef struct Thread Thread;
26 typedef struct Execargs Execargs;
27 typedef struct Proc Proc;
28 typedef struct Iocall Iocall;
30 /* must match list in sched.c */
56 Thread *hash[RENDHASH];
59 struct Tqueue /* Thread queue */
68 Lock lock; /* protects thread data structure */
69 jmp_buf sched; /* for context switches */
70 int id; /* thread id */
71 int grp; /* thread group */
72 int moribund; /* thread needs to die */
73 State state; /* run state */
74 State nextstate; /* next run state */
75 uchar *stk; /* top of stack (lowest address of stack) */
76 uint stksize; /* stack size */
77 Thread *next; /* next on ready queue */
79 Proc *proc; /* proc of this thread */
80 Thread *nextt; /* next on list of threads in this proc*/
81 int ret; /* return value for Exec, Fork */
83 char *cmdname; /* ptr to name of thread */
86 Thread *rendhash; /* Trgrp linked list */
87 void* rendtag; /* rendezvous tag */
88 void* rendval; /* rendezvous value */
89 int rendbreak; /* rendezvous has been taken */
91 Chanstate chan; /* which channel operation is current */
92 Alt *alt; /* pointer to current alt structure (debugging) */
94 void* udata; /* User per-thread data pointer */
107 jmp_buf sched; /* for context switches */
108 int pid; /* process id */
109 int splhi; /* delay notes */
110 Thread *thread; /* running thread */
113 Execargs exec; /* exec argument */
114 Proc *newproc; /* fork argument */
115 char exitstr[ERRMAX]; /* exit status */
119 Tqueue threads; /* All threads of this proc */
120 Tqueue ready; /* Runnable threads */
123 char printbuf[Printsize];
124 int blocked; /* In a rendezvous */
125 int pending; /* delayed note pending */
126 int nonotes; /* delay notes */
127 uint nextID; /* ID of most recently created thread */
128 Proc *next; /* linked list of Procs */
130 void *arg; /* passed between shared and unshared stk */
131 char str[ERRMAX]; /* used by threadexits to avoid malloc */
133 void* udata; /* User per-proc data pointer */
134 char threadint; /* tag for threadexitsall() */
137 struct Pqueue /* Proc queue */
154 long (*op)(va_list*);
160 Proc* _newproc(void(*)(void*), void*, uint, char*, int, int);
161 int _procsplhi(void);
164 int _schedexec(Execargs*);
165 void _schedexecwait(void);
166 void _schedexit(Proc*);
167 int _schedfork(Proc*);
168 void _schedinit(void*);
169 void _systhreadinit(void);
170 void _threadassert(char*);
171 void _threadbreakrendez(void);
172 void _threaddebug(ulong, char*, ...);
173 void _threadexitsall(char*);
174 void _threadflagrendez(Thread*);
175 Proc* _threadgetproc(void);
176 void _threadsetproc(Proc*);
177 void _threadinitstack(Thread*, void(*)(void*), void*);
178 void* _threadmalloc(long, int);
179 void _threadnote(void*, char*);
180 void _threadready(Thread*);
181 void* _threadrendezvous(void*, void*);
182 void _threadsysfatal(char*, va_list);
183 void** _workerdata(void);
185 extern int _threaddebuglevel;
186 extern char* _threadexitsallstatus;
187 extern Pqueue _threadpq;
188 extern Channel* _threadwaitchan;
189 extern Rgrp _threadrgrp;
191 #define DBGAPPL (1 << 0)
192 #define DBGSCHED (1 << 16)
193 #define DBGCHAN (1 << 17)
194 #define DBGREND (1 << 18)
195 /* #define DBGKILL (1 << 19) */
196 #define DBGNOTE (1 << 20)
197 #define DBGEXEC (1 << 21)
199 #define ioproc_arg(io, type) (va_arg((io)->arg, type))