]> Devi Nivas Git - cs3210-lab0.git/commitdiff
add ide_lock for sleep
authorrsc <rsc>
Mon, 17 Jul 2006 05:00:25 +0000 (05:00 +0000)
committerrsc <rsc>
Mon, 17 Jul 2006 05:00:25 +0000 (05:00 +0000)
defs.h
ide.c
proc.c
spinlock.c
spinlock.h
syscall.c

diff --git a/defs.h b/defs.h
index 9d7a94fb36d9eb9173fd376c1a6ee194501b99b6..f9c64d3beb2b72dca2cc80b72edeab3816c27e3a 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -61,10 +61,9 @@ int cpu(void);
 
 // spinlock.c
 struct spinlock;
-void acquire(struct spinlock * lock);
-void release(struct spinlock * lock);
-void acquire1(struct spinlock * lock, struct proc *);
-void release1(struct spinlock * lock, struct proc *);
+void acquire(struct spinlock*);
+void release(struct spinlock*);
+int holding(struct spinlock*);
 
 // main.c
 void load_icode(struct proc *p, uint8_t *binary, uint size);
diff --git a/ide.c b/ide.c
index 3228f7f60038192154bc01cfaf009317eae8902f..2ea2253ccc16d65ae2e982e5c03a90b6d5d889a5 100644 (file)
--- a/ide.c
+++ b/ide.c
@@ -10,6 +10,7 @@
 #include "proc.h"
 #include "defs.h"
 #include "x86.h"
+#include "spinlock.h"
 
 #define IDE_BSY                0x80
 #define IDE_DRDY       0x40
@@ -23,6 +24,7 @@ struct ide_request {
 };
 struct ide_request request[NREQUEST];
 int head, tail;
+struct spinlock ide_lock;
 
 static int diskno = 0;
 int disk_channel;
@@ -107,12 +109,14 @@ void *
 ide_start_read(uint32_t secno, void *dst, uint nsecs)
 {
   struct ide_request *r;
+  if(!holding(&ide_lock))
+    panic("ide_start_read: not holding ide_lock");
 
   if(nsecs > 256)
     panic("ide_start_read: nsecs too large");
 
   while ((head + 1) % NREQUEST == tail)
-    sleep (&disk_channel, 0);
+    sleep (&disk_channel, &ide_lock);
 
   r = &request[head];
   r->secno = secno;
@@ -132,6 +136,8 @@ ide_finish_read(void *c)
   int r = 0;
   struct ide_request *req = (struct ide_request *) c;
 
+  if(!holding(&ide_lock))
+    panic("ide_start_read: not holding ide_lock");
   for (; req->nsecs > 0; req->nsecs--, req->dst += 512) {
     if ((r = ide_wait_ready(1)) < 0)
       break;
diff --git a/proc.c b/proc.c
index 4a050989aca4c831835d0bfc7c8196d4f2741df2..b3f352bd516e0dd13d280f402cc1acc7e8b4520f 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -176,6 +176,15 @@ scheduler(void)
       if(p->state == RUNNING)
         panic("swtch to scheduler with state=RUNNING");
       
+      if(!holding(&proc_table_lock)){
+        cprintf("back to scheduler without proc_table_lock (pid=%d state=%d)", p->pid, p->state);
+        panic("scheduler lock");
+      }
+      if(cpus[cpu()].nlock != 1){
+        cprintf("holding %d locks in scheduler (pid=%d state=%d)\n", cpus[cpu()].nlock, p->pid, p->state);
+        panic("scheduler lock");
+      }
+
       // XXX if not holding proc_table_lock panic.
     }
     release(&proc_table_lock);
@@ -236,6 +245,9 @@ sleep(void *chan, struct spinlock *lk)
   if(p == 0)
     panic("sleep");
 
+  if(lk == 0)
+    panic("sleep without lk");
+
   // Must acquire proc_table_lock in order to 
   // change p->state and then call sched.
   // Once we hold proc_table_lock, we can be 
index c0f236d24af40f9745a3f947abba14c85a80ea03..171afaf01c2737524442e8cd39f8c705601ac7be 100644 (file)
@@ -21,20 +21,32 @@ getcallerpc(void *v)
 void
 acquire(struct spinlock * lock)
 {
+       if(holding(lock))
+               panic("acquire");
+
        if(cpus[cpu()].nlock++ == 0)
                cli();
        while(cmpxchg(0, 1, &lock->locked) == 1)
                ;
        cpuid(0, 0, 0, 0, 0);   // memory barrier
-       lock->locker_pc = getcallerpc(&lock);
+       lock->pc = getcallerpc(&lock);
+       lock->cpu = cpu();
 }
 
 void
 release(struct spinlock * lock)
 {
+       if(!holding(lock))
+               panic("release");
+
        cpuid(0, 0, 0, 0, 0);   // memory barrier
        lock->locked = 0;
        if(--cpus[cpu()].nlock == 0)
                sti();
 }
 
+int
+holding(struct spinlock *lock)
+{
+       return lock->locked && lock->cpu == cpu();
+}
index 044e4d8da7ad54d250bca8f333dc596dd5596dae..656d272d75d8317c2d7920ad55a962b823c9ef71 100644 (file)
@@ -1,4 +1,5 @@
 struct spinlock {
   uint locked;
-  uint locker_pc;
+  uint32_t pc;
+  int cpu;
 };
index 7bd37b7dbed5228152272f99d86f227c7b159f7f..58045d4fd68621f6740b7d112aa82ae796781f64 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -228,17 +228,20 @@ sys_block(void)
   char buf[512];
   int i, j;
   void *c;
+  extern struct spinlock ide_lock;
 
   cprintf("%d: call sys_block\n", cpu());
   for (i = 0; i < 100; i++) {
+    acquire(&ide_lock);
     if ((c = ide_start_read(i, buf, 1)) == 0) {
       panic("couldn't start read\n");
     }
     cprintf("call sleep\n");
-    sleep (c, 0);
+    sleep (c, &ide_lock);
     if (ide_finish_read(c)) {
       panic("couldn't do read\n");
     }
+    release(&ide_lock);
     cprintf("sector %d: ", i);
     for (j = 0; j < 2; j++)
       cprintf("%x ", buf[j] & 0xff);