From e1f1edbeee60812fff3666210c00973f66dfa30d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 11 Dec 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-12-11 --- gnot/clock.c | 97 +------ gnot/dat.h | 11 + gnot/fns.h | 11 +- gnot/main.c | 82 +++++- gnot/mmu.c | 7 + gnot/page.c | 8 + gnot/proc.c | 725 ------------------------------------------------- gnot/sysproc.c | 514 ----------------------------------- port/alarm.c | 108 ++++++++ port/page.c | 7 +- port/proc.c | 8 +- port/sysproc.c | 36 ++- power/clock.c | 98 +------ power/conf.h | 3 + power/dat.h | 9 + power/fns.h | 6 + power/main.c | 26 ++ power/mmu.c | 11 + 18 files changed, 323 insertions(+), 1444 deletions(-) delete mode 100644 gnot/proc.c delete mode 100644 gnot/sysproc.c create mode 100644 port/alarm.c diff --git a/gnot/clock.c b/gnot/clock.c index 5d59299dadb2445071d908061bf8b066ade4b4ec..2b5e3eb278b648026d1b7e85a0651dc25c00cecd 100644 --- a/gnot/clock.c +++ b/gnot/clock.c @@ -7,75 +7,6 @@ #include "ureg.h" -Alarm *alarmtab; - -Alarm* -alarm(int ms, void (*f)(Alarm*), void *arg) -{ - Alarm *a, *w, *pw; - ulong s; - a = newalarm(); - a->dt = MS2TK(ms); - if(a->dt < 0) - a->dt = 0; - a->f = f; - a->arg = arg; - s = splhi(); - lock(&m->alarmlock); - pw = 0; - for(w=m->alarm; w; pw=w, w=w->next){ - if(w->dt <= a->dt){ - a->dt -= w->dt; - continue; - } - w->dt -= a->dt; - break; - } - insert(&m->alarm, pw, a); - unlock(&m->alarmlock); - splx(s); - return a; -} - -void -cancel(Alarm *a) -{ - a->f = 0; -} - -Alarm* -newalarm(void) -{ - int i; - Alarm *a; - - for(i=0,a=alarmtab; ibusy==0 && a->f==0 && canlock(a)){ - if(a->busy){ - unlock(a); - continue; - } - a->f = 0; - a->arg = 0; - a->busy = 1; - unlock(a); - return a; - } - panic("newalarm"); -} - -void -alarminit(void) -{ - int i; - - alarmtab = ialloc(conf.nalarm*sizeof(Alarm), 0); - for(i=0; iticks++; @@ -105,28 +31,7 @@ clock(Ureg *ur) if (p->state==Running) p->time[p->insyscall]++; } - if(canlock(&m->alarmlock)){ - a = m->alarm; - if(a){ - for(n=0; a && a->dt<=0 && nalarm, 0, a); - a = m->alarm; - } - if(a) - a->dt--; - unlock(&m->alarmlock); - - /* execute alarm functions outside the lock */ - for(i = 0; i < n; i++){ - f = alist[i]->f; /* avoid race with cancel */ - if(f) - (*f)(alist[i]); - alist[i]->busy = 0; - } - } else - unlock(&m->alarmlock); - } + checkalarms(); kbdclock(); mouseclock(); if((ur->sr&SPL(7)) == 0 && p && p->state==Running){ diff --git a/gnot/dat.h b/gnot/dat.h index e98f4831c8aadd6661c47dc70fd04710a8a5ed2d..3efad63762598461b81336b853ff3006b5fe0170 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -152,6 +152,7 @@ struct Conf int npipe; /* number of pipes */ int nservice; /* number of services */ int nfsyschan; /* number of filsys open channels */ + ulong maxialloc; /* maximum bytes used by ialloc */ }; struct Dev @@ -214,6 +215,9 @@ struct Mach Lock alarmlock; /* access to alarm list */ void *alarm; /* alarms bound to this clock */ int fpstate; /* state of fp registers on machine */ + void (*intr)(ulong, ulong); /* !!Compatability with mips!! */ + ulong cause; /* ... */ + ulong pc; /* ... */ int stack[1]; }; @@ -342,6 +346,7 @@ struct Proc int wokeup; /* whether sleep was interrupted */ ulong pc; /* DEBUG only */ int kp; /* true if a kernel process */ + int pidonmach[1]; /* !!Compatability with mips!! */ }; struct MMU @@ -598,3 +603,9 @@ extern char user[NAMELEN]; extern char *errstrtab[]; extern void (*kprofp)(ulong); + +/* + * parameters for sysproc.c + */ +#define AOUT_MAGIC A_MAGIC +#define ENTRYOFFSET 0 diff --git a/gnot/fns.h b/gnot/fns.h index 6ee82c257ca31f6b69d66f7e360df3bb121dad07..261630ad4f2042de9c1117271f1458adfc1aea38 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -8,7 +8,7 @@ int canqlock(QLock*); void chaninit(void); void chandevreset(void); void chandevinit(void); -void checksched(void); +void checkalarms(void); void clearmmucache(void); void clock(Ureg*); Chan *clone(Chan*, Chan*); @@ -79,6 +79,7 @@ void growpte(Orig*, ulong); void *ialloc(ulong, int); int incref(Ref*); void insert(List**, List*, List*); +void invalidateu(void); void isdir(Chan*); void kbdchar(int); void kbdrepeat(int); @@ -86,7 +87,7 @@ void kbdclock(void); void kmapinit(void); KMap *kmap(Page*); int kprint(char*, ...); -void *kproc(char*, void(*)(void*), void*); +void kproc(char*, void(*)(void*), void*); void kunmap(KMap*); void lock(Lock*); void lockinit(void); @@ -138,11 +139,13 @@ int readnum(ulong, char*, ulong, ulong, int); void ready(Proc*); int return0(void*); void rs232ichar(int); +Proc *runproc(void); void qlock(QLock*); void qunlock(QLock*); void restartprint(Alarm*); void restfpregs(FPsave*); -void restore(void); +void restore(Proc*, uchar*); +void save(uchar*, int); void savefpregs(FPsave*); void sched(void); void schedinit(void); @@ -154,6 +157,7 @@ int segaddr(Seg*, ulong, ulong); void serviceinit(void); void service(char*, Chan*, Chan*, void (*)(Chan*, char*, long)); int setlabel(Label*); +void setup(Proc*); char *skipslash(char*); void sleep(Rendez*, int(*)(void*), void*); int splhi(void); @@ -181,6 +185,7 @@ void twakeme(Alarm*); long unionread(Chan*, void*, long); void unlock(Lock*); void usepage(Page*, int); +void unusepage(Page*, int); void userinit(void); void validaddr(ulong, ulong, int); void *vmemchr(void*, int, int); diff --git a/gnot/main.c b/gnot/main.c index 0cc76537c87f77ca10798d4c55f5bcbe18f72b0d..499100cb404cb4cbc8f93b4fb21a002005a7aa13 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -7,6 +7,9 @@ #include "ureg.h" #include "init.h" +#include +#include + typedef struct Boot Boot; struct Boot @@ -103,7 +106,12 @@ init0(void) { Chan *c; - restore(); + u->nerrlab = 0; + m->proc = u->p; + u->p->state = Running; + u->p->mach = m; + spllo(); + chandevinit(); u->slash = (*devtab[0].attach)(0); @@ -137,6 +145,7 @@ userinit(void) p->pgrp = newpgrp(); strcpy(p->text, "*init*"); strcpy(p->pgrp->user, user); + p->fpstate = FPinit; /* * Kernel Stack @@ -177,7 +186,6 @@ userinit(void) s->minva = UTZERO; s->maxva = UTZERO+BY2PG; - m->proc = p; ready(p); } @@ -300,6 +308,7 @@ confinit(void) conf.npage1 = (bank[1]*1024*1024)/BY2PG; conf.base1 = 16*1024*1024; conf.npage = conf.npage0+conf.npage1; + conf.maxialloc = (4*1024*1024-256*1024-BY2PG); mul = 1 + (conf.npage1>0); conf.nproc = 50*mul; conf.npgrp = 12*mul; @@ -331,3 +340,72 @@ confinit(void) conf.nservice = 3*mul; /* was conf.nproc/5 */ conf.nfsyschan = 31 + conf.nchan/20; } + +/* + * set up floating point for a new process + */ +void +setup(Proc *p) +{ + long fpnull; + + fpnull = 0; + splhi(); + m->fpstate = FPinit; + p->fpstate = FPinit; + fprestore((FPsave*)&fpnull); + spllo(); +} + +/* + * Save the part of the process state. + */ +void +save(uchar *state, int len) +{ + Balu *balu; + + if(len < sizeof(Balu)) + panic("save state too small"); + balu = (Balu *)state; + fpsave(&u->fpsave); + if(u->fpsave.type){ + if(u->fpsave.size > sizeof u->fpsave.junk) + panic("fpsize %d max %d\n", u->fpsave.size, sizeof u->fpsave.junk); + fpregsave(u->fpsave.reg); + u->p->fpstate = FPactive; + m->fpstate = FPdirty; + } + if(BALU->cr0 != 0xFFFFFFFF) /* balu busy */ + memcpy(balu, BALU, sizeof(Balu)); + else{ + balu->cr0 = 0xFFFFFFFF; + BALU->cr0 = 0xFFFFFFFF; + } +} + +/* + * Restore what save() saves + * + * Save() makes sure that what state points to is long enough + */ +void +restore(Proc *p, uchar *state) +{ + Balu *balu; + + balu = (Balu *)state; + if(p->fpstate != m->fpstate){ + if(p->fpstate == FPinit){ + u->p->fpstate = FPinit; + fprestore(&initfp); + m->fpstate = FPinit; + }else{ + fpregrestore(u->fpsave.reg); + fprestore(&u->fpsave); + m->fpstate = FPdirty; + } + } + if(balu->cr0 != 0xFFFFFFFF) /* balu busy */ + memcpy(BALU, balu, sizeof balu); +} diff --git a/gnot/mmu.c b/gnot/mmu.c index e1ad023ebe4cc60e37b302d52eec9e095f96c638..8e113030b7400e12d72d98362022436e037f3a26 100644 --- a/gnot/mmu.c +++ b/gnot/mmu.c @@ -27,6 +27,7 @@ mapstack(Proc *p) tlbvirt = USERADDR; tlbphys = PPN(p->upage->pa) | PTEVALID | PTEKERNEL; putkmmu(tlbvirt, tlbphys); + u = (User*)USERADDR; /* * if not a kernel process and this process was not the @@ -150,3 +151,9 @@ kunmap(KMap *k) putkmmu(k->va, INVALIDPTE); unlock(&kmapalloc); } + +void +invalidateu(void) +{ + putkmmu(USERADDR, INVALIDPTE); +} diff --git a/gnot/page.c b/gnot/page.c index a6b3d46bcdf21b40aa1757c924e4b4782c1f9bd7..8ed70149694b956beff472e8a92a6b42908c2bbd 100644 --- a/gnot/page.c +++ b/gnot/page.c @@ -258,6 +258,14 @@ usepage(Page *p, int dolock) unlock(&palloc); } +/* + * Move page to tail of list + */ +void +unusepage(Page *p, int dolock) +{ +} + Orig* lookorig(ulong va, ulong npte, int flag, Chan *c) { diff --git a/gnot/proc.c b/gnot/proc.c deleted file mode 100644 index 28508d25928f0865c7a1abf43cccee35283d0e9b..0000000000000000000000000000000000000000 --- a/gnot/proc.c +++ /dev/null @@ -1,725 +0,0 @@ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "errno.h" - -#include -#include - -struct -{ - Lock; - ulong pid; -}pidalloc; - -struct -{ - Lock; - Proc *arena; - Proc *free; -}procalloc; - -struct -{ - Lock; - Proc *head; - Proc *tail; -}runq; - -char *statename[]={ /* BUG: generate automatically */ - "Dead", - "Moribund", - "Zombie", - "Ready", - "Scheding", - "Running", - "Queueing", - "MMUing", - "Exiting", - "Inwait", - "Wakeme", - "Broken", -}; - -int page_alloc(int); /* !ORIG */ -void page_free(int, int); - -/* - * Called as the last routine in main(). Wait for a process on the run queue, grab it, - * and run it. Note that in this routine the interrupts are enabled for the first time. - */ -void -schedinit(void) /* never returns */ -{ - Proc *p; - - /* - * At init time: wait for a process on the run queue. - */ - for(;;){ - spllo(); - while (runq.head == 0) - /* idle loop */; - splhi(); - lock(&runq); - if(runq.head != 0) - break; - unlock(&runq); - } - - /* - * Set the u pointer and leave it there. In fact, it might as well be a define. - */ - u = (User *) USERADDR; - - /* - * For later rescheduling. Jumped to by sched() on stack switch. - */ - setlabel(&m->sched); - - /* - * Take a process from the run queue. The run queue is locked here, and guaranteed - * to have a process on it. - */ - p = runq.head; - if((runq.head = p->rnext) == 0) - runq.tail = 0; - unlock(&runq); - - /* - * Ok, here we go. We have a process and we can start running. - */ - mapstack(p); - gotolabel(&p->sched); -} - -/* - * Complete the restoring of a process after mapstack(). The interrupt level here is low. - * However, since the process is not Running, it cannot be rescheduled at this point. We - * set the process state to Running. If the previous process was dead, clean it up. - */ -void -restore(void) -{ - Proc *p = m->proc; /* previous process */ - - u->p->mach = m; - m->proc = u->p; - u->p->state = Running; - if(p->state == Moribund){ - p->pid = 0; - unlock(&p->debug); /* set in pexit */ - p->upage->ref--; - p->upage = 0; - p->qnext = procalloc.free; - procalloc.free = p; - unlock(&procalloc); /* set in pexit */ - p->state = Dead; - } -} - -/* - * Save part of the process state. Note: this is not the counterpart of restore(). - */ -void -save(Balu *balu) -{ - fpsave(&u->fpsave); - if(u->fpsave.type){ - if(u->fpsave.size > sizeof u->fpsave.junk) - panic("fpsize %d max %d\n", u->fpsave.size, sizeof u->fpsave.junk); - fpregsave(u->fpsave.reg); - u->p->fpstate = FPactive; - m->fpstate = FPdirty; - } - if(BALU->cr0 != 0xFFFFFFFF) /* balu busy */ - memcpy(balu, BALU, sizeof(Balu)); - else{ - balu->cr0 = 0xFFFFFFFF; - BALU->cr0 = 0xFFFFFFFF; - } -} - -/* - * Reschedule the process. We do not know whether the interrupt level is low or high - * here, but we set it to low in any case. If there is no other process to run, and - * this process is Running, return immediately. If this process is blocked, and there - * is no other process to run, keep spinning until either this process or another - * process becomes runnable. If it was this process, we can return immediately. - */ -void -sched(void) -{ - Proc *p = u->p; - long initfp; - Balu balu; - int saved = 0; - - /* - * Record that the process is spinning instead of blocked. Ready() uses this - * information to decide what to do with the process. - */ - p->spin = 1; - - /* - * Look for a new process to be run. - */ - for (;;){ - spllo(); - - /* - * Idle loop. Return when this process becomes runnable. If nothing else - * to do, start saving some of the process state. - */ - while (runq.head == 0) - if(p->state == Running) - return; - else if(!saved){ - save(&balu); - saved = 1; - } - - /* - * Disable clock interrupts so that there will be no rescheduling in this - * section (on this machine). If there is still a process on the run - * queue, break out of this loop. - */ - splhi(); - lock(&runq); - if(runq.head != 0) - break; - unlock(&runq); - } - p->spin = 0; - - /* - * The first process on the run queue is the process we are going to run. First - * save our state before we jump to schedinit. If this process was running, put - * it on the run queue. - */ - if(p->state == Running){ - p->state = Ready; - p->rnext = 0; - runq.tail->rnext = p; - runq.tail = p; - } - - /* - * Save some process state (if we haven't done that already) and save/restore - * pc and sp. We have to jump to schedinit() because we are going to remap the - * stack. - */ - if(!saved) - save(&balu); - if(setlabel(&p->sched) == 0) - gotolabel(&m->sched); - - /* - * Interrupts are ok now. Note that the process state is still not Running, - * so no rescheduling. - */ - spllo(); - - /* - * Jumped to by schedinit. Restore the process state. - */ - if(p->fpstate != m->fpstate) - if(p->fpstate == FPinit){ - initfp = 0; - fprestore((FPsave *) &initfp); - m->fpstate = FPinit; - } - else{ - fpregrestore(u->fpsave.reg); - fprestore(&u->fpsave); - m->fpstate = FPdirty; - } - if(balu.cr0 != 0xFFFFFFFF) /* balu busy */ - memcpy(BALU, &balu, sizeof balu); - - /* - * Complete restoring the process. - */ - restore(); -} - -void -ready(Proc *p) -{ - int s; - - s = splhi(); - if(p->spin){ - p->state = Running; - splx(s); - return; - } - lock(&runq); - p->rnext = 0; - if(runq.tail) - runq.tail->rnext = p; - else - runq.head = p; - runq.tail = p; - p->state = Ready; - unlock(&runq); - splx(s); -} - -Proc* -newproc(void) -{ - Proc *p; - -loop: - lock(&procalloc); - if(p = procalloc.free){ /* assign = */ - procalloc.free = p->qnext; - p->state = Zombie; - unlock(&procalloc); - p->mach = 0; - p->qnext = 0; - p->nchild = 0; - p->child = 0; - p->exiting = 0; - p->fpstate = FPinit; - p->kp = 0; - memset(p->seg, 0, sizeof p->seg); - lock(&pidalloc); - p->pid = ++pidalloc.pid; - unlock(&pidalloc); - if(p->pid == 0) - panic("pidalloc"); - return p; - } - unlock(&procalloc); - print("no procs\n"); - if(u == 0) - panic("newproc"); - u->p->state = Wakeme; - alarm(1000, wakeme, u->p); - sched(); - goto loop; -} - -void -procinit0(void) /* bad planning - clashes with devproc.c */ -{ - Proc *p; - int i; - - procalloc.free = ialloc(conf.nproc*sizeof(Proc), 0); - procalloc.arena = procalloc.free; - - p = procalloc.free; - for(i=0; iqnext = p+1; - p->qnext = 0; -} - -void -sleep1(Rendez *r, int (*f)(void*), void *arg) -{ - Proc *p; - int s; - - /* - * spl is to allow lock to be called - * at interrupt time. lock is mutual exclusion - */ - s = splhi(); - lock(r); - - /* - * if condition happened, never mind - */ - if((*f)(arg)){ - unlock(r); - splx(s); - return; - } - - /* - * now we are committed to - * change state and call scheduler - */ - p = u->p; - if(r->p) - print("double sleep %lux %d %d\n", r, r->p->pid, p->pid); - p->r = r; - p->wokeup = 0; - p->state = Wakeme; - r->p = p; - unlock(r); -} - -void -sleep(Rendez *r, int (*f)(void*), void *arg) -{ - sleep1(r, f, arg); - sched(); - if(u->p->wokeup){ - u->p->wokeup = 0; - error(Eintr); - } -} - -void -tsleep(Rendez *r, int (*f)(void*), void *arg, int ms) -{ - Alarm *a; - - sleep1(r, f, arg); - a = alarm(ms, twakeme, r); - sched(); - cancel(a); - if(u->p->wokeup){ - u->p->wokeup = 0; - error(Eintr); - } -} - -void -wakeup(Rendez *r) -{ - Proc *p; - int s; - - s = splhi(); - lock(r); - p = r->p; - if(p){ - r->p = 0; - if(p->state != Wakeme) - panic("wakeup: not Wakeme"); - p->r = 0; - ready(p); - } - unlock(r); - splx(s); -} - -void -wakeme(Alarm *a) -{ - ready((Proc*)(a->arg)); - cancel(a); -} - -void -twakeme(Alarm *a) -{ - wakeup((Rendez*)(a->arg)); -} - -int -postnote(Proc *p, int dolock, char *n, int flag) -{ - User *up; - KMap *k; - int s; - Rendez *r; - - if(dolock) - lock(&p->debug); - k = kmap(p->upage); - up = (User*)VA(k); - if(flag!=NUser && (up->notify==0 || up->notified)) - up->nnote = 0; /* force user's hand */ - else if(up->nnote == NNOTE-1){ - kunmap(k); - return 0; - } - strcpy(up->note[up->nnote].msg, n); - up->note[up->nnote++].flag = flag; - kunmap(k); - if(dolock) - unlock(&p->debug); - if(r = p->r){ /* assign = */ - /* wake up */ - s = splhi(); - lock(r); - if(p->r==r && r->p==p){ - r->p = 0; - if(p->state != Wakeme) - panic("postnote wakeup: not Wakeme"); - p->wokeup = 1; - p->r = 0; - ready(p); - } - unlock(r); - splx(s); - } - return 1; -} - -void -pexit(char *s, int freemem) -{ - char status[64]; - ulong mypid; - Proc *p, *c, *k, *l; - Waitmsg w; - int n; - Chan *ch; - ulong *up, *ucp, *wp; - - c = u->p; - mypid = c->pid; - if(s) - strcpy(status, s); - else - status[0] = 0; - if(freemem){ - freesegs(-1); - closepgrp(c->pgrp); - close(u->dot); - } - for(n=0; n<=u->maxfd; n++) - if(ch = u->fd[n]) /* assign = */ - close(ch); - /* - * Any of my children exiting? - */ - while(c->nchild){ - lock(&c->wait.queue); - if(canlock(&c->wait.use)){ /* no child is exiting */ - c->exiting = 1; - unlock(&c->wait.use); - unlock(&c->wait.queue); - break; - }else{ /* must wait for child */ - unlock(&c->wait.queue); - pwait(0); - } - } - - c->time[TReal] = MACHP(0)->ticks - c->time[TReal]; - /* - * Tell my parent - */ - p = c->parent; - if(p == 0) - goto out; - qlock(&p->wait); - lock(&p->wait.queue); - if(p->pid==c->parentpid && !p->exiting){ - w.pid = mypid; - strcpy(w.msg, status); - wp = &w.time[TUser]; - up = &c->time[TUser]; - ucp = &c->time[TCUser]; - *wp++ = TK2MS(*up++ + *ucp++); - *wp++ = TK2MS(*up++ + *ucp ); - *wp = TK2MS(*up ); - p->child = c; - /* - * Pass info through back door, to avoid huge Proc's - */ - p->waitmsg = (((ulong)&w)&(BY2PG-1)); - c->state = Exiting; - if(p->state == Inwait) - ready(p); - unlock(&p->wait.queue); - sched(); - }else{ - unlock(&p->wait.queue); - qunlock(&p->wait); - } - out: - if(!freemem){ - /* - * weird thing: keep at most NBROKEN around - */ - #define NBROKEN 4 - static struct{ - Lock; - int n; - Proc *p[NBROKEN]; - }broken; - int b; - - lock(&broken); - if(broken.n == NBROKEN){ - ready(broken.p[0]); - memcpy(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1)); - --broken.n; - } - broken.p[broken.n++] = c; - unlock(&broken); - c->state = Broken; - sched(); /* until someone lets us go */ - lock(&broken); - for(b=0; bpgrp); - close(u->dot); - } - - done: - - lock(&procalloc); /* sched() can't do this */ - lock(&c->debug); /* sched() can't do this */ - c->state = Moribund; - - /* - * Call the scheduler. This process gets cleaned up in restore() by the next - * process that runs. That means that if there is no other process, we'll - * hang around for a little while. - */ - sched(); /* never returns */ -} - -ulong -pwait(Waitmsg *w) -{ - Proc *c, *p; - KMap *k; - ulong cpid; - - p = u->p; -again: - while(canqlock(&p->wait)){ - if(p->nchild == 0){ - qunlock(&p->wait); - error(Enochild); - } - p->state = Inwait; - qunlock(&p->wait); - sched(); - } - lock(&p->wait.queue); /* wait until child is finished */ - c = p->child; - if(c == 0){ - p->state = Inwait; - unlock(&p->wait.queue); - sched(); - goto again; - } - p->child = 0; - k = kmap(c->upage); - if(w) - *w = *(Waitmsg*)(p->waitmsg|VA(k)); - cpid = ((Waitmsg*)(p->waitmsg|VA(k)))->pid; - kunmap(k); - p->time[TCUser] += c->time[TUser] + c->time[TCUser]; - p->time[TCSys] += c->time[TSys] + c->time[TCSys]; - p->time[TCReal] += c->time[TReal]; - p->nchild--; - unlock(&p->wait.queue); - qunlock(&p->wait); - ready(c); - return cpid; -} - -Proc* -proctab(int i) -{ - return &procalloc.arena[i]; -} - -#include -void -DEBUG(void) -{ - int i; - Proc *p; - - print("DEBUG\n"); - for(i=0; istate != Dead) - print("%d:%s upc %lux %s ut %ld st %ld q %lux r %lux\n", - p->pid, p->text, p->pc, statename[p->state], - p->time[0], p->time[1], p->qlock, p->r); - } -} - -/* - * create a kernel process. if func is nonzero put the process in the kernel - * process group, have it call func, and exit. - * - * otherwise, the new process stays in the same process group and returns. - */ -Proc * -kproc(char *name, void (*func)(void *), void *arg) -{ - Proc *p; - Chan *c; - int n; - ulong upa; - int lastvar; /* used to compute stack address */ - User *up; - KMap *k; - static Pgrp *kpgrp; - - /* - * Kernel stack - */ - p = newproc(); - p->kp = 1; - p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); - k = kmap(p->upage); - upa = VA(k); - up = (User*)upa; - - /* - * Save time: only copy u-> data and useful stack - */ - clearmmucache(); - memcpy(up, u, sizeof(User)); - n = USERADDR+BY2PG - (ulong)&lastvar; - n = (n+32) & ~(BY2WD-1); /* be safe & word align */ - memcpy((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n); - - /* - * Refs - */ - incref(up->dot); - for(n=0; n<=up->maxfd; n++) - if(func) - up->fd[n] = 0; - else if(c = u->fd[n]) /* assign = */ - incref(c); - if(!func) - up->maxfd = 0; - up->p = p; - kunmap(k); - - /* - * Sched - */ - if(setlabel(&p->sched)){ - restore(); - if(func){ - (*func)(arg); - pexit(0, 1); - } else - return 0; - } - if(func){ - if(kpgrp == 0){ - kpgrp = newpgrp(); - strcpy(kpgrp->user, "bootes"); - } - p->pgrp = kpgrp; - } else - p->pgrp = u->p->pgrp; - incref(p->pgrp); - sprint(p->text, "%s.%.6s", name, u->p->pgrp->user); - p->nchild = 0; - p->parent = 0; - memset(p->time, 0, sizeof(p->time)); - p->time[TReal] = MACHP(0)->ticks; - ready(p); - flushmmu(); - return p; -} diff --git a/gnot/sysproc.c b/gnot/sysproc.c deleted file mode 100644 index df6fb6b55a2c3fecea42f9f5a5b50fb14a41affb..0000000000000000000000000000000000000000 --- a/gnot/sysproc.c +++ /dev/null @@ -1,514 +0,0 @@ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "ureg.h" -#include "errno.h" - -#include - -int shargs(char*, int, char**); - -long -sysr1(ulong *arg) -{ - print("[%d] r1 = %d\n", u->p->pid, arg[0]); - return 0; -} - -long -sysfork(ulong *arg) -{ - Proc *p; - Seg *s; - Page *np, *op; - ulong usp, upa, pid; - Chan *c; - Orig *o; - KMap *k; - int n, on, i; - int lastvar; /* used to compute stack address */ - - /* - * Kernel stack - */ - p = newproc(); - p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); - k = kmap(p->upage); - upa = VA(k); - - /* - * Save time: only copy u-> data and useful stack - */ - clearmmucache(); - memcpy((void*)upa, u, sizeof(User)); - n = USERADDR+BY2PG - (ulong)&lastvar; - n = (n+32) & ~(BY2WD-1); /* be safe & word align */ - memcpy((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n); - ((User *)upa)->p = p; - kunmap(k); - - /* - * User stack - */ - p->seg[SSEG] = u->p->seg[SSEG]; - s = &p->seg[SSEG]; - s->proc = p; - on = (s->maxva-s->minva)>>PGSHIFT; - usp = ((Ureg*)UREGADDR)->usp; - if(usp >= USTKTOP) - panic("fork bad usp %lux", usp); - if(usp < u->p->seg[SSEG].minva) - s->minva = u->p->seg[SSEG].minva; - else - s->minva = usp & ~(BY2PG-1); - usp = s->minva & (BY2PG-1); /* just low bits */ - s->maxva = USTKTOP; - n = (s->maxva-s->minva)>>PGSHIFT; - s->o = neworig(s->minva, n, OWRPERM, 0); - lock(s->o); - /* - * Only part of last stack page - */ - for(i=0; ip->seg[SSEG].o->pte[i+(on-n)].page; - if(op){ - np = newpage(1, s->o, op->va); - k = kmap(np); - p->seg[SSEG].o->pte[i].page = np; - if(i == 0){ /* only part of last stack page */ - memset((void*)VA(k), 0, usp); - memcpy((void*)(VA(k)+usp), - (void*)(op->va+usp), BY2PG-usp); - }else /* all of higher pages */ - memcpy((void*)VA(k), (void*)op->va, BY2PG); - kunmap(k); - } - } - unlock(s->o); - /* - * Duplicate segments - */ - for(s=&u->p->seg[0], n=0; no == 0) - continue; - p->seg[n] = *s; - p->seg[n].proc = p; - o = s->o; - lock(o); - o->nproc++; - if(s->mod) - forkmod(s, &p->seg[n], p); - unlock(o); - } - /* - * Refs - */ - incref(u->dot); - for(n=0; n<=u->maxfd; n++) - if(c = u->fd[n]) /* assign = */ - incref(c); - /* - * Sched - */ - if(setlabel(&p->sched)){ - clearmmucache(); - restore(); - return 0; - } - p->parent = u->p; - p->parentpid = u->p->pid; - p->pgrp = u->p->pgrp; - incref(p->pgrp); - u->p->nchild++; - pid = p->pid; - memset(p->time, 0, sizeof(p->time)); - p->time[TReal] = MACHP(0)->ticks; - memcpy(p->text, u->p->text, NAMELEN); - ready(p); - flushmmu(); - clearmmucache(); - return pid; -} - -long -sysexec(ulong *arg) -{ - Proc *p; - Seg *s; - ulong l, t, d, b, v; - int i; - Chan *tc, *c; - Orig *o; - char **argv, **argp; - char *a, *charp, *file; - long fpnull = 0; - char *progarg[sizeof(Exec)/2+1], elem[NAMELEN]; - ulong ssize, spage, nargs, nbytes, n, bssend; - ulong *sp; - int indir; - Exec exec; - char line[sizeof(Exec)]; - - p = u->p; - validaddr(arg[0], 1, 0); - file = (char*)arg[0]; - indir = 0; - Header: - tc = namec(file, Aopen, OEXEC, 0); - if(waserror()){ - close(tc); - nexterror(); - } - if(!indir) - strcpy(elem, u->elem); - n = (*devtab[tc->type].read)(tc, &exec, sizeof(Exec)); - if(n < 2) - Err: - error(Ebadexec); - if(n==sizeof(Exec) && exec.magic==A_MAGIC){ - if((exec.text&KZERO) - || (ulong)exec.entry < UTZERO+sizeof(Exec) - || (ulong)exec.entry >= UTZERO+sizeof(Exec)+exec.text) - goto Err; - goto Binary; - } - - /* - * Process #! /bin/sh args ... - */ - memcpy(line, &exec, sizeof(Exec)); - if(indir || line[0]!='#' || line[1]!='!') - goto Err; - n = shargs(line, n, progarg); - if(n == 0) - goto Err; - indir = 1; - /* - * First arg becomes complete file name - */ - progarg[n++] = file; - progarg[n] = 0; - validaddr(arg[1], BY2WD, 1); - arg[1] += BY2WD; - file = progarg[0]; - progarg[0] = elem; - close(tc); - poperror(); - goto Header; - - Binary: - t = (UTZERO+sizeof(Exec)+exec.text+(BY2PG-1)) & ~(BY2PG-1); - d = (t + exec.data + (BY2PG-1)) & ~(BY2PG-1); - bssend = t + exec.data + exec.bss; - b = (bssend + (BY2PG-1)) & ~(BY2PG-1); - if((t|d|b) & KZERO) - error(Ebadexec); - - /* - * Args: pass 1: count - */ - nbytes = 0; - nargs = 0; - if(indir){ - argp = progarg; - while(*argp){ - a = *argp++; - nbytes += strlen(a) + 1; - nargs++; - } - } - evenaddr(arg[1]); - argp = (char**)arg[1]; - validaddr((ulong)argp, BY2WD, 0); - while(*argp){ - a = *argp++; - if(((ulong)argp&(BY2PG-1)) < BY2WD) - validaddr((ulong)argp, BY2WD, 0); - validaddr((ulong)a, 1, 0); - nbytes += (vmemchr(a, 0, 0xFFFFFFFF) - a) + 1; - nargs++; - } - ssize = BY2WD*(nargs+1) + ((nbytes+(BY2WD-1)) & ~(BY2WD-1)); - spage = (ssize+(BY2PG-1)) >> PGSHIFT; - - /* - * Build the stack segment, putting it in kernel virtual for the moment - */ - s = &p->seg[ESEG]; - s->proc = p; - s->o = neworig(TSTKTOP-(spage<minva = s->o->va; - s->maxva = TSTKTOP; - - /* - * Args: pass 2: assemble; the pages will be faulted in - */ - argv = (char**)(TSTKTOP - ssize); - charp = (char*)(TSTKTOP - nbytes); - if(indir) - argp = progarg; - else - argp = (char**)arg[1]; - for(i=0; itext, elem, NAMELEN); - - /* - * Committed. Free old memory - */ - freesegs(ESEG); - - /* - * Close on exec - */ - for(i=0; i<=u->maxfd; i++) - if((c=u->fd[i]) && c->flag&CCEXEC){ - close(c); - fdclose(i); - } - - /* - * Text. Shared. - */ - s = &p->seg[TSEG]; - s->proc = p; - o = lookorig(UTZERO, (t-UTZERO)>>PGSHIFT, OCACHED, tc); - if(o == 0){ - o = neworig(UTZERO, (t-UTZERO)>>PGSHIFT, OCACHED, tc); - o->minca = 0; - o->maxca = sizeof(Exec)+exec.text; - } - s->o = o; - s->minva = UTZERO; - s->maxva = t; - s->mod = 0; - - /* - * Data. Shared. - */ - s = &p->seg[DSEG]; - s->proc = p; - o = lookorig(t, (d-t)>>PGSHIFT, OWRPERM|OPURE|OCACHED, tc); - if(o == 0){ - o = neworig(t, (d-t)>>PGSHIFT, OWRPERM|OPURE|OCACHED, tc); - o->minca = p->seg[TSEG].o->maxca; - o->maxca = o->minca + exec.data; - } - s->o = o; - s->minva = t; - s->maxva = d; - s->mod = 0; - - /* - * BSS. Created afresh. - */ - s = &p->seg[BSEG]; - s->proc = p; - o = neworig(d, (b-d)>>PGSHIFT, OWRPERM, 0); - o->minca = 0; - o->maxca = 0; - s->o = o; - s->minva = d; - s->maxva = b; - s->mod = 0; - - close(tc); - - p->bssend = bssend; - - /* - * Move the stack - */ - s = &p->seg[SSEG]; - *s = p->seg[ESEG]; - p->seg[ESEG].o = 0; - o = s->o; - o->va += (USTKTOP-TSTKTOP); - s->minva = o->va; - s->maxva = USTKTOP; - lock(o); - for(i=0; inpte; i++) - o->pte[i].page->va += (USTKTOP-TSTKTOP); - unlock(o); - - flushmmu(); - clearmmucache(); - ((Ureg*)UREGADDR)->pc = exec.entry; - sp = (ulong*)(USTKTOP - ssize); - *--sp = nargs; - ((Ureg*)UREGADDR)->usp = (ulong)sp; - lock(&p->debug); - u->nnote = 0; - u->notify = 0; - u->notified = 0; - splhi(); - m->fpstate = FPinit; - p->fpstate = FPinit; - fprestore((FPsave*)&fpnull); - spllo(); - unlock(&p->debug); - return 0; -} - -int -shargs(char *s, int n, char **ap) -{ - int i; - - s += 2, n -= 2; /* skip #! */ - for(i=0; s[i]!='\n'; i++) - if(i == n-1) - return 0; - s[i] = 0; - *ap = 0; - i = 0; - for(;;){ - while(*s==' ' || *s=='\t') - s++; - if(*s == 0) - break; - i++; - *ap++ = s; - *ap = 0; - while(*s && *s!=' ' && *s!='\t') - s++; - if(*s == 0) - break; - else - *s++ = 0; - } - return i; -} - -int -return0(void *a) -{ - return 0; -} - -long -syssleep(ulong *arg) -{ - tsleep(&u->p->sleep, return0, 0, arg[0]); - return 0; -} - - -long -sysexits(ulong *arg) -{ - char *status; - - status = (char*)arg[0]; - if(status){ - if(waserror()) - status = "invalid exit string"; - else{ - validaddr((ulong)status, 1, 0); - vmemchr(status, 0, ERRLEN); - } - } - pexit(status, 1); -} - -long -syswait(ulong *arg) -{ - if(arg[0]){ - validaddr(arg[0], sizeof(Waitmsg), 1); - evenaddr(arg[0]); - } - return pwait((Waitmsg*)arg[0]); -} - -long -sysdeath(ulong *arg) -{ - pprint("deprecated system call"); - pexit("Suicide", 0); -} - -long -syserrstr(ulong *arg) -{ - char buf[ERRLEN]; - - validaddr(arg[0], ERRLEN, 1); - memcpy((char*)arg[0], u->error, ERRLEN); - return 0; -} - -long -sysforkpgrp(ulong *arg) -{ - Pgrp *pg; - - pg = newpgrp(); - if(waserror()){ - closepgrp(pg); - nexterror(); - } - if(arg[0] == 0) - pgrpcpy(pg, u->p->pgrp); - else - memcpy(pg->user, u->p->pgrp->user, NAMELEN); - closepgrp(u->p->pgrp); - u->p->pgrp = pg; - return pg->pgrpid; -} - -long -sysnotify(ulong *arg) -{ - validaddr(arg[0], sizeof(ulong), 0); - u->notify = (int(*)(void*, char*))(arg[0]); - return 0; -} - -long -sysnoted(ulong *arg) -{ - if(u->notified == 0) - error(Egreg); - return 0; -} - -/* - * Temporary; should be replaced by a generalized segment control operator - */ -long -sysbrk_(ulong *arg) -{ - ulong addr; - Seg *s; - - addr = arg[0]; - if(addr < u->p->bssend){ - pprint("addr below bss\n"); - pexit("Suicide", 0); - error(Esegaddr); - } - if(addr <= ((u->p->bssend+(BY2PG-1))&~(BY2PG-1))) /* still in DSEG */ - goto Return; - if(segaddr(&u->p->seg[BSEG], u->p->seg[BSEG].minva, arg[0]) == 0){ - pprint("bad segaddr in brk\n"); - pexit("Suicide", 0); - error(Esegaddr); - } - Return: - u->p->bssend = addr; - return 0; -} diff --git a/port/alarm.c b/port/alarm.c new file mode 100644 index 0000000000000000000000000000000000000000..bc3880af9c2f119142f9a022b5ea9173d8ec2413 --- /dev/null +++ b/port/alarm.c @@ -0,0 +1,108 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" + +Alarm *alarmtab; + +Alarm* +alarm(int ms, void (*f)(Alarm*), void *arg) +{ + Alarm *a, *w, *pw; + ulong s; + if(ms < 0) + ms = 0; + a = newalarm(); + a->dt = MS2TK(ms); + a->f = f; + a->arg = arg; + s = splhi(); + lock(&m->alarmlock); + pw = 0; + for(w=m->alarm; w; pw=w, w=w->next){ + if(w->dt <= a->dt){ + a->dt -= w->dt; + continue; + } + w->dt -= a->dt; + break; + } + insert(&m->alarm, pw, a); + unlock(&m->alarmlock); + splx(s); + return a; +} + +void +cancel(Alarm *a) +{ + a->f = 0; +} + +Alarm* +newalarm(void) +{ + int i; + Alarm *a; + + for(i=0,a=alarmtab; ibusy==0 && a->f==0 && canlock(a)){ + if(a->busy){ + unlock(a); + continue; + } + a->f = 0; + a->arg = 0; + a->busy = 1; + unlock(a); + return a; + } + panic("newalarm"); +} + +void +alarminit(void) +{ + int i; + + alarmtab = ialloc(conf.nalarm*sizeof(Alarm), 0); + for(i=0; ialarmlock)){ + a = m->alarm; + if(a){ + for(n=0; a && a->dt<=0 && nalarm, 0, a); + a = m->alarm; + } + if(a) + a->dt--; + unlock(&m->alarmlock); + + /* execute alarm functions outside the lock */ + for(i = 0; i < n; i++){ + f = alist[i]->f; /* avoid race with cancel */ + if(f) + (*f)(alist[i]); + alist[i]->busy = 0; + } + } else + unlock(&m->alarmlock); + } +} diff --git a/port/page.c b/port/page.c index ae9d6fefb49c3c6019f79f64705fa51f5cae9358..e7695ecc80759f150fe2221cf97b413a4bc7cc90 100644 --- a/port/page.c +++ b/port/page.c @@ -70,6 +70,8 @@ ialloc(ulong n, int align) palloc.addr += BY2PG-1; palloc.addr &= ~(BY2PG-1); } + if(palloc.addr >= conf.maxialloc) + panic("keep bill joy away"); return (void*)(p|KZERO); } @@ -151,7 +153,10 @@ pageinit(void) for(p=palloc.head; p<=palloc.tail; p++,ppn++){ p->next = p+1; p->prev = p-1; - p->pa = ppn<pa = conf.base0+(ppn<pa = conf.base1+((ppn-conf.npage0)<prev = 0; palloc.tail->next = 0; diff --git a/port/proc.c b/port/proc.c index c0eed779a045fcfa622a32e940282fc8e5ac4354..23d32889af7e8eb19dae2fc7d9833dc499faeac5 100644 --- a/port/proc.c +++ b/port/proc.c @@ -52,7 +52,7 @@ schedinit(void) /* never returns */ if(u){ m->proc = 0; p = u->p; - puttlbx(0, KZERO | PTEPID(0), 0); /* safety first */ + invalidateu(); /* safety first */ u = 0; if(p->state == Running) ready(p); @@ -76,17 +76,20 @@ schedinit(void) /* never returns */ void sched(void) { + uchar procstate[64]; /* sleeze for portability */ Proc *p; ulong tlbvirt, tlbphys; void (*f)(ulong, ulong); if(u){ splhi(); + save(procstate, sizeof(procstate)); if(setlabel(&u->p->sched)){ /* woke up */ p = u->p; p->state = Running; p->mach = m; m->proc = p; + restore(p, procstate); spllo(); return; } @@ -132,7 +135,7 @@ runproc(void) loop: while(runq.head == 0) - for(i=0; i<10; i++) + for(i=0; i<10; i++) /* keep out of shared memory for a while */ ; splhi(); lock(&runq); @@ -573,6 +576,7 @@ kproc(char *name, void (*func)(void *), void *arg) /* * Save time: only copy u-> data and useful stack */ + clearmmucache(); memcpy(up, u, sizeof(User)); n = USERADDR+BY2PG - (ulong)&lastvar; n = (n+32) & ~(BY2WD-1); /* be safe & word align */ diff --git a/port/sysproc.c b/port/sysproc.c index 2213524629cd442fb105936ffd6c223885974010..ae2c7f05d747e025ed6111b762c6ad68b610a63e 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -41,6 +41,7 @@ sysfork(ulong *arg) /* * Save time: only copy u-> data and useful stack */ + clearmmucache(); memcpy((void*)upa, u, sizeof(User)); n = USERADDR+BY2PG - (ulong)&lastvar; n = (n+32) & ~(BY2WD-1); /* be safe & word align */ @@ -114,6 +115,7 @@ sysfork(ulong *arg) * Sched */ if(setlabel(&p->sched)){ + clearmmucache(); u->p = p; p->state = Running; p->mach = m; @@ -132,6 +134,7 @@ sysfork(ulong *arg) memcpy(p->text, u->p->text, NAMELEN); ready(p); flushmmu(); + clearmmucache(); return pid; } @@ -147,7 +150,7 @@ sysexec(ulong *arg) char **argv, **argp; char *a, *charp, *file; char *progarg[sizeof(Exec)/2+1], elem[NAMELEN]; - ulong ssize, spage, nargs, nbytes, n; + ulong ssize, spage, nargs, nbytes, n, bssend; ulong *sp; int indir; Exec exec; @@ -169,7 +172,7 @@ sysexec(ulong *arg) if(n < 2) Err: error(Ebadexec); - if(n==sizeof(Exec) && exec.magic==V_MAGIC){ + if(n==sizeof(Exec) && exec.magic==AOUT_MAGIC){ if((exec.text&KZERO) || (ulong)exec.entry < UTZERO+sizeof(Exec) || (ulong)exec.entry >= UTZERO+sizeof(Exec)+exec.text) @@ -206,7 +209,8 @@ sysexec(ulong *arg) * Last partial page of data goes into BSS. */ d = (t + exec.data) & ~(BY2PG-1); - b = (t + exec.data + exec.bss + (BY2PG-1)) & ~(BY2PG-1); + bssend = t + exec.data + exec.bss; + b = (bssend + (BY2PG-1)) & ~(BY2PG-1); if((t|d|b) & KZERO) error(Ebadexec); @@ -331,6 +335,8 @@ sysexec(ulong *arg) close(tc); + p->bssend = bssend; + /* * Move the stack */ @@ -347,7 +353,8 @@ sysexec(ulong *arg) unlock(o); flushmmu(); - ((Ureg*)UREGADDR)->pc = exec.entry - 4; + clearmmucache(); + ((Ureg*)UREGADDR)->pc = exec.entry + ENTRYOFFSET; sp = (ulong*)(USTKTOP - ssize); *--sp = nargs; ((Ureg*)UREGADDR)->usp = (ulong)sp; @@ -355,6 +362,7 @@ sysexec(ulong *arg) u->nnote = 0; u->notify = 0; u->notified = 0; + setup(p); unlock(&p->debug); return 0; } @@ -488,7 +496,25 @@ sysnoted(ulong *arg) long sysbrk_(ulong *arg) { - if(segaddr(&u->p->seg[BSEG], u->p->seg[BSEG].minva, arg[0]) == 0) + ulong addr; + Seg *s; + + addr = arg[0]; +#ifdef WHYROB + if(addr < u->p->bssend){ + pprint("addr below bss\n"); + pexit("Suicide", 0); error(Esegaddr); + } +#endif WHYROB + if(addr <= ((u->p->bssend+(BY2PG-1))&~(BY2PG-1))) /* still in DSEG */ + goto Return; + if(segaddr(&u->p->seg[BSEG], u->p->seg[BSEG].minva, arg[0]) == 0){ + pprint("bad segaddr in brk\n"); + pexit("Suicide", 0); + error(Esegaddr); + } + Return: + u->p->bssend = addr; return 0; } diff --git a/power/clock.c b/power/clock.c index 802ba629feb8a50071e3d0ded46d9dc9260313a4..540b049fed104dcf0e92d9c42950db57305abe36 100644 --- a/power/clock.c +++ b/power/clock.c @@ -7,75 +7,6 @@ #include "ureg.h" -Alarm *alarmtab; - -Alarm* -alarm(int ms, void (*f)(Alarm*), void *arg) -{ - Alarm *a, *w, *pw; - ulong s; - if(ms < 0) - ms = 0; - a = newalarm(); - a->dt = MS2TK(ms); - a->f = f; - a->arg = arg; - s = splhi(); - lock(&m->alarmlock); - pw = 0; - for(w=m->alarm; w; pw=w, w=w->next){ - if(w->dt <= a->dt){ - a->dt -= w->dt; - continue; - } - w->dt -= a->dt; - break; - } - insert(&m->alarm, pw, a); - unlock(&m->alarmlock); - splx(s); - return a; -} - -void -cancel(Alarm *a) -{ - a->f = 0; -} - -Alarm* -newalarm(void) -{ - int i; - Alarm *a; - - for(i=0,a=alarmtab; ibusy==0 && a->f==0 && canlock(a)){ - if(a->busy){ - unlock(a); - continue; - } - a->f = 0; - a->arg = 0; - a->busy = 1; - unlock(a); - return a; - } - panic("newalarm"); -} - -void -alarminit(void) -{ - int i; - - alarmtab = ialloc(conf.nalarm*sizeof(Alarm), 0); - for(i=0; ialarmlock)){ - a = m->alarm; - if(a){ - for(n=0; a && a->dt<=0 && nalarm, 0, a); - a = m->alarm; - } - if(a) - a->dt--; - unlock(&m->alarmlock); - - /* execute alarm functions outside the lock */ - for(i = 0; i < n; i++){ - f = alist[i]->f; /* avoid race with cancel */ - if(f) - (*f)(alist[i]); - alist[i]->busy = 0; - } - } else - unlock(&m->alarmlock); - } + checkalarms(); return; } if(n & INTR4){ diff --git a/power/conf.h b/power/conf.h index 5dc87296cbc5722073d4feb8d395c73ddee18346..b2f150c02ce0cac454f236d9dd96b6f005d852be 100644 --- a/power/conf.h +++ b/power/conf.h @@ -26,6 +26,9 @@ Conftab conftab[] = { {"nurp", &conf.nurp }, {"nasync", &conf.nasync }, {"npipe", &conf.npipe }, + {"maxialloc", &conf.maxialloc }, + {"base0", &conf.base0 }, + {"base1", &conf.base1 }, { 0, 0 }, }; diff --git a/power/dat.h b/power/dat.h index a9d0e6e4a8a00bcf2af7d36a0c50095d5c1ff3f7..e307035e81b6b2bf67de07da3d8091b52e7cdc32 100644 --- a/power/dat.h +++ b/power/dat.h @@ -149,6 +149,9 @@ struct Conf ulong nurp; /* max urp conversations */ ulong nasync; /* number of async protocol modules */ ulong npipe; /* number of pipes */ + ulong maxialloc; /* maximum bytes used by ialloc */ + ulong base0; /* base of bank 0 */ + ulong base1; /* base of bank 1 */ }; struct Dev @@ -315,6 +318,7 @@ struct Proc short pidonmach[MAXMACH]; /* TLB pid on each mmu */ Page *upage; /* BUG: should be unlinked from page list */ Seg seg[NSEG]; + ulong bssend; /* initial top of bss seg */ ulong pid; int nchild; QLock wait; /* exiting children to be waited for */ @@ -698,3 +702,8 @@ extern Dev devtab[]; extern char devchar[]; extern FPsave initfp; +/* + * parameters for sysproc.c + */ +#define AOUT_MAGIC V_MAGIC +#define ENTRYOFFSET (-4) diff --git a/power/fns.h b/power/fns.h index 8b3a614b33f8203248364405a043128f6ec970cb..ee4a8ab4e669c4ac53b1ceb0403c8faedec5b805 100644 --- a/power/fns.h +++ b/power/fns.h @@ -9,12 +9,14 @@ int canqlock(QLock*); void chaninit(void); void chandevreset(void); void chandevinit(void); +void checkalarms(void); void clock(ulong, ulong); void clockinit(void); Chan *clone(Chan*, Chan*); void close(Chan*); void closemount(Mount*); void closepgrp(Pgrp*); +void clearmmucache(void); long clrfpintr(void); int compactpte(Orig*, ulong); ulong confeval(char*); @@ -81,6 +83,7 @@ void icflush(void *, int); int incref(Ref*); void insert(List**, List*, List*); void intr(ulong, ulong); +void invalidateu(void); void ioboardinit(void); void isdir(Chan*); void kbdchar(int); @@ -152,9 +155,11 @@ int readnum(ulong, char*, ulong, ulong, int); void ready(Proc*); void qlock(QLock*); void qunlock(QLock*); +void restore(Proc*, uchar*); void restfpregs(FPsave*); int return0(void*); Proc *runproc(void); +void save(uchar*, int); void savefpregs(FPsave*); void sched(void); void schedinit(void); @@ -162,6 +167,7 @@ long seconds(void); Seg *seg(Proc*, ulong); int segaddr(Seg*, ulong, ulong); int setlabel(Label*); +void setup(Proc*); void setvmevec(int, void (*)(int)); void sinit(void); char* skipslash(char*); diff --git a/power/main.c b/power/main.c index ab736c07178973b0c3935f4a5ed9eebed46f56d9..7225ba25baf0fe8f1cf4d455e8d35540ebfc2383 100644 --- a/power/main.c +++ b/power/main.c @@ -590,7 +590,9 @@ confinit(void) x += 0x3141526; } conf.npage0 = i*1024/4; + conf.base0 = 0; conf.npage = conf.npage0; + conf.maxialloc = (128*1024*1024-256*1024-BY2PG); /* * clear MP bus error caused by sizing memory @@ -693,3 +695,27 @@ arginit(void) _argv = argv; argsize = ssize; } + +/* + * set up machine dependent process state for a new process + */ +void +setup(Proc *p) +{ +} + +/* + * Save machine dependent process state + */ +void +save(uchar *state, int len) +{ +} + +/* + * Restore what save() saves + */ +void +restore(Proc *p, uchar *state) +{ +} diff --git a/power/mmu.c b/power/mmu.c index fc9a724677e05f0866d40b99cdec3cfa4238f083..2bd400ab06cd50d14cffcfb68a5052b05e7fbbdd 100644 --- a/power/mmu.c +++ b/power/mmu.c @@ -101,3 +101,14 @@ flushmmu(void) mapstack(u->p); spllo(); } + +void +clearmmucache(void) +{ +} + +void +invalidateu(void) +{ + puttlbx(0, KZERO | PTEPID(0), 0); +}