]> Devi Nivas Git - cs3210-lab0.git/commitdiff
Replace yield system call with sleep.
authorrsc <rsc>
Mon, 27 Aug 2007 13:34:35 +0000 (13:34 +0000)
committerrsc <rsc>
Mon, 27 Aug 2007 13:34:35 +0000 (13:34 +0000)
defs.h
syscall.c
syscall.h
sysproc.c
trap.c
trapasm.S
user.h
usys.S
zombie.c

diff --git a/defs.h b/defs.h
index af22433287662c93e67aa4ad42fcfd89f8b5f0ae..7af5421c04a7fb7a55b4d36278e2fe23ffde7678 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -139,7 +139,9 @@ void            syscall(void);
 
 // trap.c
 void            idtinit(void);
+extern int      ticks;
 void            tvinit(void);
+extern struct spinlock tickslock;
 
 // number of elements in fixed-size array
 #define NELEM(x) (sizeof(x)/sizeof((x)[0]))
index d7cf1230426e0274a7bc8e12ebbec4a93b9f36ea..9fed725d543fb50d27eb523d7000aef4ba5214f9 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -102,10 +102,10 @@ extern int sys_open(void);
 extern int sys_pipe(void);
 extern int sys_read(void);
 extern int sys_sbrk(void);
+extern int sys_sleep(void);
 extern int sys_unlink(void);
 extern int sys_wait(void);
 extern int sys_write(void);
-extern int sys_yield(void);
 
 static int (*syscalls[])(void) = {
 [SYS_chdir]   sys_chdir,
@@ -124,10 +124,10 @@ static int (*syscalls[])(void) = {
 [SYS_pipe]    sys_pipe,
 [SYS_read]    sys_read,
 [SYS_sbrk]    sys_sbrk,
+[SYS_sleep]   sys_sleep,
 [SYS_unlink]  sys_unlink,
 [SYS_wait]    sys_wait,
 [SYS_write]   sys_write,
-[SYS_yield]   sys_yield,
 };
 
 void
index 85ea220eaa7c4bc4f184849c13068397d2026642..f4b7807ed615bf10c8f6c4df8d044c6655ddf1bd 100644 (file)
--- a/syscall.h
+++ b/syscall.h
@@ -18,4 +18,4 @@
 #define SYS_dup    17
 #define SYS_getpid 18
 #define SYS_sbrk   19
-#define SYS_yield  20
+#define SYS_sleep  20
index 8cf329199fde3c075112adc42d3c48a6d7113408..48fbe373dc68561897c6a9277127b79b0769de34 100644 (file)
--- a/sysproc.c
+++ b/sysproc.c
@@ -70,8 +70,21 @@ sys_sbrk(void)
 }
 
 int
-sys_yield(void)
+sys_sleep(void)
 {
-  yield();
+  int n, ticks0;
+  
+  if(argint(0, &n) < 0)
+    return -1;
+  acquire(&tickslock);
+  ticks0 = ticks;
+  while(ticks - ticks0 < n){
+    if(cp->killed){
+      release(&tickslock);
+      return -1;
+    }
+    sleep(&ticks, &tickslock);
+  }
+  release(&tickslock);
   return 0;
 }
diff --git a/trap.c b/trap.c
index 217e79d7b33c4d4021d41de610b4b4a0601ed7fd..e045aeded07370e1daefa5d659d45b55992e7425 100644 (file)
--- a/trap.c
+++ b/trap.c
@@ -6,10 +6,13 @@
 #include "x86.h"
 #include "traps.h"
 #include "syscall.h"
+#include "spinlock.h"
 
 // Interrupt descriptor table (shared by all CPUs).
 struct gatedesc idt[256];
 extern uint vectors[];  // in vectors.S: array of 256 entry pointers
+struct spinlock tickslock;
+int ticks;
 
 void
 tvinit(void)
@@ -19,6 +22,8 @@ tvinit(void)
   for(i = 0; i < 256; i++)
     SETGATE(idt[i], 0, SEG_KCODE<<3, vectors[i], 0);
   SETGATE(idt[T_SYSCALL], 0, SEG_KCODE<<3, vectors[T_SYSCALL], DPL_USER);
+  
+  initlock(&tickslock, "time");
 }
 
 void
@@ -47,21 +52,14 @@ trap(struct trapframe *tf)
   // PAGEBREAK: 10
   switch(tf->trapno){
   case IRQ_OFFSET + IRQ_TIMER:
-    lapic_timerintr();
-    cpus[cpu()].nlock--;
-    if(cp){
-      // Force process exit if it has been killed and is in user space.
-      // (If it is still executing in the kernel, let it keep running
-      // until it gets to the regular system call return.)
-      if((tf->cs&3) == DPL_USER && cp->killed)
-        proc_exit();
-
-      // Force process to give up CPU and let others run.
-      // If locks were held with interrupts on, would need to check nlock.
-      if(cp->state == RUNNING)
-        yield();
+    if(cpu() == 0){
+      acquire(&tickslock);
+      ticks++;
+      wakeup(&ticks);
+      release(&tickslock);
     }
-    return;
+    lapic_eoi();
+    break;
 
   case IRQ_OFFSET + IRQ_IDE:
     ide_intr();
@@ -75,6 +73,7 @@ trap(struct trapframe *tf)
   
   case IRQ_OFFSET + IRQ_SPURIOUS:
     cprintf("spurious interrupt from cpu %d eip %x\n", cpu(), tf->eip);
+    lapic_eoi();
     break;
     
   default:
@@ -84,12 +83,23 @@ trap(struct trapframe *tf)
               cp->pid, cp->name, tf->trapno, tf->err, cpu(), tf->eip);
       proc_exit();
     }
-    
     // Otherwise it's our mistake.
     cprintf("unexpected trap %d from cpu %d eip %x\n",
             tf->trapno, cpu(), tf->eip);
     panic("trap");
   }
-  
   cpus[cpu()].nlock--;
+
+  if(tf->trapno == IRQ_OFFSET + IRQ_TIMER && cp != 0){
+    // Force process exit if it has been killed and is in user space.
+    // (If it is still executing in the kernel, let it keep running
+    // until it gets to the regular system call return.)
+    if((tf->cs&3) == DPL_USER && cp->killed)
+      proc_exit();
+
+    // Force process to give up CPU and let others run.
+    // If locks were held with interrupts on, would need to check nlock.
+    if(cp->state == RUNNING)
+      yield();
+  }
 }
index ac964131cbea1e80702a81fc6b92c5306e8f4f7e..87a832a7f3393746c1141036bd3c48b8796398b1 100644 (file)
--- a/trapasm.S
+++ b/trapasm.S
@@ -3,7 +3,7 @@
 .globl trapret1
 .globl alltraps
 
-.set SEG_KDATA_SEL  0x10   # selector for SEG_KDATA
+.set SEG_KDATA_SEL, 0x10   # selector for SEG_KDATA
 
   # vectors.S sends all traps here.
 alltraps:
diff --git a/user.h b/user.h
index 1bbe2fd6c0cd1d9e57da8a57d11e0d2cf19be915..c3ee675da2173e9d5f37445bcd955c5c349844bd 100644 (file)
--- a/user.h
+++ b/user.h
@@ -18,6 +18,7 @@ int chdir(char*);
 int dup(int);
 int getpid();
 char* sbrk(int);
+int sleep(int);
 
 // ulib.c
 int stat(char*, struct stat*);
diff --git a/usys.S b/usys.S
index 210774dc07e719f1a671b1f5eb5e3a4297d6c047..380cb91fae9a2a68bff0783c1bf11f4d4f161be7 100644 (file)
--- a/usys.S
+++ b/usys.S
@@ -27,4 +27,4 @@ STUB(chdir)
 STUB(dup)
 STUB(getpid)
 STUB(sbrk)
-STUB(yield)
+STUB(sleep)
index 883ea75caedc7d000d67e260a4c225210a507a33..07ad7982419e1d743d42874467699a66c75c0ebf 100644 (file)
--- a/zombie.c
+++ b/zombie.c
@@ -1,4 +1,5 @@
-// Create a zombie process.
+// Create a zombie process that 
+// must be reparented at exit.
 
 #include "types.h"
 #include "stat.h"
@@ -10,7 +11,6 @@ main(void)
   int i;
 
   if(fork() > 0)
-    for(i=0; i<10; i++)
-      yield();
+    sleep(5);  // Let child exit before parent.
   exit();
 }