M gnot/clock.c => gnot/clock.c +1 -96
@@ 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; i<conf.nalarm; i++,a++)
- if(a->busy==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; i<conf.nalarm; i++){
- lock(&alarmtab[i]); /* allocate locks, as they are used at interrupt time */
- unlock(&alarmtab[i]);
- }
-}
-
void
delay(int ms)
{
@@ 87,15 18,10 @@ delay(int ms)
;
}
-#define NA 10
void
clock(Ureg *ur)
{
- int i, n;
- Alarm *a;
- void (*f)(void*);
Proc *p;
- Alarm *alist[NA];
SYNCREG[1] = 0x5F; /* clear interrupt */
m->ticks++;
@@ 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 && n<NA; n++){
- alist[n] = a;
- delete(&m->alarm, 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){
M gnot/dat.h => gnot/dat.h +11 -0
@@ 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
M gnot/fns.h => gnot/fns.h +8 -3
@@ 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);
M gnot/main.c => gnot/main.c +80 -2
@@ 7,6 7,9 @@
#include "ureg.h"
#include "init.h"
+#include <libg.h>
+#include <gnot.h>
+
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);
+}
M gnot/mmu.c => gnot/mmu.c +7 -0
@@ 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);
+}
M gnot/page.c => gnot/page.c +8 -0
@@ 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)
{
D gnot/proc.c => gnot/proc.c +0 -725
@@ 1,725 0,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "errno.h"
-
-#include <libg.h>
-#include <gnot.h>
-
-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; i<conf.nproc-1; i++,p++)
- p->qnext = 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; b<NBROKEN; b++)
- if(broken.p[b] == c){
- broken.n--;
- memcpy(&broken.p[b], &broken.p[b+1], sizeof(Proc*)*(NBROKEN-(b+1)));
- break;
- }
- unlock(&broken);
- freesegs(-1);
- closepgrp(c->pgrp);
- 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 <ureg.h>
-void
-DEBUG(void)
-{
- int i;
- Proc *p;
-
- print("DEBUG\n");
- for(i=0; i<conf.nproc; i++){
- p = procalloc.arena+i;
- if(p->state != 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;
-}
D gnot/sysproc.c => gnot/sysproc.c +0 -514
@@ 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 <a.out.h>
-
-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; i<n; i++){
- op = u->p->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; n<NSEG; n++, s++){
- if(n == SSEG) /* already done */
- continue;
- if(s->o == 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<<PGSHIFT), spage, OWRPERM, 0);
- s->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; i<nargs; i++){
- if(indir && *argp==0){
- indir = 0;
- argp = (char**)arg[1];
- }
- *argv++ = charp + (USTKTOP-TSTKTOP);
- n = strlen(*argp) + 1;
- memcpy(charp, *argp++, n);
- charp += n;
- }
-
- memcpy(p->text, 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; i<o->npte; 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;
-}
A port/alarm.c => port/alarm.c +108 -0
@@ 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; i<conf.nalarm; i++,a++)
+ if(a->busy==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; i<conf.nalarm; i++){
+ lock(&alarmtab[i]); /* allocate locks, as they are used at interrupt time */
+ unlock(&alarmtab[i]);
+ }
+}
+
+#define NA 10 /* alarms per clock tick */
+void
+checkalarms(void)
+{
+ int i, n;
+ Alarm *a;
+ void (*f)(void*);
+ Alarm *alist[NA];
+
+ if(canlock(&m->alarmlock)){
+ a = m->alarm;
+ if(a){
+ for(n=0; a && a->dt<=0 && n<NA; n++){
+ alist[n] = a;
+ delete(&m->alarm, 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);
+ }
+}
M port/page.c => port/page.c +6 -1
@@ 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<<PGSHIFT;
+ if(ppn < conf.npage0)
+ p->pa = conf.base0+(ppn<<PGSHIFT);
+ else
+ p->pa = conf.base1+((ppn-conf.npage0)<<PGSHIFT);
}
palloc.head->prev = 0;
palloc.tail->next = 0;
M port/proc.c => port/proc.c +6 -2
@@ 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 */
M port/sysproc.c => port/sysproc.c +31 -5
@@ 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;
}
M power/clock.c => power/clock.c +2 -96
@@ 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; i<conf.nalarm; i++,a++)
- if(a->busy==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; i<conf.nalarm; i++){
- lock(&alarmtab[i]); /* allocate locks, as they are used at interrupt time */
- unlock(&alarmtab[i]);
- }
-}
-
void
delay(int ms)
{
@@ 147,15 78,11 @@ clockinit(void)
-#define NA 10
void
clock(ulong n, ulong pc)
{
- int i, na;
- Alarm *a;
- void (*f)(void*);
+ int i;
Proc *p;
- Alarm *alist[NA];
if(n&INTR2){
i = *CLRTIM0;
@@ 180,28 107,7 @@ clock(ulong n, ulong pc)
print("someone's exiting\n");
exit();
}
- if(canlock(&m->alarmlock)){
- a = m->alarm;
- if(a){
- for(n=0; a && a->dt<=0 && n<NA; n++){
- alist[n] = a;
- delete(&m->alarm, 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){
M power/conf.h => power/conf.h +3 -0
@@ 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 },
};
M power/dat.h => power/dat.h +9 -0
@@ 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)
M power/fns.h => power/fns.h +6 -0
@@ 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*);
M power/main.c => power/main.c +26 -0
@@ 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)
+{
+}
M power/mmu.c => power/mmu.c +11 -0
@@ 101,3 101,14 @@ flushmmu(void)
mapstack(u->p);
spllo();
}
+
+void
+clearmmucache(void)
+{
+}
+
+void
+invalidateu(void)
+{
+ puttlbx(0, KZERO | PTEPID(0), 0);
+}