]> Devi Nivas Git - cs3210-lab1.git/commitdiff
sleep, wakeup, wait, exit
authorrtm <rtm>
Thu, 15 Jun 2006 19:58:01 +0000 (19:58 +0000)
committerrtm <rtm>
Thu, 15 Jun 2006 19:58:01 +0000 (19:58 +0000)
Makefile
defs.h
main.c
proc.c
proc.h
syscall.c
syscall.h

index 2a8c3ce93b8457ce46af9db2ef9f7eb0e50120e9..fa93f850374b0c0385cfd10c64aa4c69177f4c15 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ CC = i386-jos-elf-gcc
 LD = i386-jos-elf-ld
 OBJCOPY = i386-jos-elf-objcopy
 OBJDUMP = i386-jos-elf-objdump
-CFLAGS = -nostdinc -I. -O -Wall
+CFLAGS = -nostdinc -I. -O -Wall -MD
 
 xv6.img : bootblock kernel
        dd if=/dev/zero of=xv6.img count=10000
@@ -27,5 +27,7 @@ kernel : $(OBJS)
 vectors.S : vectors.pl
        perl vectors.pl > vectors.S
 
+-include *.d
+
 clean : 
-       rm -f *.o bootblock kernel kernel.asm xv6.img
+       rm -f *.o bootblock kernel kernel.asm xv6.img *.d
diff --git a/defs.h b/defs.h
index ad51167444d20dd6ae2a4af84abd99b426c75a8d..eea3d0ca8def581cc5a902b775d0a0df3b4acaeb 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -12,6 +12,8 @@ struct proc;
 void setupsegs(struct proc *);
 struct proc * newproc(void);
 void swtch(void);
+void sleep(void *);
+void wakeup(void *);
 
 // trap.c
 void tinit(void);
diff --git a/main.c b/main.c
index 6b07d836fa2642cf77d4b8b849650f341418c3c7..43c8c0260ef82fed14fa532539edb9b6599b957c 100644 (file)
--- a/main.c
+++ b/main.c
@@ -42,6 +42,8 @@ main()
   p->tf->tf_es = p->tf->tf_ds = p->tf->tf_ss = (SEG_UDATA << 3) | 3;
   p->tf->tf_cs = (SEG_UCODE << 3) | 3;
   p->tf->tf_eflags = FL_IF;
+  p->pid = 0;
+  p->ppid = 0;
   setupsegs(p);
 
   p = newproc();
@@ -56,6 +58,13 @@ main()
   p->mem[i++] = 0xcd; // int
   p->mem[i++] = T_SYSCALL;
   p->mem[i++] = 0xb8; // mov ..., %eax
+  p->mem[i++] = SYS_wait;
+  p->mem[i++] = 0;
+  p->mem[i++] = 0;
+  p->mem[i++] = 0;
+  p->mem[i++] = 0xcd; // int
+  p->mem[i++] = T_SYSCALL;
+  p->mem[i++] = 0xb8; // mov ..., %eax
   p->mem[i++] = SYS_exit;
   p->mem[i++] = 0;
   p->mem[i++] = 0;
diff --git a/proc.c b/proc.c
index 1e90e37a46f612692e35564478a8675c173c4b50..82910399b3f156be177467e69daa189c382a1c26 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -7,6 +7,7 @@
 
 struct proc proc[NPROC];
 struct proc *curproc;
+int next_pid = 1;
 
 /*
  * set up a process's task state and segment descriptors
@@ -54,6 +55,8 @@ newproc()
   if(np >= &proc[NPROC])
     return 0;
 
+  np->pid = next_pid++;
+  np->ppid = curproc->pid;
   np->sz = curproc->sz;
   np->mem = kalloc(curproc->sz);
   if(np->mem == 0)
@@ -111,7 +114,12 @@ swtch()
 
   // XXX callee-saved registers?
 
-  // XXX probably ought to lgdt on trap return too
+  // h/w sets busy bit in TSS descriptor sometimes, and faults
+  // if it's set in LTR. so clear tss descriptor busy bit.
+  curproc->gdt[SEG_TSS].sd_type = STS_T32A;
+
+  // XXX probably ought to lgdt on trap return too, in case
+  // a system call has moved a program or changed its size.
 
   asm volatile("lgdt %0" : : "g" (np->gdt_pd.pd_lim));
   ltr(SEG_TSS << 3);
@@ -122,3 +130,21 @@ swtch()
   asm volatile("movl %0, %%esp" : : "g" (np->esp));
   asm volatile("movl %0, %%ebp" : : "g" (np->ebp));
 }
+
+void
+sleep(void *chan)
+{
+  curproc->chan = chan;
+  curproc->state = WAITING;
+  swtch();
+}
+
+void
+wakeup(void *chan)
+{
+  struct proc *p;
+
+  for(p = proc; p < &proc[NPROC]; p++)
+    if(p->state == WAITING && p->chan == chan)
+      p->state = RUNNABLE;
+}
diff --git a/proc.h b/proc.h
index 39e1c494bdacb4043d0de236c9bdea9d9b4d0fb8..6eba56623b71698dc0f4b10283af1272778ae49a 100644 (file)
--- a/proc.h
+++ b/proc.h
@@ -20,7 +20,10 @@ struct proc{
   char *mem; // start of process's physical memory
   unsigned sz; // total size of mem, including kernel stack
   char *kstack; // kernel stack, separate from mem so it doesn't move
-  enum { UNUSED, RUNNABLE, WAITING } state;
+  enum { UNUSED, RUNNABLE, WAITING, ZOMBIE } state;
+  int pid;
+  int ppid;
+  void *chan; // sleep
 
   struct Taskstate ts;  // only to give cpu address of kernel stack
   struct Segdesc gdt[NSEGS];
index 9cb20dcc4a9effdd4efe70b354f81bb786bee1e3..1968c8afaeedb3de1833c90d457d6b07ef716538 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -24,11 +24,52 @@ sys_fork()
 void
 sys_exit()
 {
-  curproc->state = UNUSED;
-  // XXX free resources. notify parent. abandon children.
+  struct proc *p;
+
+  curproc->state = ZOMBIE;
+
+  // wake up parent
+  for(p = proc; p < &proc[NPROC]; p++)
+    if(p->pid == curproc->ppid)
+      wakeup(p);
+
+  // abandon children
+  for(p = proc; p < &proc[NPROC]; p++)
+    if(p->ppid == curproc->pid)
+      p->pid = 1;
+
   swtch();
 }
 
+void
+sys_wait()
+{
+  struct proc *p;
+  int any;
+
+  cprintf("waid pid %d ppid %d\n", curproc->pid, curproc->ppid);
+
+  while(1){
+    any = 0;
+    for(p = proc; p < &proc[NPROC]; p++){
+      if(p->state == ZOMBIE && p->ppid == curproc->pid){
+        kfree(p->mem, p->sz);
+        kfree(p->kstack, KSTACKSIZE);
+        p->state = UNUSED;
+        cprintf("%x collected %x\n", curproc, p);
+        return;
+      }
+      if(p->state != UNUSED && p->ppid == curproc->pid)
+        any = 1;
+    }
+    if(any == 0){
+      cprintf("%x nothing to wait for\n", curproc);
+      return;
+    }
+    sleep(curproc);
+  }
+}
+
 void
 syscall()
 {
@@ -42,6 +83,9 @@ syscall()
   case SYS_exit:
     sys_exit();
     break;
+  case SYS_wait:
+    sys_wait();
+    break;
   default:
     cprintf("unknown sys call %d\n", num);
     // XXX fault
index 3155dbdd280d8c087c6026f0fd52951ae1a1fab0..13bb2c75a264659ac6195ba110a71781304b56b2 100644 (file)
--- a/syscall.h
+++ b/syscall.h
@@ -1,2 +1,3 @@
 #define SYS_fork 1
 #define SYS_exit 2
+#define SYS_wait 3