]> Devi Nivas Git - cs3210-lab0.git/commitdiff
passes both usertests
authorrtm <rtm>
Wed, 12 Jul 2006 15:35:33 +0000 (15:35 +0000)
committerrtm <rtm>
Wed, 12 Jul 2006 15:35:33 +0000 (15:35 +0000)
exit had acquire where I meant release
swtch now checks that you hold no locks

Notes
proc.c
proc.h
spinlock.c
trap.c
usertests.c

diff --git a/Notes b/Notes
index 8fab37d3229d925ccd45345d9856ed875225d2a6..b5f4035adce0cb17d063dea4ea53f363f2e03f05 100644 (file)
--- a/Notes
+++ b/Notes
@@ -114,26 +114,15 @@ wakeup needs proc_table_lock
   so we need recursive locks?
   or you must hold the lock to call wakeup?
 
-if locks contain proc *, they can't be used at interrupt time
-  only proc_table_lock will be used at interrupt time?
-  maybe it doesn't matter if we use curproc?
-
 in general, the table locks protect both free-ness and
   public variables of table elements
   in many cases you can use table elements w/o a lock
   e.g. if you are the process, or you are using an fd
 
-why can't i get a lock in console code?
-  always triple fault
-  because release turns on interrupts!
-  a bad idea very early in main()
-  but mp_init() calls cprintf
-
 lock code shouldn't call cprintf...
-ide_init doesn't work now?
-and IOAPIC: read from unsupported address
-  when running pre-empt user test
-  so maybe something wrong with clock interrupts
-  no! if one cpu holds lock w/ curproc0=,
-    then another cpu can take it, it looks like
-    a recursive acquire()
+
+nasty hack to allow locks before first process,
+  and to allow them in interrupts when curproc may be zero
+
+race between release and sleep in sys_wait()
+race between sys_exit waking up parent and setting state=ZOMBIE
diff --git a/proc.c b/proc.c
index 53469a1baf2d8f4579c0cbdbf7e616fcffef5028..0e35540c7bfd0e1421504d904786e1ad6f15becc 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -181,7 +181,9 @@ swtch(int newstate)
 {
   struct proc *p = curproc[cpu()];
   if(p == 0)
-    panic("swtch");
+    panic("swtch no proc");
+  if(p->locks != 0)
+    panic("swtch w/ locks");
   p->newstate = newstate; // basically an argument to scheduler()
   if(setjmp(&p->jmpbuf) == 0)
     longjmp(&cpus[cpu()].jmpbuf);
@@ -203,9 +205,11 @@ wakeup(void *chan)
   struct proc *p;
 
   acquire(&proc_table_lock);
-  for(p = proc; p < &proc[NPROC]; p++)
-    if(p->state == WAITING && p->chan == chan)
+  for(p = proc; p < &proc[NPROC]; p++){
+    if(p->state == WAITING && p->chan == chan){
       p->state = RUNNABLE;
+    }
+  }
   release(&proc_table_lock);
 }
 
@@ -225,7 +229,7 @@ proc_exit()
   struct proc *cp = curproc[cpu()];
   int fd;
 
-  cprintf("exit %x\n", cp);
+  cprintf("exit %x pid %d ppid %d\n", cp, cp->pid, cp->ppid);
 
   for(fd = 0; fd < NOFILE; fd++){
     if(cp->fds[fd]){
@@ -246,7 +250,7 @@ proc_exit()
     if(p->ppid == cp->pid)
       p->pid = 1;
 
-  acquire(&proc_table_lock);
+  release(&proc_table_lock);
 
   // switch into scheduler
   swtch(ZOMBIE);
@@ -265,10 +269,8 @@ cli(void)
 void
 sti(void)
 {
-  if(cpus[cpu()].clis < 1){
-    cprintf("cpu %d clis %d\n", cpu(), cpus[cpu()].clis);
+  if(cpus[cpu()].clis < 1)
     panic("sti");
-  }
   cpus[cpu()].clis -= 1;
   if(cpus[cpu()].clis < 1)
     __asm __volatile("sti");
diff --git a/proc.h b/proc.h
index 4c5807bbdf964840b885276af4f4b93fc609225f..e13df410fc7be068b305c92a985f22fe4759fe39 100644 (file)
--- a/proc.h
+++ b/proc.h
@@ -45,6 +45,7 @@ struct proc{
   int ppid;
   void *chan; // sleep
   int killed;
+  int locks; // # of locks currently held
   struct fd *fds[NOFILE];
 
   struct Taskstate ts;  // only to give cpu address of kernel stack
index bd6bff57159615e8a484db4f34d0e1cd324bcea4..507e74b330c48d7fa72e03353832bfbb1e41026f 100644 (file)
@@ -17,10 +17,11 @@ int getcallerpc(void *v) {
 void
 acquire(struct spinlock * lock)
 {
+  struct proc *cp = curproc[cpu()];
   unsigned who;
 
-  if(curproc[cpu()])
-    who = (unsigned) curproc[cpu()];
+  if(cp)
+    who = (unsigned) cp;
   else
     who = cpu() + 1;
 
@@ -38,16 +39,20 @@ acquire(struct spinlock * lock)
     lock->who = who;
   }
 
+  if(cp)
+    cp->locks += 1;
+
   if(DEBUG) cprintf("cpu%d: acquired at %x\n", cpu(), getcallerpc(&lock));
 }
 
 void
 release(struct spinlock * lock)
 {
+  struct proc *cp = curproc[cpu()];
   unsigned who;
 
-  if(curproc[cpu()])
-    who = (unsigned) curproc[cpu()];
+  if(cp)
+    who = (unsigned) cp;
   else
     who = cpu() + 1;
 
@@ -57,6 +62,8 @@ release(struct spinlock * lock)
     panic("release");
 
   lock->count -= 1;
+  if(cp)
+    cp->locks -= 1;
   if(lock->count < 1){
     lock->who = 0;
     cmpxchg(1, 0, &lock->locked);
diff --git a/trap.c b/trap.c
index 862225b6606abb4c91a8a95325a9a309be53ea06..6f5409bb1b10878911d1d626d865cc534b44b0a9 100644 (file)
--- a/trap.c
+++ b/trap.c
@@ -62,6 +62,9 @@ trap(struct Trapframe *tf)
     struct proc *cp = curproc[cpu()];
     lapic_timerintr();
     if(cp){
+      if(cpus[cpu()].clis != 0)
+        panic("trap clis > 0");
+      cpus[cpu()].clis += 1;
       sti();
       if(cp->killed)
         proc_exit();
@@ -69,6 +72,7 @@ trap(struct Trapframe *tf)
     }
     return;
   }
+
   if(v == (IRQ_OFFSET + IRQ_IDE)){
     ide_intr();
     return;
index fa1b2100a7f4b0ee293b01ec8ba5fbff067a81fd..2f688ca98d82e1894f29f8700d01cc973699a40e 100644 (file)
@@ -93,8 +93,8 @@ preempt()
 main()
 {
   puts("usertests starting\n");
-  //pipe1();
-  preempt();
+  pipe1();
+  //preempt();
 
   while(1)
     ;