threadimpl.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /*
  10. * Some notes on locking:
  11. *
  12. * All the locking woes come from implementing
  13. * threadinterrupt (and threadkill).
  14. *
  15. * _threadgetproc()->thread is always a live pointer.
  16. * p->threads, p->ready, and _threadrgrp also contain
  17. * live thread pointers. These may only be consulted
  18. * while holding p->lock or _threadrgrp.lock; in procs
  19. * other than p, the pointers are only guaranteed to be live
  20. * while the lock is still being held.
  21. *
  22. * Thread structures can only be freed by the proc
  23. * they belong to. Threads marked with t->inrendez
  24. * need to be extracted from the _threadrgrp before
  25. * being freed.
  26. *
  27. * _threadrgrp.lock cannot be acquired while holding p->lock.
  28. */
  29. typedef struct Pqueue Pqueue;
  30. typedef struct Rgrp Rgrp;
  31. typedef struct Tqueue Tqueue;
  32. typedef struct Thread Thread;
  33. typedef struct Execargs Execargs;
  34. typedef struct Proc Proc;
  35. /* must match list in sched.c */
  36. typedef enum
  37. {
  38. Dead,
  39. Running,
  40. Ready,
  41. Rendezvous,
  42. } State;
  43. typedef enum
  44. {
  45. Channone,
  46. Chanalt,
  47. Chansend,
  48. Chanrecv,
  49. } Chanstate;
  50. enum
  51. {
  52. RENDHASH = 13,
  53. Printsize = 2048,
  54. NPRIV = 8,
  55. };
  56. struct Rgrp
  57. {
  58. Lock lock;
  59. Thread *hash[RENDHASH];
  60. };
  61. struct Tqueue /* Thread queue */
  62. {
  63. int asleep;
  64. Thread *head;
  65. Thread **tail;
  66. };
  67. struct Thread
  68. {
  69. Lock lock; /* protects thread data structure */
  70. jmp_buf sched; /* for context switches */
  71. int id; /* thread id */
  72. int grp; /* thread group */
  73. int moribund; /* thread needs to die */
  74. State state; /* run state */
  75. State nextstate; /* next run state */
  76. unsigned char *stk; /* top of stack (lowest address of stack) */
  77. uint stksize; /* stack size */
  78. 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 */
  82. char *cmdname; /* ptr to name of thread */
  83. int inrendez;
  84. Thread *rendhash; /* Trgrp linked list */
  85. void* rendtag; /* rendezvous tag */
  86. void* rendval; /* rendezvous value */
  87. int rendbreak; /* rendezvous has been taken */
  88. Chanstate chan; /* which channel operation is current */
  89. Alt *alt; /* pointer to current alt structure (debugging) */
  90. void* udata[NPRIV]; /* User per-thread data pointer */
  91. };
  92. struct Execargs
  93. {
  94. char *prog;
  95. char **args;
  96. int fd[2];
  97. };
  98. struct Proc
  99. {
  100. Lock lock;
  101. jmp_buf sched; /* for context switches */
  102. int pid; /* process id */
  103. int splhi; /* delay notes */
  104. Thread *thread; /* running thread */
  105. int needexec;
  106. Execargs exec; /* exec argument */
  107. Proc *newproc; /* fork argument */
  108. char exitstr[ERRMAX]; /* exit status */
  109. int rforkflag;
  110. int nthreads;
  111. Tqueue threads; /* All threads of this proc */
  112. Tqueue ready; /* Runnable threads */
  113. Lock readylock;
  114. char printbuf[Printsize];
  115. int blocked; /* In a rendezvous */
  116. int pending; /* delayed note pending */
  117. int nonotes; /* delay notes */
  118. uint nextID; /* ID of most recently created thread */
  119. Proc *next; /* linked list of Procs */
  120. void *arg; /* passed between shared and unshared stk */
  121. char str[ERRMAX]; /* used by threadexits to avoid malloc */
  122. void* wdata; /* Lib(worker) per-proc data pointer */
  123. void* udata; /* User per-proc data pointer */
  124. char threadint; /* tag for threadexitsall() */
  125. };
  126. struct Pqueue { /* Proc queue */
  127. Lock lock;
  128. Proc *head;
  129. Proc **tail;
  130. };
  131. struct Ioproc
  132. {
  133. int tid;
  134. Channel *c, *creply;
  135. int inuse;
  136. int32_t (*op)(va_list*);
  137. va_list arg;
  138. long ret;
  139. char err[ERRMAX];
  140. Ioproc *next;
  141. };
  142. void _freeproc(Proc*);
  143. void _freethread(Thread*);
  144. Proc* _newproc(void(*)(void*), void*, uint, char*, int, int);
  145. int _procsplhi(void);
  146. void _procsplx(int);
  147. void _sched(void);
  148. int _schedexec(Execargs*);
  149. void _schedexecwait(void);
  150. void _schedexit(Proc*);
  151. int _schedfork(Proc*);
  152. void _schedinit(void*);
  153. void _systhreadinit(void);
  154. void _threadassert(char*);
  155. void _threadbreakrendez(void);
  156. void _threaddebug(uint32_t, char*, ...);
  157. void _threadexitsall(char*);
  158. void _threadflagrendez(Thread*);
  159. Proc* _threadgetproc(void);
  160. void _threadsetproc(Proc*);
  161. void _threadinitstack(Thread*, void(*)(void*), void*);
  162. void* _threadmalloc(int32_t, int);
  163. void _threadnote(void*, char*);
  164. void _threadready(Thread*);
  165. void* _threadrendezvous(void*, void*);
  166. void _threadsignal(void);
  167. void _threadsysfatal(char*, ...);
  168. void** _workerdata(void);
  169. void _xinc(int32_t*);
  170. long _xdec(int32_t*);
  171. extern int _threaddebuglevel;
  172. extern char* _threadexitsallstatus;
  173. extern Pqueue _threadpq;
  174. extern Channel* _threadwaitchan;
  175. extern Rgrp _threadrgrp;
  176. #define DBGAPPL (1 << 0)
  177. #define DBGSCHED (1 << 16)
  178. #define DBGCHAN (1 << 17)
  179. #define DBGREND (1 << 18)
  180. /* #define DBGKILL (1 << 19) */
  181. #define DBGNOTE (1 << 20)
  182. #define DBGEXEC (1 << 21)
  183. #define ioproc_arg(io, type) (va_arg((io)->arg, type))