4 #include "threadimpl.h"
6 typedef struct Mainarg Mainarg;
16 static jmp_buf _mainjmp;
17 static void mainlauncher(void*);
18 extern void (*_sysfatal)(char*, va_list);
19 extern void (*__assert)(char*);
20 extern int (*_dial)(char*, char*, char*, int*);
22 extern int _threaddial(char*, char*, char*, int*);
27 main(int argc, char **argv)
37 //_threaddebuglevel = (DBGSCHED|DBGCHAN|DBGREND)^~0;
39 _qlockinit(_threadrendezvous);
40 _sysfatal = _threadsysfatal;
42 __assert = _threadassert;
44 if(mainstacksize == 0)
45 mainstacksize = 8*1024;
47 a = _threadmalloc(sizeof *a, 1);
51 p = _newproc(mainlauncher, a, mainstacksize, "threadmain", 0, 0);
53 abort(); /* not reached */
57 mainlauncher(void *arg)
62 threadmain(a->argc, a->argv);
63 threadexits("threadmain");
71 while(*p != ' ' && *p != 0)
83 memset(b, 0, sizeof(b));
84 f = open("/dev/cputime", OREAD|OCEXEC);
87 if(read(f, b, sizeof(b)) <= 0){
113 _threaddebug(DBGEXEC, "_schedexec %s", e->prog);
115 exec(e->prog, e->args);
116 _threaddebug(DBGEXEC, "_schedexec failed: %r");
117 rerrstr(buf, sizeof buf);
119 strcpy(buf, "exec failed");
120 write(e->fd[1], buf, strlen(buf));
126 _schedexec(Execargs *e)
130 switch(pid = rfork(RFREND|RFNOTEG|RFFDG|RFMEM|RFPROC)){
143 switch(pid = rfork(RFPROC|RFMEM|RFNOWAIT|p->rforkflag)){
145 *mainp = p; /* write to stack, so local to proc */
146 longjmp(_mainjmp, 1);
158 lock(&_threadpq.lock);
159 for(l=&_threadpq.head; *l; l=&(*l)->next){
167 unlock(&_threadpq.lock);
169 utfecpy(ex, ex+sizeof ex, p->exitstr);
183 p = _threadgetproc();
186 _threaddebug(DBGEXEC, "_schedexecwait %d", t->ret);
198 if((c = _threadwaitchan) != nil)
203 threadexits("procexec");
221 _threadsetproc(Proc *p)