summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--defs.h1
-rw-r--r--exec.c15
-rw-r--r--proc.c101
-rw-r--r--proc.h3
-rw-r--r--syscall.c23
-rw-r--r--sysfile.c12
-rw-r--r--vm.c4
7 files changed, 97 insertions, 62 deletions
diff --git a/defs.h b/defs.h
index 67ea9f6..5e049ae 100644
--- a/defs.h
+++ b/defs.h
@@ -108,6 +108,7 @@ void exit(void);
int fork(void);
int growproc(int);
int kill(int);
+struct proc* myproc();
void pinit(void);
void procdump(void);
void scheduler(void) __attribute__((noreturn));
diff --git a/exec.c b/exec.c
index 14d673f..b40134f 100644
--- a/exec.c
+++ b/exec.c
@@ -17,6 +17,7 @@ exec(char *path, char **argv)
struct inode *ip;
struct proghdr ph;
pde_t *pgdir, *oldpgdir;
+ struct proc *curproc = myproc();
begin_op();
@@ -90,15 +91,15 @@ exec(char *path, char **argv)
for(last=s=path; *s; s++)
if(*s == '/')
last = s+1;
- safestrcpy(myproc()->name, last, sizeof(myproc()->name));
+ safestrcpy(curproc->name, last, sizeof(curproc->name));
// Commit to the user image.
- oldpgdir = myproc()->pgdir;
- myproc()->pgdir = pgdir;
- myproc()->sz = sz;
- myproc()->tf->eip = elf.entry; // main
- myproc()->tf->esp = sp;
- switchuvm(myproc());
+ oldpgdir = curproc->pgdir;
+ curproc->pgdir = pgdir;
+ curproc->sz = sz;
+ curproc->tf->eip = elf.entry; // main
+ curproc->tf->esp = sp;
+ switchuvm(curproc);
freevm(oldpgdir);
return 0;
diff --git a/proc.c b/proc.c
index bd62e4b..4e8f461 100644
--- a/proc.c
+++ b/proc.c
@@ -26,14 +26,23 @@ pinit(void)
initlock(&ptable.lock, "ptable");
}
+// XXX get rid off?
int
cpuid() {
return mycpu()-cpus;
}
-void
-setproc(struct proc* p) {
- mycpu()->proc = p;
+// Disable interrupts so that we are not rescheduled
+// while reading proc from the cpu structure
+struct proc*
+myproc(void) {
+ struct cpu *c;
+ struct proc *p;
+ pushcli();
+ c = mycpu();
+ p = c->proc;
+ popcli();
+ return p;
}
//PAGEBREAK: 32
@@ -130,17 +139,18 @@ int
growproc(int n)
{
uint sz;
+ struct proc *curproc = myproc();
- sz = myproc()->sz;
+ sz = curproc->sz;
if(n > 0){
- if((sz = allocuvm(myproc()->pgdir, sz, sz + n)) == 0)
+ if((sz = allocuvm(curproc->pgdir, sz, sz + n)) == 0)
return -1;
} else if(n < 0){
- if((sz = deallocuvm(myproc()->pgdir, sz, sz + n)) == 0)
+ if((sz = deallocuvm(curproc->pgdir, sz, sz + n)) == 0)
return -1;
}
- myproc()->sz = sz;
- switchuvm(myproc());
+ curproc->sz = sz;
+ switchuvm(curproc);
return 0;
}
@@ -152,6 +162,7 @@ fork(void)
{
int i, pid;
struct proc *np;
+ struct proc *curproc = myproc();
// Allocate process.
if((np = allocproc()) == 0){
@@ -159,25 +170,25 @@ fork(void)
}
// Copy process state from proc.
- if((np->pgdir = copyuvm(myproc()->pgdir, myproc()->sz)) == 0){
+ if((np->pgdir = copyuvm(curproc->pgdir, curproc->sz)) == 0){
kfree(np->kstack);
np->kstack = 0;
np->state = UNUSED;
return -1;
}
- np->sz = myproc()->sz;
- np->parent = myproc();
- *np->tf = *myproc()->tf;
+ np->sz = curproc->sz;
+ np->parent = curproc;
+ *np->tf = *curproc->tf;
// Clear %eax so that fork returns 0 in the child.
np->tf->eax = 0;
for(i = 0; i < NOFILE; i++)
- if(myproc()->ofile[i])
- np->ofile[i] = filedup(myproc()->ofile[i]);
- np->cwd = idup(myproc()->cwd);
+ if(curproc->ofile[i])
+ np->ofile[i] = filedup(curproc->ofile[i]);
+ np->cwd = idup(curproc->cwd);
- safestrcpy(np->name, myproc()->name, sizeof(myproc()->name));
+ safestrcpy(np->name, curproc->name, sizeof(curproc->name));
pid = np->pid;
@@ -196,33 +207,34 @@ fork(void)
void
exit(void)
{
+ struct proc *curproc = myproc();
struct proc *p;
int fd;
- if(myproc() == initproc)
+ if(curproc == initproc)
panic("init exiting");
// Close all open files.
for(fd = 0; fd < NOFILE; fd++){
- if(myproc()->ofile[fd]){
- fileclose(myproc()->ofile[fd]);
- myproc()->ofile[fd] = 0;
+ if(curproc->ofile[fd]){
+ fileclose(curproc->ofile[fd]);
+ curproc->ofile[fd] = 0;
}
}
begin_op();
- iput(myproc()->cwd);
+ iput(curproc->cwd);
end_op();
- myproc()->cwd = 0;
+ curproc->cwd = 0;
acquire(&ptable.lock);
// Parent might be sleeping in wait().
- wakeup1(myproc()->parent);
+ wakeup1(curproc->parent);
// Pass abandoned children to init.
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
- if(p->parent == myproc()){
+ if(p->parent == curproc){
p->parent = initproc;
if(p->state == ZOMBIE)
wakeup1(initproc);
@@ -230,7 +242,7 @@ exit(void)
}
// Jump into the scheduler, never to return.
- myproc()->state = ZOMBIE;
+ curproc->state = ZOMBIE;
sched();
panic("zombie exit");
}
@@ -242,13 +254,14 @@ wait(void)
{
struct proc *p;
int havekids, pid;
-
+ struct proc *curproc = myproc();
+
acquire(&ptable.lock);
for(;;){
// Scan through table looking for exited children.
havekids = 0;
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
- if(p->parent != myproc())
+ if(p->parent != curproc)
continue;
havekids = 1;
if(p->state == ZOMBIE){
@@ -268,13 +281,13 @@ wait(void)
}
// No point waiting if we don't have any children.
- if(!havekids || myproc()->killed){
+ if(!havekids || curproc->killed){
release(&ptable.lock);
return -1;
}
// Wait for children to exit. (See wakeup1 call in proc_exit.)
- sleep(myproc(), &ptable.lock); //DOC: wait-sleep
+ sleep(curproc, &ptable.lock); //DOC: wait-sleep
}
}
@@ -290,6 +303,7 @@ void
scheduler(void)
{
struct proc *p;
+ struct cpu *c = mycpu();
for(;;){
// Enable interrupts on this processor.
@@ -304,15 +318,18 @@ scheduler(void)
// Switch to chosen process. It is the process's job
// to release ptable.lock and then reacquire it
// before jumping back to us.
- setproc(p);
+ c->proc = p;
switchuvm(p);
p->state = RUNNING;
- swtch(&(mycpu()->scheduler), p->context);
+ p->cpu = c;
+ // cprintf("%d: switch to %d\n", c-cpus, p->pid);
+ swtch(&(p->cpu->scheduler), p->context);
switchkvm();
// Process is done running for now.
// It should have changed its p->state before coming back.
- setproc(0);
+ c->proc = 0;
+ p->cpu = 0;
}
release(&ptable.lock);
@@ -330,17 +347,20 @@ void
sched(void)
{
int intena;
+ struct proc *p = myproc();
if(!holding(&ptable.lock))
panic("sched ptable.lock");
if(mycpu()->ncli != 1)
panic("sched locks");
- if(myproc()->state == RUNNING)
+ if(p->state == RUNNING)
panic("sched running");
if(readeflags()&FL_IF)
panic("sched interruptible");
intena = mycpu()->intena;
- swtch(&myproc()->context, mycpu()->scheduler);
+ // cprintf("%d: before swtch %d %x\n", p->cpu-cpus, p->pid, * (int *) 0x1d);
+ swtch(&p->context, p->cpu->scheduler);
+ // cprintf("%d/%d: after swtch %d %x\n", cpuid(), p->cpu-cpus, p->pid, * (int *) 0x1d);
mycpu()->intena = intena;
}
@@ -380,7 +400,9 @@ forkret(void)
void
sleep(void *chan, struct spinlock *lk)
{
- if(myproc() == 0)
+ struct proc *p = myproc();
+
+ if(p == 0)
panic("sleep");
if(lk == 0)
@@ -397,12 +419,15 @@ sleep(void *chan, struct spinlock *lk)
release(lk);
}
// Go to sleep.
- myproc()->chan = chan;
- myproc()->state = SLEEPING;
+ p->chan = chan;
+ p->state = SLEEPING;
+
+ // cprintf("sleep %d\n", p->pid);
+
sched();
// Tidy up.
- myproc()->chan = 0;
+ p->chan = 0;
// Reacquire original lock.
if(lk != &ptable.lock){ //DOC: sleeplock2
diff --git a/proc.h b/proc.h
index 38a2d32..7047d54 100644
--- a/proc.h
+++ b/proc.h
@@ -30,12 +30,14 @@ mycpu(void) {
return cpu;
}
+#if 0
static inline struct proc*
myproc(void) {
struct proc *proc;
asm("movl %%gs:4, %0" : "=r"(proc));
return proc;
}
+#endif
//PAGEBREAK: 17
@@ -74,6 +76,7 @@ struct proc {
struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory
char name[16]; // Process name (debugging)
+ struct cpu *cpu; // If running, which cpu.
};
// Process memory is laid out contiguously, low addresses first:
diff --git a/syscall.c b/syscall.c
index 2d6769e..ee85261 100644
--- a/syscall.c
+++ b/syscall.c
@@ -17,7 +17,9 @@
int
fetchint(uint addr, int *ip)
{
- if(addr >= myproc()->sz || addr+4 > myproc()->sz)
+ struct proc *curproc = myproc();
+
+ if(addr >= curproc->sz || addr+4 > curproc->sz)
return -1;
*ip = *(int*)(addr);
return 0;
@@ -30,11 +32,12 @@ int
fetchstr(uint addr, char **pp)
{
char *s, *ep;
+ struct proc *curproc = myproc();
- if(addr >= myproc()->sz)
+ if(addr >= curproc->sz)
return -1;
*pp = (char*)addr;
- ep = (char*)myproc()->sz;
+ ep = (char*)curproc->sz;
for(s = *pp; s < ep; s++){
if(*s == 0)
return s - *pp;
@@ -56,10 +59,11 @@ int
argptr(int n, char **pp, int size)
{
int i;
-
+ struct proc *curproc = myproc();
+
if(argint(n, &i) < 0)
return -1;
- if(size < 0 || (uint)i >= myproc()->sz || (uint)i+size > myproc()->sz)
+ if(size < 0 || (uint)i >= curproc->sz || (uint)i+size > curproc->sz)
return -1;
*pp = (char*)i;
return 0;
@@ -128,13 +132,14 @@ void
syscall(void)
{
int num;
+ struct proc *curproc = myproc();
- num = myproc()->tf->eax;
+ num = curproc->tf->eax;
if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
- myproc()->tf->eax = syscalls[num]();
+ curproc->tf->eax = syscalls[num]();
} else {
cprintf("%d %s: unknown sys call %d\n",
- myproc()->pid, myproc()->name, num);
- myproc()->tf->eax = -1;
+ curproc->pid, curproc->name, num);
+ curproc->tf->eax = -1;
}
}
diff --git a/sysfile.c b/sysfile.c
index fae6960..87e508b 100644
--- a/sysfile.c
+++ b/sysfile.c
@@ -41,10 +41,11 @@ static int
fdalloc(struct file *f)
{
int fd;
+ struct proc *curproc = myproc();
for(fd = 0; fd < NOFILE; fd++){
- if(myproc()->ofile[fd] == 0){
- myproc()->ofile[fd] = f;
+ if(curproc->ofile[fd] == 0){
+ curproc->ofile[fd] = f;
return fd;
}
}
@@ -373,7 +374,8 @@ sys_chdir(void)
{
char *path;
struct inode *ip;
-
+ struct proc *curproc = myproc();
+
begin_op();
if(argstr(0, &path) < 0 || (ip = namei(path)) == 0){
end_op();
@@ -386,9 +388,9 @@ sys_chdir(void)
return -1;
}
iunlock(ip);
- iput(myproc()->cwd);
+ iput(curproc->cwd);
end_op();
- myproc()->cwd = ip;
+ curproc->cwd = ip;
return 0;
}
diff --git a/vm.c b/vm.c
index cb159ad..d1640e8 100644
--- a/vm.c
+++ b/vm.c
@@ -27,13 +27,11 @@ seginit(void)
c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, DPL_USER);
c->gdt[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER);
c->cpu = c;
+ c->proc = 0;
// Map cpu and proc -- these are private per cpu.
c->gdt[SEG_KCPU] = SEG(STA_W, &c->cpu, 4, 0);
lgdt(c->gdt, sizeof(c->gdt));
loadgs(SEG_KCPU << 3);
- // Initialize cpu-local storage.
- // setcpu(c);
- setproc(0);
}
// Return the address of the PTE in page table pgdir