aboutsummaryrefslogtreecommitdiff
path: root/src/libthread/ucontext.c
blob: 98e92ccfa727fddc1d6f6207bd226c435f505a96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "threadimpl.h"

static void
launcher(void (*f)(void*), void *arg)
{
	f(arg);
	threadexits(nil);
}

void
_threadinitstack(Thread *t, void (*f)(void*), void *arg)
{
	sigset_t zero;

	/* do a reasonable initialization */
	memset(&t->context.uc, 0, sizeof t->context.uc);
	sigemptyset(&zero);
	sigprocmask(SIG_BLOCK, &zero, &t->context.uc.uc_sigmask);

	/* call getcontext, because on Linux makecontext neglects floating point */
	getcontext(&t->context.uc);

	/* call makecontext to do the real work. */
	/* leave a few words open on both ends */
	t->context.uc.uc_stack.ss_sp = t->stk+8;
	t->context.uc.uc_stack.ss_size = t->stksize-16;
	makecontext(&t->context.uc, (void(*)())launcher, 2, f, arg);
}

void
_threadinswitch(int enter)
{
	USED(enter);
}

void
_threadstacklimit(void *bottom, void *top)
{
	USED(bottom);
	USED(top);
}

void
_swaplabel(Label *old, Label *new)
{
	if(swapcontext(&old->uc, &new->uc) < 0)
		sysfatal("swapcontext: %r");
}