Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
14
_assert(char *fmt)
15
{
16
	panic("assert failed: %s", fmt);
17
}
18
 
19
int
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
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
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
58
kexit(void)
59
{
60
	_exits(nil);
61
}
62
 
63
void
64
initcompat(void)
65
{
66
	rfork(RFREND);
67
	privup = privalloc();
68
	kerndate = seconds();
69
	eve = getuser();
70
	newup("main");
71
}
72
 
73
int
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
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*
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
113
seconds(void)
114
{
115
	return time(nil);
116
}
117
 
118
void
119
error(char *err)
120
{
121
	strncpy(up->error, err, ERRMAX);
122
	nexterror();
123
}
124
 
125
void
126
nexterror(void)
127
{
128
	longjmp(up->errlab[--up->nerrlab], 1);
129
}
130
 
131
int
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
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
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
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
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
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
244
rendclearintr(void)
245
{
246
	lock(&up->rlock);
247
	up->intr = 0;
248
	unlock(&up->rlock);
249
}
250