#include #include #include "threadimpl.h" typedef struct Mainarg Mainarg; struct Mainarg { int argc; char **argv; }; int mainstacksize; int _threadnotefd; int _threadpasserpid; static void mainlauncher(void*); extern void (*_sysfatal)(char*, va_list); void _threadstatus(int x) { USED(x); threadstatus(); } void _threaddie(int x) { extern char *_threadexitsallstatus; USED(x); if(_threadexitsallstatus) exit(_threadexitsallstatus[0] ? 1 : 0); } static void _nop(int x) { USED(x); } int main(int argc, char **argv) { Mainarg *a; Proc *p; signal(SIGTERM, _threaddie); signal(SIGCHLD, _nop); signal(SIGALRM, _nop); // signal(SIGINFO, _threadstatus); // rfork(RFREND); //_threaddebuglevel = (DBGSCHED|DBGCHAN|DBGREND)^~0; _systhreadinit(); _qlockinit(_threadrendezvous); _sysfatal = _threadsysfatal; notify(_threadnote); if(mainstacksize == 0) mainstacksize = 32*1024; a = _threadmalloc(sizeof *a, 1); a->argc = argc; a->argv = argv; p = _newproc(mainlauncher, a, mainstacksize, "threadmain", 0, 0); _schedinit(p); abort(); /* not reached */ return 0; } static void mainlauncher(void *arg) { Mainarg *a; a = arg; threadmain(a->argc, a->argv); threadexits("threadmain"); } void _threadsignal(void) { } void _threadsignalpasser(void) { } int _schedfork(Proc *p) { int pid; lock(&p->lock); pid = ffork(RFMEM|RFNOWAIT, _schedinit, p); p->pid = pid; unlock(&p->lock); return pid; } void _schedexit(Proc *p) { char ex[ERRMAX]; Proc **l; lock(&_threadpq.lock); for(l=&_threadpq.head; *l; l=&(*l)->next){ if(*l == p){ *l = p->next; if(*l == nil) _threadpq.tail = l; break; } } _threadprocs--; unlock(&_threadpq.lock); strncpy(ex, p->exitstr, sizeof ex); ex[sizeof ex-1] = '\0'; free(p); _exit(ex[0]); } int nrand(int n) { return random()%n; } void _systhreadinit(void) { } void threadstats(void) { extern int _threadnrendez, _threadhighnrendez, _threadnalt, _threadhighnentry; fprint(2, "*** THREAD LIBRARY STATS ***\n"); fprint(2, "nrendez %d high simultaneous %d\n", _threadnrendez, _threadhighnrendez); fprint(2, "nalt %d high simultaneous entry %d\n", _threadnalt, _threadhighnentry); }