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 Alt *alt;
118 };
120 struct _Procrendez
122 Lock *l;
123 int asleep;
124 #ifdef PLAN9PORT_USING_PTHREADS
125 pthread_cond_t cond;
126 #else
127 int pid;
128 #endif
129 };
131 extern void _procsleep(_Procrendez*);
132 extern void _procwakeup(_Procrendez*);
133 extern void _procwakeupandunlock(_Procrendez*);
135 struct Proc
137 Proc *next;
138 Proc *prev;
139 char msg[128];
140 #ifdef PLAN9PORT_USING_PTHREADS
141 pthread_t osprocid;
142 #else
143 int osprocid;
144 #endif
145 Lock lock;
146 int nswitch;
147 _Thread *thread;
148 _Thread *pinthread;
149 _Threadlist runqueue;
150 _Threadlist idlequeue;
151 _Threadlist allthreads;
152 uint nthread;
153 uint sysproc;
154 _Procrendez runrend;
155 Context schedcontext;
156 void *udata;
157 Jmp sigjmp;
158 int mainproc;
159 };
161 #define proc() _threadproc()
162 #define setproc(p) _threadsetproc(p)
164 extern Proc *_threadprocs;
165 extern Lock _threadprocslock;
166 extern Proc *_threadexecproc;
167 extern Channel *_threadexecchan;
168 extern QLock _threadexeclock;
169 extern Channel *_dowaitchan;
171 extern void _procstart(Proc*, void (*fn)(Proc*));
172 extern _Thread *_threadcreate(Proc*, void(*fn)(void*), void*, uint);
173 extern void _threadexit(void);
174 extern Proc *_threadproc(void);
175 extern void _threadsetproc(Proc*);
176 extern int _threadlock(Lock*, int, ulong);
177 extern void _threadunlock(Lock*, ulong);
178 extern void _pthreadinit(void);
179 extern int _threadspawn(int*, char*, char**);
180 extern int _runthreadspawn(int*, char*, char**);
181 extern void _threadsetupdaemonize(void);
182 extern void _threaddodaemonize(char*);
183 extern void _threadpexit(void);
184 extern void _threaddaemonize(void);