251 lines · 3.3 KB · C
RawDownload
#include	"dat.h"#include	"fns.h"#include	"error.h"#include	"interp.h" Proc*newproc(void){	Proc *p; 	p = malloc(sizeof(Proc));	if(p == nil)		return nil; 	p->type = Unknown;	p->killed = 0;	p->swipend = 0;	p->env = &p->defenv;	kstrdup(&p->env->user, "*nouser");	p->env->errstr = p->env->errbuf0;	p->env->syserrstr = p->env->errbuf1;	addprog(p); 	return p;} voidwerrstr(char *fmt, ...){        va_list arg;        char buf[ERRMAX];         va_start(arg, fmt);        vseprint(buf, buf+sizeof(buf), fmt, arg);        va_end(arg);        kstrcpy(up->env->errstr, buf, ERRMAX);} voidSleep(Rendez *r, int (*f)(void*), void *arg){	lock(&up->rlock);	lock(&r->l); 	/*	 * if interrupted or condition happened, never mind	 */	if(up->killed || f(arg)) {		unlock(&r->l);	}else{		if(r->p != nil)			panic("double sleep pc=0x%lux %s[%lud] %s[%lud] r=0x%lux\n", getcallerpc(&r), r->p->text, r->p->pid, up->text, up->pid, r); 		r->p = up;		unlock(&r->l);		up->swipend = 0;		up->r = r;	/* for swiproc */		unlock(&up->rlock); 		osblock(); 		lock(&up->rlock);		up->r = nil;	} 	if(up->killed || up->swipend) {		up->killed = 0;		up->swipend = 0;		unlock(&up->rlock);		error(Eintr);	}	unlock(&up->rlock);} intWakeup(Rendez *r){	Proc *p; 	lock(&r->l);	p = r->p;	if(p != nil) {		r->p = nil;		osready(p);	}	unlock(&r->l);	return p != nil;} voidswiproc(Proc *p, int interp){	Rendez *r;		if(p == nil)		return; 	/*	 * Pull out of emu Sleep	 */	lock(&p->rlock);	if(!interp)		p->killed = 1;	r = p->r;	if(r != nil) {		lock(&r->l);		if(r->p == p){			p->swipend = 1;			r->p = nil;			osready(p);		}		unlock(&r->l);		unlock(&p->rlock);		return;	}	unlock(&p->rlock); 	/*	 * Maybe pull out of Host OS	 */	lock(&p->sysio);	if(p->syscall && p->intwait == 0) {		p->swipend = 1;		p->intwait = 1;		unlock(&p->sysio);		oshostintr(p);		return;		}	unlock(&p->sysio);} voidnotkilled(void){	lock(&up->rlock);	up->killed = 0;	unlock(&up->rlock);} voidosenter(void){	up->syscall = 1;} voidosleave(void){	int r; 	lock(&up->rlock);	r = up->swipend;	up->swipend = 0;	unlock(&up->rlock); 	lock(&up->sysio);	up->syscall = 0;	unlock(&up->sysio); 	/* Cleared by the signal/note/exception handler */	while(up->intwait)		osyield(); 	if(r != 0)		error(Eintr);} voidrptwakeup(void *o, void *ar){	Rept *r; 	r = ar;	if(r == nil)		return;	lock(&r->l);	r->o = o;	unlock(&r->l);	Wakeup(&r->r);} static intrptactive(void *a){	Rept *r = a;	int i;	lock(&r->l);	i = r->active(r->o);	unlock(&r->l);	return i;} static voidrproc(void *a){	long now, then;	ulong t;	int i;	void *o;	Rept *r; 	up->env->fgrp = newfgrp(nil);	r = a;	t = (ulong)r->t; Wait:	Sleep(&r->r, rptactive, r);	lock(&r->l);	o = r->o;	unlock(&r->l);	then = osmillisec();	for(;;){		osmillisleep(t);		now = osmillisec();		if(waserror())			break;		i = r->ck(o, now-then);		poperror();		if(i == -1)			goto Wait;		if(i == 0)			continue;		then = now;		acquire();		if(waserror()) {			release();			break;		}		r->f(o);		poperror();		release();	}	pexit("", 0);} void*rptproc(char *s, int t, void *o, int (*active)(void*), int (*ck)(void*, int), void (*f)(void*)){	Rept *r; 	r = mallocz(sizeof(Rept), 1);	if(r == nil)		return nil;	r->t = t;	r->active = active;	r->ck = ck;	r->f = f;	r->o = o;	kproc(s, rproc, r, KPDUPPG);	return r;}