#include "lib9.h"#include "dat.h"#include "fns.h"#include "error.h"#include "interp.h" voidksleep(Rendez *r, int (*f)(void*), void *arg){ up->r = r; lock(&r->l); if(f(arg)) { up->r = nil; unlock(&r->l); return; } if(r->p != nil) panic("Sleep %s %s r=%p\n", r->p->text, up->text, r); up->swipend = 0; r->p = up; unlock(&r->l); krendez(up, 0); if(up->swipend) { up->swipend = 0; error(Eintr); }} voidkwakeup(Rendez *r){ Proc *p; lock(&r->l); p = r->p; if(p != nil) { r->p = nil; p->r = nil; krendez(p, 0); } unlock(&r->l);} voidswiproc(Proc *p){ Rendez *r; if(p == nil) return; /* * Pull out of emu Sleep */ r = p->r; if(r != nil) { lock(&r->l); if(p->r == r) { p->swipend = 1; r->p = nil; p->r = nil; krendez(p, 0); } unlock(&r->l); return; } /* * Maybe pull out of Host OS */ lock(&p->sysio); if(p->syscall && p->intwait == 0) { p->intwait = 1; p->swipend = 1; unlock(&p->sysio); oshostintr(p); return; } unlock(&p->sysio);} voidosenter(void){ up->syscall = 1; strcpy(up->text, "syscall");} voidosleave(void){ int r; lock(&up->sysio); r = up->swipend; up->swipend = 0; up->syscall = 0; unlock(&up->sysio); /* Cleared by the signal/note/exception handler */ while(up->intwait) osyield(); if(r != 0) error(Eintr); strcpy(up->text, "");}
#include "lib9.h"
#include "dat.h"
#include "fns.h"
#include "error.h"
#include "interp.h"
void
ksleep(Rendez *r, int (*f)(void*), void *arg)
{
up->r = r;
lock(&r->l);
if(f(arg)) {
up->r = nil;
unlock(&r->l);
return;
}
if(r->p != nil)
panic("Sleep %s %s r=%p\n", r->p->text, up->text, r);
up->swipend = 0;
r->p = up;
unlock(&r->l);
krendez(up, 0);
if(up->swipend) {
up->swipend = 0;
error(Eintr);
}
}
void
kwakeup(Rendez *r)
{
Proc *p;
lock(&r->l);
p = r->p;
if(p != nil) {
r->p = nil;
p->r = nil;
krendez(p, 0);
}
unlock(&r->l);
}
void
swiproc(Proc *p)
{
Rendez *r;
if(p == nil)
return;
/*
* Pull out of emu Sleep
*/
r = p->r;
if(r != nil) {
lock(&r->l);
if(p->r == r) {
p->swipend = 1;
r->p = nil;
p->r = nil;
krendez(p, 0);
}
unlock(&r->l);
return;
}
/*
* Maybe pull out of Host OS
*/
lock(&p->sysio);
if(p->syscall && p->intwait == 0) {
p->intwait = 1;
p->swipend = 1;
unlock(&p->sysio);
oshostintr(p);
return;
}
unlock(&p->sysio);
}
void
osenter(void)
{
up->syscall = 1;
strcpy(up->text, "syscall");
}
void
osleave(void)
{
int r;
lock(&up->sysio);
r = up->swipend;
up->swipend = 0;
up->syscall = 0;
unlock(&up->sysio);
/* Cleared by the signal/note/exception handler */
while(up->intwait)
osyield();
if(r != 0)
error(Eintr);
strcpy(up->text, "");
}