Blob


1 #include <signal.h>
2 #include "threadimpl.h"
4 typedef struct Mainarg Mainarg;
5 struct Mainarg
6 {
7 int argc;
8 char **argv;
9 };
11 int mainstacksize;
12 int _threadnotefd;
13 int _threadpasserpid;
14 static void mainlauncher(void*);
15 extern void (*_sysfatal)(char*, va_list);
17 void
18 _threaddie(int x)
19 {
20 extern char *_threadexitsallstatus;
21 USED(x);
23 if(_threadexitsallstatus)
24 exit(_threadexitsallstatus[0] ? 1 : 0);
25 }
27 static void
28 _nop(int x)
29 {
30 USED(x);
31 }
33 int
34 main(int argc, char **argv)
35 {
36 Mainarg *a;
37 Proc *p;
39 signal(SIGTERM, _threaddie);
40 signal(SIGCHLD, _nop);
41 // rfork(RFREND);
43 //_threaddebuglevel = (DBGSCHED|DBGCHAN|DBGREND)^~0;
44 _systhreadinit();
45 _qlockinit(_threadrendezvous);
46 _sysfatal = _threadsysfatal;
47 notify(_threadnote);
48 if(mainstacksize == 0)
49 mainstacksize = 32*1024;
51 a = _threadmalloc(sizeof *a, 1);
52 a->argc = argc;
53 a->argv = argv;
55 p = _newproc(mainlauncher, a, mainstacksize, "threadmain", 0, 0);
56 _schedinit(p);
57 abort(); /* not reached */
58 return 0;
59 }
61 static void
62 mainlauncher(void *arg)
63 {
64 Mainarg *a;
66 a = arg;
67 threadmain(a->argc, a->argv);
68 threadexits("threadmain");
69 }
71 void
72 _threadsignal(void)
73 {
74 }
76 void
77 _threadsignalpasser(void)
78 {
79 }
81 int
82 _schedfork(Proc *p)
83 {
84 int pid;
85 lock(&p->lock);
86 pid = ffork(RFMEM|RFNOWAIT, _schedinit, p);
87 p->pid = pid;
88 unlock(&p->lock);
89 return pid;
91 }
93 void
94 _schedexit(Proc *p)
95 {
96 char ex[ERRMAX];
97 Proc **l;
99 lock(&_threadpq.lock);
100 for(l=&_threadpq.head; *l; l=&(*l)->next){
101 if(*l == p){
102 *l = p->next;
103 if(*l == nil)
104 _threadpq.tail = l;
105 break;
108 _threadprocs--;
109 unlock(&_threadpq.lock);
111 strncpy(ex, p->exitstr, sizeof ex);
112 ex[sizeof ex-1] = '\0';
113 free(p);
114 _exit(ex[0]);
117 int
118 nrand(int n)
120 return random()%n;
123 void
124 _systhreadinit(void)
128 void
129 threadstats(void)
131 extern int _threadnrendez, _threadhighnrendez,
132 _threadnalt, _threadhighnentry;
133 fprint(2, "*** THREAD LIBRARY STATS ***\n");
134 fprint(2, "nrendez %d high simultaneous %d\n",
135 _threadnrendez, _threadhighnrendez);
136 fprint(2, "nalt %d high simultaneous entry %d\n",
137 _threadnalt, _threadhighnentry);