Blame


1 31cf0ab1 2004-12-28 devnull #include "threadimpl.h"
2 31cf0ab1 2004-12-28 devnull
3 4753f069 2005-01-17 devnull #undef exits
4 4753f069 2005-01-17 devnull #undef _exits
5 4753f069 2005-01-17 devnull
6 31cf0ab1 2004-12-28 devnull extern int __isthreaded;
7 31cf0ab1 2004-12-28 devnull
8 31cf0ab1 2004-12-28 devnull /*
9 31cf0ab1 2004-12-28 devnull * spin locks
10 31cf0ab1 2004-12-28 devnull */
11 31cf0ab1 2004-12-28 devnull extern int _tas(int*);
12 31cf0ab1 2004-12-28 devnull
13 31cf0ab1 2004-12-28 devnull void
14 31cf0ab1 2004-12-28 devnull _threadunlock(Lock *l, ulong pc)
15 31cf0ab1 2004-12-28 devnull {
16 31cf0ab1 2004-12-28 devnull USED(pc);
17 31cf0ab1 2004-12-28 devnull
18 31cf0ab1 2004-12-28 devnull l->held = 0;
19 31cf0ab1 2004-12-28 devnull }
20 31cf0ab1 2004-12-28 devnull
21 31cf0ab1 2004-12-28 devnull int
22 31cf0ab1 2004-12-28 devnull _threadlock(Lock *l, int block, ulong pc)
23 31cf0ab1 2004-12-28 devnull {
24 31cf0ab1 2004-12-28 devnull int i;
25 31cf0ab1 2004-12-28 devnull
26 31cf0ab1 2004-12-28 devnull USED(pc);
27 31cf0ab1 2004-12-28 devnull
28 31cf0ab1 2004-12-28 devnull /* once fast */
29 31cf0ab1 2004-12-28 devnull if(!_tas(&l->held))
30 31cf0ab1 2004-12-28 devnull return 1;
31 31cf0ab1 2004-12-28 devnull if(!block)
32 31cf0ab1 2004-12-28 devnull return 0;
33 31cf0ab1 2004-12-28 devnull
34 31cf0ab1 2004-12-28 devnull /* a thousand times pretty fast */
35 31cf0ab1 2004-12-28 devnull for(i=0; i<1000; i++){
36 31cf0ab1 2004-12-28 devnull if(!_tas(&l->held))
37 31cf0ab1 2004-12-28 devnull return 1;
38 31cf0ab1 2004-12-28 devnull sched_yield();
39 31cf0ab1 2004-12-28 devnull }
40 31cf0ab1 2004-12-28 devnull /* now nice and slow */
41 31cf0ab1 2004-12-28 devnull for(i=0; i<1000; i++){
42 31cf0ab1 2004-12-28 devnull if(!_tas(&l->held))
43 31cf0ab1 2004-12-28 devnull return 1;
44 31cf0ab1 2004-12-28 devnull usleep(100*1000);
45 31cf0ab1 2004-12-28 devnull }
46 31cf0ab1 2004-12-28 devnull /* take your time */
47 31cf0ab1 2004-12-28 devnull while(_tas(&l->held))
48 31cf0ab1 2004-12-28 devnull usleep(1000*1000);
49 31cf0ab1 2004-12-28 devnull return 1;
50 31cf0ab1 2004-12-28 devnull }
51 31cf0ab1 2004-12-28 devnull
52 31cf0ab1 2004-12-28 devnull /*
53 31cf0ab1 2004-12-28 devnull * For FreeBSD libc.
54 31cf0ab1 2004-12-28 devnull */
55 31cf0ab1 2004-12-28 devnull
56 31cf0ab1 2004-12-28 devnull typedef struct {
57 31cf0ab1 2004-12-28 devnull volatile long access_lock;
58 31cf0ab1 2004-12-28 devnull volatile long lock_owner;
59 31cf0ab1 2004-12-28 devnull volatile char *fname;
60 31cf0ab1 2004-12-28 devnull volatile int lineno;
61 31cf0ab1 2004-12-28 devnull } spinlock_t;
62 31cf0ab1 2004-12-28 devnull
63 31cf0ab1 2004-12-28 devnull void
64 31cf0ab1 2004-12-28 devnull _spinlock(spinlock_t *lk)
65 31cf0ab1 2004-12-28 devnull {
66 31cf0ab1 2004-12-28 devnull lock((Lock*)&lk->access_lock);
67 31cf0ab1 2004-12-28 devnull }
68 31cf0ab1 2004-12-28 devnull
69 31cf0ab1 2004-12-28 devnull /*
70 31cf0ab1 2004-12-28 devnull * sleep and wakeup
71 31cf0ab1 2004-12-28 devnull */
72 31cf0ab1 2004-12-28 devnull static void
73 31cf0ab1 2004-12-28 devnull ign(int x)
74 31cf0ab1 2004-12-28 devnull {
75 31cf0ab1 2004-12-28 devnull USED(x);
76 31cf0ab1 2004-12-28 devnull }
77 31cf0ab1 2004-12-28 devnull
78 31cf0ab1 2004-12-28 devnull static void /*__attribute__((constructor))*/
79 31cf0ab1 2004-12-28 devnull ignusr1(int restart)
80 31cf0ab1 2004-12-28 devnull {
81 31cf0ab1 2004-12-28 devnull struct sigaction sa;
82 31cf0ab1 2004-12-28 devnull
83 31cf0ab1 2004-12-28 devnull memset(&sa, 0, sizeof sa);
84 31cf0ab1 2004-12-28 devnull sa.sa_handler = ign;
85 31cf0ab1 2004-12-28 devnull sigemptyset(&sa.sa_mask);
86 31cf0ab1 2004-12-28 devnull sigaddset(&sa.sa_mask, SIGUSR1);
87 31cf0ab1 2004-12-28 devnull if(restart)
88 31cf0ab1 2004-12-28 devnull sa.sa_flags = SA_RESTART;
89 31cf0ab1 2004-12-28 devnull sigaction(SIGUSR1, &sa, nil);
90 31cf0ab1 2004-12-28 devnull }
91 31cf0ab1 2004-12-28 devnull
92 31cf0ab1 2004-12-28 devnull void
93 31cf0ab1 2004-12-28 devnull _procsleep(_Procrendez *r)
94 31cf0ab1 2004-12-28 devnull {
95 31cf0ab1 2004-12-28 devnull sigset_t mask;
96 31cf0ab1 2004-12-28 devnull
97 31cf0ab1 2004-12-28 devnull /*
98 31cf0ab1 2004-12-28 devnull * Go to sleep.
99 31cf0ab1 2004-12-28 devnull *
100 31cf0ab1 2004-12-28 devnull * Block USR1, set the handler to interrupt system calls,
101 31cf0ab1 2004-12-28 devnull * unlock the vouslock so our waker can wake us,
102 31cf0ab1 2004-12-28 devnull * and then suspend.
103 31cf0ab1 2004-12-28 devnull */
104 31cf0ab1 2004-12-28 devnull again:
105 31cf0ab1 2004-12-28 devnull r->asleep = 1;
106 31cf0ab1 2004-12-28 devnull r->pid = getpid();
107 31cf0ab1 2004-12-28 devnull
108 31cf0ab1 2004-12-28 devnull sigprocmask(SIG_SETMASK, nil, &mask);
109 31cf0ab1 2004-12-28 devnull sigaddset(&mask, SIGUSR1);
110 31cf0ab1 2004-12-28 devnull sigprocmask(SIG_SETMASK, &mask, nil);
111 31cf0ab1 2004-12-28 devnull ignusr1(0);
112 31cf0ab1 2004-12-28 devnull unlock(r->l);
113 31cf0ab1 2004-12-28 devnull sigdelset(&mask, SIGUSR1);
114 31cf0ab1 2004-12-28 devnull sigsuspend(&mask);
115 31cf0ab1 2004-12-28 devnull
116 31cf0ab1 2004-12-28 devnull /*
117 31cf0ab1 2004-12-28 devnull * We're awake. Make USR1 not interrupt system calls.
118 31cf0ab1 2004-12-28 devnull */
119 31cf0ab1 2004-12-28 devnull lock(r->l);
120 31cf0ab1 2004-12-28 devnull ignusr1(1);
121 31cf0ab1 2004-12-28 devnull if(r->asleep && r->pid == getpid()){
122 31cf0ab1 2004-12-28 devnull /* Didn't really wake up - signal from something else */
123 31cf0ab1 2004-12-28 devnull goto again;
124 31cf0ab1 2004-12-28 devnull }
125 31cf0ab1 2004-12-28 devnull }
126 31cf0ab1 2004-12-28 devnull
127 31cf0ab1 2004-12-28 devnull void
128 31cf0ab1 2004-12-28 devnull _procwakeup(_Procrendez *r)
129 31cf0ab1 2004-12-28 devnull {
130 31cf0ab1 2004-12-28 devnull if(r->asleep){
131 31cf0ab1 2004-12-28 devnull r->asleep = 0;
132 31cf0ab1 2004-12-28 devnull assert(r->pid >= 1);
133 31cf0ab1 2004-12-28 devnull kill(r->pid, SIGUSR1);
134 31cf0ab1 2004-12-28 devnull }
135 4a8edd8d 2005-01-14 devnull }
136 4a8edd8d 2005-01-14 devnull
137 4a8edd8d 2005-01-14 devnull void
138 4a8edd8d 2005-01-14 devnull _procwakeupandunlock(_Procrendez *r)
139 4a8edd8d 2005-01-14 devnull {
140 4a8edd8d 2005-01-14 devnull _procwakeup(r);
141 4a8edd8d 2005-01-14 devnull unlock(r->l);
142 31cf0ab1 2004-12-28 devnull }
143 31cf0ab1 2004-12-28 devnull
144 4a8edd8d 2005-01-14 devnull
145 31cf0ab1 2004-12-28 devnull /*
146 31cf0ab1 2004-12-28 devnull * process creation and exit
147 31cf0ab1 2004-12-28 devnull */
148 31cf0ab1 2004-12-28 devnull typedef struct Stackfree Stackfree;
149 31cf0ab1 2004-12-28 devnull struct Stackfree
150 31cf0ab1 2004-12-28 devnull {
151 31cf0ab1 2004-12-28 devnull Stackfree *next;
152 31cf0ab1 2004-12-28 devnull int pid;
153 31cf0ab1 2004-12-28 devnull };
154 31cf0ab1 2004-12-28 devnull static Lock stacklock;
155 31cf0ab1 2004-12-28 devnull static Stackfree *stackfree;
156 31cf0ab1 2004-12-28 devnull
157 31cf0ab1 2004-12-28 devnull static void
158 31cf0ab1 2004-12-28 devnull delayfreestack(uchar *stk)
159 31cf0ab1 2004-12-28 devnull {
160 31cf0ab1 2004-12-28 devnull Stackfree *sf;
161 31cf0ab1 2004-12-28 devnull
162 31cf0ab1 2004-12-28 devnull sf = (Stackfree*)stk;
163 31cf0ab1 2004-12-28 devnull sf->pid = getpid();
164 31cf0ab1 2004-12-28 devnull lock(&stacklock);
165 31cf0ab1 2004-12-28 devnull sf->next = stackfree;
166 31cf0ab1 2004-12-28 devnull stackfree = sf;
167 31cf0ab1 2004-12-28 devnull unlock(&stacklock);
168 31cf0ab1 2004-12-28 devnull }
169 31cf0ab1 2004-12-28 devnull
170 31cf0ab1 2004-12-28 devnull static void
171 31cf0ab1 2004-12-28 devnull dofreestacks(void)
172 31cf0ab1 2004-12-28 devnull {
173 31cf0ab1 2004-12-28 devnull Stackfree *sf, *last, *next;
174 31cf0ab1 2004-12-28 devnull
175 31cf0ab1 2004-12-28 devnull if(stackfree==nil || !canlock(&stacklock))
176 31cf0ab1 2004-12-28 devnull return;
177 31cf0ab1 2004-12-28 devnull
178 31cf0ab1 2004-12-28 devnull for(last=nil,sf=stackfree; sf; last=sf,sf=next){
179 31cf0ab1 2004-12-28 devnull next = sf->next;
180 31cf0ab1 2004-12-28 devnull if(sf->pid >= 1 && kill(sf->pid, 0) < 0 && errno == ESRCH){
181 31cf0ab1 2004-12-28 devnull free(sf);
182 31cf0ab1 2004-12-28 devnull if(last)
183 31cf0ab1 2004-12-28 devnull last->next = next;
184 31cf0ab1 2004-12-28 devnull else
185 31cf0ab1 2004-12-28 devnull stackfree = next;
186 31cf0ab1 2004-12-28 devnull sf = last;
187 31cf0ab1 2004-12-28 devnull }
188 31cf0ab1 2004-12-28 devnull }
189 31cf0ab1 2004-12-28 devnull unlock(&stacklock);
190 31cf0ab1 2004-12-28 devnull }
191 31cf0ab1 2004-12-28 devnull
192 31cf0ab1 2004-12-28 devnull static int
193 31cf0ab1 2004-12-28 devnull startprocfn(void *v)
194 31cf0ab1 2004-12-28 devnull {
195 31cf0ab1 2004-12-28 devnull void **a;
196 31cf0ab1 2004-12-28 devnull uchar *stk;
197 31cf0ab1 2004-12-28 devnull void (*fn)(void*);
198 31cf0ab1 2004-12-28 devnull Proc *p;
199 31cf0ab1 2004-12-28 devnull
200 31cf0ab1 2004-12-28 devnull a = (void**)v;
201 31cf0ab1 2004-12-28 devnull fn = a[0];
202 31cf0ab1 2004-12-28 devnull p = a[1];
203 31cf0ab1 2004-12-28 devnull stk = a[2];
204 31cf0ab1 2004-12-28 devnull free(a);
205 31cf0ab1 2004-12-28 devnull p->osprocid = getpid();
206 31cf0ab1 2004-12-28 devnull
207 31cf0ab1 2004-12-28 devnull (*fn)(p);
208 31cf0ab1 2004-12-28 devnull
209 31cf0ab1 2004-12-28 devnull delayfreestack(stk);
210 31cf0ab1 2004-12-28 devnull _exit(0);
211 31cf0ab1 2004-12-28 devnull return 0;
212 31cf0ab1 2004-12-28 devnull }
213 31cf0ab1 2004-12-28 devnull
214 31cf0ab1 2004-12-28 devnull void
215 31cf0ab1 2004-12-28 devnull _procstart(Proc *p, void (*fn)(Proc*))
216 31cf0ab1 2004-12-28 devnull {
217 31cf0ab1 2004-12-28 devnull void **a;
218 31cf0ab1 2004-12-28 devnull uchar *stk;
219 31cf0ab1 2004-12-28 devnull int pid;
220 31cf0ab1 2004-12-28 devnull
221 31cf0ab1 2004-12-28 devnull dofreestacks();
222 31cf0ab1 2004-12-28 devnull a = malloc(3*sizeof a[0]);
223 31cf0ab1 2004-12-28 devnull if(a == nil)
224 31cf0ab1 2004-12-28 devnull sysfatal("_procstart malloc: %r");
225 31cf0ab1 2004-12-28 devnull stk = malloc(65536);
226 31cf0ab1 2004-12-28 devnull if(stk == nil)
227 31cf0ab1 2004-12-28 devnull sysfatal("_procstart malloc stack: %r");
228 31cf0ab1 2004-12-28 devnull
229 31cf0ab1 2004-12-28 devnull a[0] = fn;
230 31cf0ab1 2004-12-28 devnull a[1] = p;
231 31cf0ab1 2004-12-28 devnull a[2] = stk;
232 31cf0ab1 2004-12-28 devnull
233 31cf0ab1 2004-12-28 devnull pid = rfork_thread(RFPROC|RFMEM|RFNOWAIT, stk+65536-64, startprocfn, a);
234 31cf0ab1 2004-12-28 devnull if(pid < 0){
235 31cf0ab1 2004-12-28 devnull fprint(2, "_procstart rfork_thread: %r\n");
236 31cf0ab1 2004-12-28 devnull abort();
237 31cf0ab1 2004-12-28 devnull }
238 31cf0ab1 2004-12-28 devnull }
239 31cf0ab1 2004-12-28 devnull
240 31cf0ab1 2004-12-28 devnull static char *threadexitsmsg;
241 31cf0ab1 2004-12-28 devnull void
242 31cf0ab1 2004-12-28 devnull sigusr2handler(int s)
243 31cf0ab1 2004-12-28 devnull {
244 31cf0ab1 2004-12-28 devnull /* fprint(2, "%d usr2 %d\n", time(0), getpid()); */
245 31cf0ab1 2004-12-28 devnull if(threadexitsmsg)
246 31cf0ab1 2004-12-28 devnull _exits(threadexitsmsg);
247 31cf0ab1 2004-12-28 devnull }
248 31cf0ab1 2004-12-28 devnull
249 31cf0ab1 2004-12-28 devnull void
250 31cf0ab1 2004-12-28 devnull threadexitsall(char *msg)
251 31cf0ab1 2004-12-28 devnull {
252 31cf0ab1 2004-12-28 devnull static int pid[1024];
253 31cf0ab1 2004-12-28 devnull int i, npid, mypid;
254 31cf0ab1 2004-12-28 devnull Proc *p;
255 31cf0ab1 2004-12-28 devnull
256 31cf0ab1 2004-12-28 devnull if(msg == nil)
257 31cf0ab1 2004-12-28 devnull msg = "";
258 31cf0ab1 2004-12-28 devnull mypid = getpid();
259 31cf0ab1 2004-12-28 devnull lock(&_threadprocslock);
260 31cf0ab1 2004-12-28 devnull threadexitsmsg = msg;
261 31cf0ab1 2004-12-28 devnull npid = 0;
262 31cf0ab1 2004-12-28 devnull for(p=_threadprocs; p; p=p->next)
263 31cf0ab1 2004-12-28 devnull if(p->osprocid != mypid && p->osprocid >= 1)
264 31cf0ab1 2004-12-28 devnull pid[npid++] = p->osprocid;
265 31cf0ab1 2004-12-28 devnull for(i=0; i<npid; i++)
266 31cf0ab1 2004-12-28 devnull kill(pid[i], SIGUSR2);
267 31cf0ab1 2004-12-28 devnull unlock(&_threadprocslock);
268 31cf0ab1 2004-12-28 devnull exits(msg);
269 31cf0ab1 2004-12-28 devnull }
270 31cf0ab1 2004-12-28 devnull
271 31cf0ab1 2004-12-28 devnull /*
272 31cf0ab1 2004-12-28 devnull * per-process data, indexed by pid
273 31cf0ab1 2004-12-28 devnull *
274 31cf0ab1 2004-12-28 devnull * could use modify_ldt and a segment register
275 31cf0ab1 2004-12-28 devnull * to avoid the many calls to getpid(), but i don't
276 31cf0ab1 2004-12-28 devnull * care -- this is compatibility code. linux 2.6 with
277 31cf0ab1 2004-12-28 devnull * nptl is a good enough pthreads to avoid this whole file.
278 31cf0ab1 2004-12-28 devnull */
279 31cf0ab1 2004-12-28 devnull typedef struct Perproc Perproc;
280 31cf0ab1 2004-12-28 devnull struct Perproc
281 31cf0ab1 2004-12-28 devnull {
282 31cf0ab1 2004-12-28 devnull int pid;
283 31cf0ab1 2004-12-28 devnull Proc *proc;
284 31cf0ab1 2004-12-28 devnull };
285 31cf0ab1 2004-12-28 devnull
286 31cf0ab1 2004-12-28 devnull static Lock perlock;
287 31cf0ab1 2004-12-28 devnull static Perproc perproc[1024];
288 31cf0ab1 2004-12-28 devnull #define P ((Proc*)-1)
289 31cf0ab1 2004-12-28 devnull
290 31cf0ab1 2004-12-28 devnull static Perproc*
291 31cf0ab1 2004-12-28 devnull myperproc(void)
292 31cf0ab1 2004-12-28 devnull {
293 31cf0ab1 2004-12-28 devnull int i, pid, h;
294 31cf0ab1 2004-12-28 devnull Perproc *p;
295 31cf0ab1 2004-12-28 devnull
296 31cf0ab1 2004-12-28 devnull pid = getpid();
297 31cf0ab1 2004-12-28 devnull h = pid%nelem(perproc);
298 31cf0ab1 2004-12-28 devnull for(i=0; i<nelem(perproc); i++){
299 31cf0ab1 2004-12-28 devnull p = &perproc[(i+h)%nelem(perproc)];
300 31cf0ab1 2004-12-28 devnull if(p->pid == pid)
301 31cf0ab1 2004-12-28 devnull return p;
302 31cf0ab1 2004-12-28 devnull if(p->pid == 0){
303 31cf0ab1 2004-12-28 devnull print("found 0 at %d (h=%d)\n", (i+h)%nelem(perproc), h);
304 31cf0ab1 2004-12-28 devnull break;
305 31cf0ab1 2004-12-28 devnull }
306 31cf0ab1 2004-12-28 devnull }
307 31cf0ab1 2004-12-28 devnull fprint(2, "myperproc %d: cannot find self\n", pid);
308 31cf0ab1 2004-12-28 devnull abort();
309 31cf0ab1 2004-12-28 devnull return nil;
310 31cf0ab1 2004-12-28 devnull }
311 31cf0ab1 2004-12-28 devnull
312 31cf0ab1 2004-12-28 devnull static Perproc*
313 31cf0ab1 2004-12-28 devnull newperproc(void)
314 31cf0ab1 2004-12-28 devnull {
315 31cf0ab1 2004-12-28 devnull int i, pid, h;
316 31cf0ab1 2004-12-28 devnull Perproc *p;
317 31cf0ab1 2004-12-28 devnull
318 31cf0ab1 2004-12-28 devnull lock(&perlock);
319 31cf0ab1 2004-12-28 devnull pid = getpid();
320 31cf0ab1 2004-12-28 devnull h = pid%nelem(perproc);
321 31cf0ab1 2004-12-28 devnull for(i=0; i<nelem(perproc); i++){
322 31cf0ab1 2004-12-28 devnull p = &perproc[(i+h)%nelem(perproc)];
323 31cf0ab1 2004-12-28 devnull if(p->pid == pid || p->pid == -1 || p->pid == 0){
324 31cf0ab1 2004-12-28 devnull p->pid = pid;
325 31cf0ab1 2004-12-28 devnull unlock(&perlock);
326 31cf0ab1 2004-12-28 devnull return p;
327 31cf0ab1 2004-12-28 devnull }
328 31cf0ab1 2004-12-28 devnull }
329 31cf0ab1 2004-12-28 devnull fprint(2, "newperproc %d: out of procs\n", pid);
330 31cf0ab1 2004-12-28 devnull abort();
331 31cf0ab1 2004-12-28 devnull return nil;
332 31cf0ab1 2004-12-28 devnull }
333 31cf0ab1 2004-12-28 devnull
334 31cf0ab1 2004-12-28 devnull Proc*
335 31cf0ab1 2004-12-28 devnull _threadproc(void)
336 31cf0ab1 2004-12-28 devnull {
337 31cf0ab1 2004-12-28 devnull return myperproc()->proc;
338 31cf0ab1 2004-12-28 devnull }
339 31cf0ab1 2004-12-28 devnull
340 31cf0ab1 2004-12-28 devnull void
341 31cf0ab1 2004-12-28 devnull _threadsetproc(Proc *p)
342 31cf0ab1 2004-12-28 devnull {
343 31cf0ab1 2004-12-28 devnull Perproc *pp;
344 31cf0ab1 2004-12-28 devnull
345 31cf0ab1 2004-12-28 devnull if(p)
346 31cf0ab1 2004-12-28 devnull p->osprocid = getpid();
347 31cf0ab1 2004-12-28 devnull pp = newperproc();
348 31cf0ab1 2004-12-28 devnull pp->proc = p;
349 31cf0ab1 2004-12-28 devnull if(p == nil)
350 31cf0ab1 2004-12-28 devnull pp->pid = -1;
351 31cf0ab1 2004-12-28 devnull }
352 31cf0ab1 2004-12-28 devnull
353 31cf0ab1 2004-12-28 devnull void
354 31cf0ab1 2004-12-28 devnull _pthreadinit(void)
355 31cf0ab1 2004-12-28 devnull {
356 d54ead7f 2004-12-28 devnull __isthreaded = 1;
357 31cf0ab1 2004-12-28 devnull signal(SIGUSR2, sigusr2handler);
358 31cf0ab1 2004-12-28 devnull }
359 d54ead7f 2004-12-28 devnull
360 1d2533d0 2004-12-28 devnull void
361 1d2533d0 2004-12-28 devnull _threadpexit(void)
362 1d2533d0 2004-12-28 devnull {
363 1d2533d0 2004-12-28 devnull _exit(0);
364 1d2533d0 2004-12-28 devnull }
365 1d2533d0 2004-12-28 devnull
366 1d2533d0 2004-12-28 devnull
367 d54ead7f 2004-12-28 devnull /*
368 d54ead7f 2004-12-28 devnull * FreeBSD 4 and earlier needs the context functions.
369 d54ead7f 2004-12-28 devnull */
370 d54ead7f 2004-12-28 devnull void
371 d54ead7f 2004-12-28 devnull makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
372 d54ead7f 2004-12-28 devnull {
373 d54ead7f 2004-12-28 devnull int *sp;
374 31cf0ab1 2004-12-28 devnull
375 d54ead7f 2004-12-28 devnull sp = (int*)ucp->uc_stack.ss_sp+ucp->uc_stack.ss_size/4;
376 d54ead7f 2004-12-28 devnull sp -= argc;
377 d54ead7f 2004-12-28 devnull memmove(sp, &argc+1, argc*sizeof(int));
378 d54ead7f 2004-12-28 devnull *--sp = 0; /* return address */
379 d54ead7f 2004-12-28 devnull ucp->uc_mcontext.mc_eip = (long)func;
380 d54ead7f 2004-12-28 devnull ucp->uc_mcontext.mc_esp = (int)sp;
381 d54ead7f 2004-12-28 devnull }
382 d54ead7f 2004-12-28 devnull
383 d54ead7f 2004-12-28 devnull extern int getmcontext(mcontext_t*);
384 d54ead7f 2004-12-28 devnull extern int setmcontext(mcontext_t*);
385 d54ead7f 2004-12-28 devnull
386 d54ead7f 2004-12-28 devnull int
387 d54ead7f 2004-12-28 devnull getcontext(ucontext_t *uc)
388 d54ead7f 2004-12-28 devnull {
389 d54ead7f 2004-12-28 devnull return getmcontext(&uc->uc_mcontext);
390 d54ead7f 2004-12-28 devnull }
391 d54ead7f 2004-12-28 devnull
392 d54ead7f 2004-12-28 devnull void
393 d54ead7f 2004-12-28 devnull setcontext(ucontext_t *uc)
394 d54ead7f 2004-12-28 devnull {
395 d54ead7f 2004-12-28 devnull setmcontext(&uc->uc_mcontext);
396 d54ead7f 2004-12-28 devnull }
397 d54ead7f 2004-12-28 devnull
398 d54ead7f 2004-12-28 devnull int
399 d54ead7f 2004-12-28 devnull swapcontext(ucontext_t *oucp, ucontext_t *ucp)
400 d54ead7f 2004-12-28 devnull {
401 d54ead7f 2004-12-28 devnull if(getcontext(oucp) == 0)
402 d54ead7f 2004-12-28 devnull setcontext(ucp);
403 d54ead7f 2004-12-28 devnull return 0;
404 d54ead7f 2004-12-28 devnull }
405 d54ead7f 2004-12-28 devnull