1 #include <u.h>
2 #include <libc.h>
3 #include "compat.h"
4 #include "error.h"
5
6 #include "errstr.h"
7
8 ulong kerndate;
9 Proc **privup;
10 char *eve;
11 extern void *mainmem;
12
13 void
_assert(char * fmt)14 _assert(char *fmt)
15 {
16 panic("assert failed: %s", fmt);
17 }
18
19 int
errdepth(int ed)20 errdepth(int ed)
21 {
22 if(ed >= 0 && up->nerrlab != ed)
23 panic("unbalanced error depth: expected %d got %d\n", ed, up->nerrlab);
24 return up->nerrlab;
25 }
26
27 void
newup(char * name)28 newup(char *name)
29 {
30 up = smalloc(sizeof(Proc));
31 up->user = eve;
32 strncpy(up->name, name, KNAMELEN-1);
33 up->name[KNAMELEN-1] = '\0';
34 }
35
36 void
kproc(char * name,void (* f)(void *),void * a)37 kproc(char *name, void (*f)(void *), void *a)
38 {
39 int pid;
40
41 pid = rfork(RFPROC|RFMEM|RFNOWAIT);
42 switch(pid){
43 case -1:
44 panic("can't make new thread: %r");
45 case 0:
46 break;
47 default:
48 return;
49 }
50
51 newup(name);
52 if(!waserror())
53 (*f)(a);
54 _exits(nil);
55 }
56
57 void
kexit(void)58 kexit(void)
59 {
60 _exits(nil);
61 }
62
63 void
initcompat(void)64 initcompat(void)
65 {
66 rfork(RFREND);
67 privup = privalloc();
68 kerndate = seconds();
69 eve = getuser();
70 newup("main");
71 }
72
73 int
openmode(ulong o)74 openmode(ulong o)
75 {
76 o &= ~(OTRUNC|OCEXEC|ORCLOSE);
77 if(o > OEXEC)
78 error(Ebadarg);
79 if(o == OEXEC)
80 return OREAD;
81 return o;
82 }
83
84 void
panic(char * fmt,...)85 panic(char *fmt, ...)
86 {
87 char buf[512];
88 char buf2[512];
89 va_list va;
90
91 va_start(va, fmt);
92 vseprint(buf, buf+sizeof(buf), fmt, va);
93 va_end(va);
94 sprint(buf2, "panic: %s\n", buf);
95 write(2, buf2, strlen(buf2));
96
97 exits("error");
98 }
99
100 void*
smalloc(ulong n)101 smalloc(ulong n)
102 {
103 void *p;
104
105 p = mallocz(n, 1);
106 if(p == nil)
107 panic("out of memory");
108 setmalloctag(p, getcallerpc(&n));
109 return p;
110 }
111
112 long
seconds(void)113 seconds(void)
114 {
115 return time(nil);
116 }
117
118 void
error(char * err)119 error(char *err)
120 {
121 strncpy(up->error, err, ERRMAX);
122 nexterror();
123 }
124
125 void
nexterror(void)126 nexterror(void)
127 {
128 longjmp(up->errlab[--up->nerrlab], 1);
129 }
130
131 int
readstr(ulong off,char * buf,ulong n,char * str)132 readstr(ulong off, char *buf, ulong n, char *str)
133 {
134 int size;
135
136 size = strlen(str);
137 if(off >= size)
138 return 0;
139 if(off+n > size)
140 n = size-off;
141 memmove(buf, str+off, n);
142 return n;
143 }
144
145 void
_rendsleep(void * tag)146 _rendsleep(void* tag)
147 {
148 void *value;
149
150 for(;;){
151 value = rendezvous(tag, (void*)0x22a891b8);
152 if(value == (void*)0x7f7713f9)
153 break;
154 if(tag != (void*)~0)
155 panic("_rendsleep: rendezvous mismatch");
156 }
157 }
158
159 void
_rendwakeup(void * tag)160 _rendwakeup(void* tag)
161 {
162 void *value;
163
164 for(;;){
165 value = rendezvous(tag, (void*)0x7f7713f9);
166 if(value == (void*)0x22a891b8)
167 break;
168 if(tag != (void*)~0)
169 panic("_rendwakeup: rendezvous mismatch");
170 }
171 }
172
173 void
rendsleep(Rendez * r,int (* f)(void *),void * arg)174 rendsleep(Rendez *r, int (*f)(void*), void *arg)
175 {
176 lock(&up->rlock);
177 up->r = r;
178 unlock(&up->rlock);
179
180 lock(r);
181
182 /*
183 * if condition happened, never mind
184 */
185 if(up->intr || f(arg)){
186 unlock(r);
187 goto Done;
188 }
189
190 /*
191 * now we are committed to
192 * change state and call scheduler
193 */
194 if(r->p)
195 panic("double sleep");
196 r->p = up;
197 unlock(r);
198
199 _rendsleep(r);
200
201 Done:
202 lock(&up->rlock);
203 up->r = 0;
204 if(up->intr){
205 up->intr = 0;
206 unlock(&up->rlock);
207 error(Eintr);
208 }
209 unlock(&up->rlock);
210 }
211
212 int
rendwakeup(Rendez * r)213 rendwakeup(Rendez *r)
214 {
215 Proc *p;
216 int rv;
217
218 lock(r);
219 p = r->p;
220 rv = 0;
221 if(p){
222 r->p = nil;
223 _rendwakeup(r);
224 rv = 1;
225 }
226 unlock(r);
227 return rv;
228 }
229
230 void
rendintr(void * v)231 rendintr(void *v)
232 {
233 Proc *p;
234
235 p = v;
236 lock(&p->rlock);
237 p->intr = 1;
238 if(p->r)
239 rendwakeup(p->r);
240 unlock(&p->rlock);
241 }
242
243 void
rendclearintr(void)244 rendclearintr(void)
245 {
246 lock(&up->rlock);
247 up->intr = 0;
248 unlock(&up->rlock);
249 }
250
251