123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- #include <u.h>
- #include <libc.h>
- #include "compat.h"
- #include "error.h"
- #include "errstr.h"
- ulong kerndate;
- Proc **privup;
- char *eve;
- extern void *mainmem;
- void
- _assert(char *fmt)
- {
- panic("assert failed: %s", fmt);
- }
- int
- errdepth(int ed)
- {
- if(ed >= 0 && up->nerrlab != ed)
- panic("unbalanced error depth: expected %d got %d\n", ed, up->nerrlab);
- return up->nerrlab;
- }
- void
- newup(char *name)
- {
- up = smalloc(sizeof(Proc));
- up->user = eve;
- strncpy(up->name, name, KNAMELEN-1);
- up->name[KNAMELEN-1] = '\0';
- }
- void
- kproc(char *name, void (*f)(void *), void *a)
- {
- int pid;
- pid = rfork(RFPROC|RFMEM|RFNOWAIT);
- switch(pid){
- case -1:
- panic("can't make new thread: %r");
- case 0:
- break;
- default:
- return;
- }
- newup(name);
- if(!waserror())
- (*f)(a);
- _exits(nil);
- }
- void
- kexit(void)
- {
- _exits(nil);
- }
- void
- initcompat(void)
- {
- rfork(RFREND);
- privup = privalloc();
- kerndate = seconds();
- eve = getuser();
- newup("main");
- }
- int
- openmode(ulong o)
- {
- o &= ~(OTRUNC|OCEXEC|ORCLOSE);
- if(o > OEXEC)
- error(Ebadarg);
- if(o == OEXEC)
- return OREAD;
- return o;
- }
- void
- panic(char *fmt, ...)
- {
- char buf[512];
- char buf2[512];
- va_list va;
- va_start(va, fmt);
- vseprint(buf, buf+sizeof(buf), fmt, va);
- va_end(va);
- sprint(buf2, "panic: %s\n", buf);
- write(2, buf2, strlen(buf2));
- exits("error");
- }
- void*
- smalloc(ulong n)
- {
- void *p;
- p = mallocz(n, 1);
- if(p == nil)
- panic("out of memory");
- setmalloctag(p, getcallerpc(&n));
- return p;
- }
- long
- seconds(void)
- {
- return time(nil);
- }
- void
- error(char *err)
- {
- strncpy(up->error, err, ERRMAX);
- nexterror();
- }
- void
- nexterror(void)
- {
- longjmp(up->errlab[--up->nerrlab], 1);
- }
- int
- readstr(ulong off, char *buf, ulong n, char *str)
- {
- int size;
- size = strlen(str);
- if(off >= size)
- return 0;
- if(off+n > size)
- n = size-off;
- memmove(buf, str+off, n);
- return n;
- }
- void
- _rendsleep(void* tag)
- {
- void *value;
- for(;;){
- value = rendezvous(tag, (void*)0x22a891b8);
- if(value == (void*)0x7f7713f9)
- break;
- if(tag != (void*)~0)
- panic("_rendsleep: rendezvous mismatch");
- }
- }
- void
- _rendwakeup(void* tag)
- {
- void *value;
- for(;;){
- value = rendezvous(tag, (void*)0x7f7713f9);
- if(value == (void*)0x22a891b8)
- break;
- if(tag != (void*)~0)
- panic("_rendwakeup: rendezvous mismatch");
- }
- }
- void
- rendsleep(Rendez *r, int (*f)(void*), void *arg)
- {
- lock(&up->rlock);
- up->r = r;
- unlock(&up->rlock);
- lock(r);
- /*
- * if condition happened, never mind
- */
- if(up->intr || f(arg)){
- unlock(r);
- goto Done;
- }
- /*
- * now we are committed to
- * change state and call scheduler
- */
- if(r->p)
- panic("double sleep");
- r->p = up;
- unlock(r);
- _rendsleep(r);
- Done:
- lock(&up->rlock);
- up->r = 0;
- if(up->intr){
- up->intr = 0;
- unlock(&up->rlock);
- error(Eintr);
- }
- unlock(&up->rlock);
- }
- int
- rendwakeup(Rendez *r)
- {
- Proc *p;
- int rv;
- lock(r);
- p = r->p;
- rv = 0;
- if(p){
- r->p = nil;
- _rendwakeup(r);
- rv = 1;
- }
- unlock(r);
- return rv;
- }
- void
- rendintr(void *v)
- {
- Proc *p;
- p = v;
- lock(&p->rlock);
- p->intr = 1;
- if(p->r)
- rendwakeup(p->r);
- unlock(&p->rlock);
- }
- void
- rendclearintr(void)
- {
- lock(&up->rlock);
- up->intr = 0;
- unlock(&up->rlock);
- }
|