]> Devi Nivas Git - cs3210-lab1.git/commitdiff
Read curproc from cpu structure, but be careful because after a schedule event
authorFrans Kaashoek <kaashoek@mit.edu>
Wed, 1 Feb 2017 01:21:14 +0000 (20:21 -0500)
committerFrans Kaashoek <kaashoek@mit.edu>
Wed, 1 Feb 2017 01:21:14 +0000 (20:21 -0500)
myproc() points to a different thread.

   myproc();
   sched();
   myproc();  // this proc maybe different than the one before sched

Thus, in a function that operates on one thread better to retrieve the
current process once at the start of the function.

defs.h
exec.c
proc.c
proc.h
syscall.c
sysfile.c
vm.c

diff --git a/defs.h b/defs.h
index 67ea9f6cba91d2450682239f70ce4690f5b295a4..5e049aed51e62d83db8c5d48879ccc0457219d18 100644 (file)
--- 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 14d673f12ed9aafe689cd75417a615344d73c0e0..b40134f352f4463eda28814c25a6f481bd592836 100644 (file)
--- 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 bd62e4b97d6b5f12a32b7d3e0db725915cd50e35..4e8f461a448956a5230f338c137c5280c74783f7 100644 (file)
--- 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 38a2d32c0f4a4dd6a7f1fb9ba4a18e0ff49977aa..7047d549396bb01f380998bbab442a705f1d7206 100644 (file)
--- 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:
index 2d6769e204d33a60d8c35eca8cc8f0af80a5399c..ee8526160204d5a3917a28777af1ddb4f5a988c8 100644 (file)
--- 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;
   }
 }
index fae69608b26a41784134b6e3d55aa50886f16357..87e508b26805efa2cc789adf9b9742fc6aa625f0 100644 (file)
--- 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 cb159ad841f18301aa383b18ec5f7c2f1437769c..d1640e8c3cc71b28094760831026fa6e6eae212d 100644 (file)
--- 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