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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
$NetBSD: patch-au,v 1.2 2005/03/01 10:00:47 is Exp $
--- csw/netbsd.c.orig 2005-03-01 09:35:06.000000000 +0000
+++ csw/netbsd.c
@@ -0,0 +1,116 @@
+/*
+ * netbsd.c -- context switch code for NetBSD 2.
+ *
+ * Some Makefile changes are needed to use this code.
+ */
+
+#include <ucontext.h>
+
+static void startup();
+void sr_stk_underflow();
+
+#ifdef __i386__
+void pthread__i386_init(void);
+
+#define _getcontext_u(uc) (*_md_getcontext_u)(uc)
+#define _setcontext_u(uc) (*_md_setcontext_u)(uc)
+#define _swapcontext_u(oc,nc) (*_md_swapcontext_u)(oc,nc)
+
+static void sr_getcontext_u(ucontext_t *);
+static void sr_setcontext_u(ucontext_t *);
+static void sr_swapcontext_u(ucontext_t *, ucontext_t *);
+
+void (*_md_getcontext_u) (ucontext_t *) = sr_getcontext_u;
+void (*_md_setcontext_u) (ucontext_t *) = sr_setcontext_u;
+void (*_md_swapcontext_u)(ucontext_t *, ucontext_t *) = sr_swapcontext_u;
+
+static void
+sr_getcontext_u(ucontext_t *uc) {
+ pthread__i386_init();
+ _getcontext_u(uc);
+}
+
+static void
+sr_setcontext_u(ucontext_t *uc) {
+ pthread__i386_init();
+ _setcontext_u(uc);
+}
+
+static void
+sr_swapcontext_u(ucontext_t *oldc, ucontext_t *newc) {
+ pthread__i386_init();
+ _swapcontext_u(oldc, newc);
+}
+#endif
+
+
+/*
+ * sr_build_context (func, buf, bufsize, arg1, arg2, arg3, arg4)
+ *
+ * Build a context that will call func(arg1,arg2,arg3,arg4) when activated
+ * and will catch an underflow error if func returns. We use an intermediary
+ * in order to catch that return.
+ */
+void
+sr_build_context (func, buf, bufsize, arg1, arg2, arg3, arg4)
+void (*func)();
+char *buf;
+int bufsize;
+unsigned long arg1, arg2, arg3, arg4;
+{
+ ucontext_t *uc = (ucontext_t *) buf; /* put header at front of buf */
+
+ _getcontext_u(uc); /* initialize context */
+
+ uc->uc_stack.ss_sp = buf + sizeof (ucontext_t);
+ uc->uc_stack.ss_size = bufsize - sizeof (ucontext_t);
+
+ makecontext (uc, startup, 5, func, arg1, arg2, arg3, arg4);
+ uc->uc_stack.ss_flags = 0;
+}
+
+/*
+ * startup (func, stk) -- intermediary for startup and underflow detection.
+ */
+static void
+startup (func, arg1, arg2, arg3, arg4)
+void (*func)();
+unsigned long arg1, arg2, arg3, arg4;
+{
+ (*func) (arg1, arg2, arg3, arg4);
+ sr_stk_underflow();
+}
+
+
+
+/*
+ * sr_chg_context (newctx, oldctx) -- change contexts.
+ */
+void
+sr_chg_context (new, old)
+char *new, *old;
+{
+ ucontext_t *oldu, *newu;
+ newu = (ucontext_t *)new;
+
+ if (old) {
+ oldu = (ucontext_t *)old;
+ _swapcontext_u(oldu, newu);
+ } else {
+ _setcontext_u(newu);
+ }
+}
+
+
+
+/*
+ * sr_check_stk (stk) -- check for stack overflow.
+ *
+ * We have no idea of how to do that, so we do nothing.
+ */
+void
+sr_check_stk(stk)
+char *stk;
+{
+ /* nothing */
+}
|