xref: /plan9/sys/src/cmd/vnc/compat.c (revision 74f16c8187aab477889167f2422d0597b1b7d0ff)
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