main.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <thread.h>
  4. #include "threadimpl.h"
  5. typedef struct Mainarg Mainarg;
  6. struct Mainarg
  7. {
  8. int argc;
  9. char **argv;
  10. };
  11. int mainstacksize;
  12. int _threadnotefd;
  13. int _threadpasserpid;
  14. static jmp_buf _mainjmp;
  15. static void mainlauncher(void*);
  16. extern void (*_sysfatal)(char*, va_list);
  17. extern void (*__assert)(char*);
  18. void
  19. main(int argc, char **argv)
  20. {
  21. Mainarg *a;
  22. Proc *p;
  23. rfork(RFREND);
  24. if(p = (Proc*)setjmp(_mainjmp))
  25. _schedinit(p);
  26. //_threaddebuglevel = (DBGSCHED|DBGCHAN|DBGREND)^~0;
  27. _systhreadinit();
  28. _qlockinit(_threadrendezvous);
  29. _sysfatal = _threadsysfatal;
  30. __assert = _threadassert;
  31. notify(_threadnote);
  32. if(mainstacksize == 0)
  33. mainstacksize = 8*1024;
  34. a = _threadmalloc(sizeof *a, 1);
  35. a->argc = argc;
  36. a->argv = argv;
  37. p = _newproc(mainlauncher, a, mainstacksize, "threadmain", 0, 0);
  38. _schedinit(p);
  39. abort(); /* not reached */
  40. }
  41. static void
  42. mainlauncher(void *arg)
  43. {
  44. Mainarg *a;
  45. a = arg;
  46. threadmain(a->argc, a->argv);
  47. threadexits("threadmain");
  48. }
  49. static char*
  50. skip(char *p)
  51. {
  52. while(*p == ' ')
  53. p++;
  54. while(*p != ' ' && *p != 0)
  55. p++;
  56. return p;
  57. }
  58. static long
  59. _times(long *t)
  60. {
  61. char b[200], *p;
  62. int f;
  63. ulong r;
  64. memset(b, 0, sizeof(b));
  65. f = open("/dev/cputime", OREAD|OCEXEC);
  66. if(f < 0)
  67. return 0;
  68. if(read(f, b, sizeof(b)) <= 0){
  69. close(f);
  70. return 0;
  71. }
  72. p = b;
  73. if(t)
  74. t[0] = atol(p);
  75. p = skip(p);
  76. if(t)
  77. t[1] = atol(p);
  78. p = skip(p);
  79. r = atol(p);
  80. if(t){
  81. p = skip(p);
  82. t[2] = atol(p);
  83. p = skip(p);
  84. t[3] = atol(p);
  85. }
  86. return r;
  87. }
  88. static void
  89. efork(Execargs *e)
  90. {
  91. char buf[ERRMAX];
  92. _threaddebug(DBGEXEC, "_schedexec %s", e->prog);
  93. close(e->fd[0]);
  94. exec(e->prog, e->args);
  95. _threaddebug(DBGEXEC, "_schedexec failed: %r");
  96. rerrstr(buf, sizeof buf);
  97. if(buf[0]=='\0')
  98. strcpy(buf, "exec failed");
  99. write(e->fd[1], buf, strlen(buf));
  100. close(e->fd[1]);
  101. _exits(buf);
  102. }
  103. int
  104. _schedexec(Execargs *e)
  105. {
  106. int pid;
  107. switch(pid = rfork(RFREND|RFNOTEG|RFFDG|RFMEM|RFPROC)){
  108. case 0:
  109. efork(e);
  110. default:
  111. return pid;
  112. }
  113. }
  114. int
  115. _schedfork(Proc *p)
  116. {
  117. int pid;
  118. switch(pid = rfork(RFPROC|RFMEM|RFNOWAIT|p->rforkflag)){
  119. case 0:
  120. longjmp(_mainjmp, (int)p);
  121. default:
  122. return pid;
  123. }
  124. }
  125. void
  126. _schedexit(Proc *p)
  127. {
  128. char ex[ERRMAX];
  129. Proc **l;
  130. lock(&_threadpq.lock);
  131. for(l=&_threadpq.head; *l; l=&(*l)->next){
  132. if(*l == p){
  133. *l = p->next;
  134. if(*l == nil)
  135. _threadpq.tail = l;
  136. break;
  137. }
  138. }
  139. unlock(&_threadpq.lock);
  140. utfecpy(ex, ex+sizeof ex, p->exitstr);
  141. free(p);
  142. _exits(ex);
  143. }
  144. void
  145. _schedexecwait(void)
  146. {
  147. int pid;
  148. Channel *c;
  149. Proc *p;
  150. Thread *t;
  151. Waitmsg *w;
  152. p = _threadgetproc();
  153. t = p->thread;
  154. pid = t->ret;
  155. _threaddebug(DBGEXEC, "_schedexecwait %d", t->ret);
  156. rfork(RFCFDG);
  157. for(;;){
  158. w = wait();
  159. if(w == nil)
  160. break;
  161. if(w->pid == pid)
  162. break;
  163. free(w);
  164. }
  165. if(w != nil){
  166. if((c = _threadwaitchan) != nil)
  167. sendp(c, w);
  168. else
  169. free(w);
  170. }
  171. threadexits("procexec");
  172. }
  173. static Proc **procp;
  174. void
  175. _systhreadinit(void)
  176. {
  177. procp = privalloc();
  178. }
  179. Proc*
  180. _threadgetproc(void)
  181. {
  182. return *procp;
  183. }
  184. void
  185. _threadsetproc(Proc *p)
  186. {
  187. *procp = p;
  188. }