Blob


1 #include "u.h"
2 #include <errno.h>
3 #include <sys/time.h>
4 #include <sys/types.h>
5 #include <sys/wait.h>
6 #include <sched.h>
7 #include <signal.h>
8 #if !defined(__OpenBSD__)
9 # include <ucontext.h>
10 #endif
11 #include <sys/utsname.h>
12 #include "libc.h"
13 #include "thread.h"
15 #if defined(__FreeBSD__) && __FreeBSD__ < 5
16 extern int getmcontext(mcontext_t*);
17 extern void setmcontext(mcontext_t*);
18 #define setcontext(u) setmcontext(&(u)->uc_mcontext)
19 #define getcontext(u) getmcontext(&(u)->uc_mcontext)
20 extern int swapcontext(ucontext_t*, ucontext_t*);
21 extern void makecontext(ucontext_t*, void(*)(), int, ...);
22 #endif
24 #if defined(__APPLE__)
25 # define mcontext libthread_mcontext
26 # define mcontext_t libthread_mcontext_t
27 # define ucontext libthread_ucontext
28 # define ucontext_t libthread_ucontext_t
29 # if defined(__i386__)
30 # include "386-ucontext.h"
31 # else
32 # include "power-ucontext.h"
33 # endif
34 #endif
36 #if defined(__OpenBSD__)
37 # define mcontext libthread_mcontext
38 # define mcontext_t libthread_mcontext_t
39 # define ucontext libthread_ucontext
40 # define ucontext_t libthread_ucontext_t
41 # if defined __i386__
42 # include "386-ucontext.h"
43 # else
44 # include "power-ucontext.h"
45 # endif
46 extern pid_t rfork_thread(int, void*, int(*)(void*), void*);
47 #endif
49 /* THIS DOES NOT WORK! Don't do this!
50 (At least, not on Solaris. Maybe this is right for Linux,
51 in which case it should say if defined(__linux__) && defined(__sun__),
52 but surely the latter would be defined(__sparc__).
54 #if defined(__sun__)
55 # define mcontext libthread_mcontext
56 # define mcontext_t libthread_mcontext_t
57 # define ucontext libthread_ucontext
58 # define ucontext_t libthread_ucontext_t
59 # include "sparc-ucontext.h"
60 #endif
61 */
63 #if defined(__arm__)
64 int getmcontext(mcontext_t*);
65 void setmcontext(const mcontext_t*);
66 #define setcontext(u) setmcontext(&(u)->uc_mcontext)
67 #define getcontext(u) getmcontext(&(u)->uc_mcontext)
68 #endif
71 typedef struct Context Context;
72 typedef struct Execjob Execjob;
73 typedef struct Proc Proc;
74 typedef struct _Procrendez _Procrendez;
76 typedef struct Jmp Jmp;
77 struct Jmp
78 {
79 p9jmp_buf b;
80 };
82 enum
83 {
84 STACK = 8192
85 };
87 struct Context
88 {
89 ucontext_t uc;
90 };
92 struct Execjob
93 {
94 int *fd;
95 char *cmd;
96 char **argv;
97 Channel *c;
98 };
100 struct _Thread
102 _Thread *next;
103 _Thread *prev;
104 _Thread *allnext;
105 _Thread *allprev;
106 Context context;
107 uint id;
108 uchar *stk;
109 uint stksize;
110 int exiting;
111 void (*startfn)(void*);
112 void *startarg;
113 Proc *proc;
114 char name[256];
115 char state[256];
116 void *udata;
117 };
119 struct _Procrendez
121 Lock *l;
122 int asleep;
123 #ifdef PLAN9PORT_USING_PTHREADS
124 pthread_cond_t cond;
125 #else
126 int pid;
127 #endif
128 };
130 extern void _procsleep(_Procrendez*);
131 extern void _procwakeup(_Procrendez*);
132 extern void _procwakeupandunlock(_Procrendez*);
134 struct Proc
136 Proc *next;
137 Proc *prev;
138 char msg[128];
139 #ifdef PLAN9PORT_USING_PTHREADS
140 pthread_t osprocid;
141 #else
142 int osprocid;
143 #endif
144 Lock lock;
145 int nswitch;
146 _Thread *thread;
147 _Thread *pinthread;
148 _Threadlist runqueue;
149 _Threadlist idlequeue;
150 _Threadlist allthreads;
151 uint nthread;
152 uint sysproc;
153 _Procrendez runrend;
154 Context schedcontext;
155 void *udata;
156 Jmp sigjmp;
157 int mainproc;
158 };
160 #define proc() _threadproc()
161 #define setproc(p) _threadsetproc(p)
163 extern Proc *_threadprocs;
164 extern Lock _threadprocslock;
165 extern Proc *_threadexecproc;
166 extern Channel *_threadexecchan;
167 extern QLock _threadexeclock;
168 extern Channel *_dowaitchan;
170 extern void _procstart(Proc*, void (*fn)(Proc*));
171 extern _Thread *_threadcreate(Proc*, void(*fn)(void*), void*, uint);
172 extern void _threadexit(void);
173 extern Proc *_threadproc(void);
174 extern void _threadsetproc(Proc*);
175 extern int _threadlock(Lock*, int, ulong);
176 extern void _threadunlock(Lock*, ulong);
177 extern void _pthreadinit(void);
178 extern int _threadspawn(int*, char*, char**);
179 extern int _runthreadspawn(int*, char*, char**);
180 extern void _threadsetupdaemonize(void);
181 extern void _threaddodaemonize(char*);
182 extern void _threadpexit(void);
183 extern void _threaddaemonize(void);