]> Devi Nivas Git - cs3210-lab1.git/commitdiff
Rearrange proc.h and proc.c to get our action-packed spreads back (mostly). They...
authorAustin Clements <amdragon@mit.edu>
Thu, 2 Sep 2010 08:15:17 +0000 (04:15 -0400)
committerAustin Clements <amdragon@mit.edu>
Thu, 2 Sep 2010 08:15:17 +0000 (04:15 -0400)
proc.c
proc.h
runoff.spec

diff --git a/proc.c b/proc.c
index 375b1bbd377a5b81ea88ed2881cb59b95d519d19..819737770263992db0b9061083e95f1e12319d4f 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -193,6 +193,92 @@ fork(void)
   return pid;
 }
 
+// Exit the current process.  Does not return.
+// An exited process remains in the zombie state
+// until its parent calls wait() to find out it exited.
+void
+exit(void)
+{
+  struct proc *p;
+  int fd;
+
+  if(proc == initproc)
+    panic("init exiting");
+
+  // Close all open files.
+  for(fd = 0; fd < NOFILE; fd++){
+    if(proc->ofile[fd]){
+      fileclose(proc->ofile[fd]);
+      proc->ofile[fd] = 0;
+    }
+  }
+
+  iput(proc->cwd);
+  proc->cwd = 0;
+
+  acquire(&ptable.lock);
+
+  // Parent might be sleeping in wait().
+  wakeup1(proc->parent);
+
+  // Pass abandoned children to init.
+  for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
+    if(p->parent == proc){
+      p->parent = initproc;
+      if(p->state == ZOMBIE)
+        wakeup1(initproc);
+    }
+  }
+
+  // Jump into the scheduler, never to return.
+  proc->state = ZOMBIE;
+  sched();
+  panic("zombie exit");
+}
+
+// Wait for a child process to exit and return its pid.
+// Return -1 if this process has no children.
+int
+wait(void)
+{
+  struct proc *p;
+  int havekids, pid;
+
+  acquire(&ptable.lock);
+  for(;;){
+    // Scan through table looking for zombie children.
+    havekids = 0;
+    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
+      if(p->parent != proc)
+        continue;
+      havekids = 1;
+      if(p->state == ZOMBIE){
+        // Found one.
+        pid = p->pid;
+        kfree(p->kstack);
+        p->kstack = 0;
+        freevm(p->pgdir);
+        p->state = UNUSED;
+        p->pid = 0;
+        p->parent = 0;
+        p->name[0] = 0;
+        p->killed = 0;
+        release(&ptable.lock);
+        return pid;
+      }
+    }
+
+    // No point waiting if we don't have any children.
+    if(!havekids || proc->killed){
+      release(&ptable.lock);
+      return -1;
+    }
+
+    // Wait for children to exit.  (See wakeup1 call in proc_exit.)
+    sleep(proc, &ptable.lock);  //DOC: wait-sleep
+  }
+}
+
 //PAGEBREAK: 42
 // Per-CPU process scheduler.
 // Each CPU calls scheduler() after setting itself up.
@@ -357,89 +443,3 @@ kill(int pid)
   return -1;
 }
 
-// Exit the current process.  Does not return.
-// An exited process remains in the zombie state
-// until its parent calls wait() to find out it exited.
-void
-exit(void)
-{
-  struct proc *p;
-  int fd;
-
-  if(proc == initproc)
-    panic("init exiting");
-
-  // Close all open files.
-  for(fd = 0; fd < NOFILE; fd++){
-    if(proc->ofile[fd]){
-      fileclose(proc->ofile[fd]);
-      proc->ofile[fd] = 0;
-    }
-  }
-
-  iput(proc->cwd);
-  proc->cwd = 0;
-
-  acquire(&ptable.lock);
-
-  // Parent might be sleeping in wait().
-  wakeup1(proc->parent);
-
-  // Pass abandoned children to init.
-  for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
-    if(p->parent == proc){
-      p->parent = initproc;
-      if(p->state == ZOMBIE)
-        wakeup1(initproc);
-    }
-  }
-
-  // Jump into the scheduler, never to return.
-  proc->state = ZOMBIE;
-  sched();
-  panic("zombie exit");
-}
-
-// Wait for a child process to exit and return its pid.
-// Return -1 if this process has no children.
-int
-wait(void)
-{
-  struct proc *p;
-  int havekids, pid;
-
-  acquire(&ptable.lock);
-  for(;;){
-    // Scan through table looking for zombie children.
-    havekids = 0;
-    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
-      if(p->parent != proc)
-        continue;
-      havekids = 1;
-      if(p->state == ZOMBIE){
-        // Found one.
-        pid = p->pid;
-        kfree(p->kstack);
-        p->kstack = 0;
-        freevm(p->pgdir);
-        p->state = UNUSED;
-        p->pid = 0;
-        p->parent = 0;
-        p->name[0] = 0;
-        p->killed = 0;
-        release(&ptable.lock);
-        return pid;
-      }
-    }
-
-    // No point waiting if we don't have any children.
-    if(!havekids || proc->killed){
-      release(&ptable.lock);
-      return -1;
-    }
-
-    // Wait for children to exit.  (See wakeup1 call in proc_exit.)
-    sleep(proc, &ptable.lock);  //DOC: wait-sleep
-  }
-}
-
diff --git a/proc.h b/proc.h
index 8799668f0cd02411539b81efa2eea980e07a1115..4a80a28070049fe0ed31d9d1847b601b0133ef81 100644 (file)
--- a/proc.h
+++ b/proc.h
@@ -8,6 +8,36 @@
 #define SEG_TSS   6  // this process's task state
 #define NSEGS     7
 
+// Per-CPU state
+struct cpu {
+  uchar id;                    // Local APIC ID; index into cpus[] below
+  struct context *scheduler;   // Switch here to enter scheduler
+  struct taskstate ts;         // Used by x86 to find stack for interrupt
+  struct segdesc gdt[NSEGS];   // x86 global descriptor table
+  volatile uint booted;        // Has the CPU started?
+  int ncli;                    // Depth of pushcli nesting.
+  int intena;                  // Were interrupts enabled before pushcli?
+  
+  // Cpu-local storage variables; see below
+  struct cpu *cpu;
+  struct proc *proc;
+};
+
+extern struct cpu cpus[NCPU];
+extern int ncpu;
+
+// Per-CPU variables, holding pointers to the
+// current cpu and to the current process.
+// The asm suffix tells gcc to use "%gs:0" to refer to cpu
+// and "%gs:4" to refer to proc.  ksegment sets up the
+// %gs segment register so that %gs refers to the memory
+// holding those two variables in the local cpu's struct cpu.
+// This is similar to how thread-local variables are implemented
+// in thread libraries such as Linux pthreads.
+extern struct cpu *cpu asm("%gs:0");       // This cpu.
+extern struct proc *proc asm("%gs:4");     // Current proc on this cpu.
+
+//PAGEBREAK: 17
 // Saved registers for kernel context switches.
 // Don't need to save all the segment registers (%cs, etc),
 // because they are constant across kernel contexts.
@@ -50,32 +80,3 @@ struct proc {
 //   original data and bss
 //   fixed-size stack
 //   expandable heap
-
-// Per-CPU state
-struct cpu {
-  uchar id;                    // Local APIC ID; index into cpus[] below
-  struct context *scheduler;   // Switch here to enter scheduler
-  struct taskstate ts;         // Used by x86 to find stack for interrupt
-  struct segdesc gdt[NSEGS];   // x86 global descriptor table
-  volatile uint booted;        // Has the CPU started?
-  int ncli;                    // Depth of pushcli nesting.
-  int intena;                  // Were interrupts enabled before pushcli?
-  
-  // Cpu-local storage variables; see below
-  struct cpu *cpu;
-  struct proc *proc;
-};
-
-extern struct cpu cpus[NCPU];
-extern int ncpu;
-
-// Per-CPU variables, holding pointers to the
-// current cpu and to the current process.
-// The asm suffix tells gcc to use "%gs:0" to refer to cpu
-// and "%gs:4" to refer to proc.  ksegment sets up the
-// %gs segment register so that %gs refers to the memory
-// holding those two variables in the local cpu's struct cpu.
-// This is similar to how thread-local variables are implemented
-// in thread libraries such as Linux pthreads.
-extern struct cpu *cpu asm("%gs:0");       // This cpu.
-extern struct proc *proc asm("%gs:4");     // Current proc on this cpu.
index fe960cea6fad7e03f30b70f763892c70616b916f..9d87528d87feaa59b7a9a2aac95a978c172b9949 100644 (file)
@@ -20,22 +20,27 @@ sheet1: left
 
 even: bootasm.S  # mild preference
 even: bootother.S  # mild preference
-even: bootmain.S  # mild preference
+even: bootmain.c  # mild preference
 even: main.c
 # mp.c don't care at all
 # even: initcode.S
 # odd: init.c
 
 # spinlock.h either
-left: spinlock.c  # mild preference
-even: proc.h  # mild preference
+left: spinlock.h  # mild preference
+even: spinlock.h  # mild preference
+
+# This gets struct proc and allocproc on the same spread
+right: proc.h
+odd: proc.h
 
 # goal is to have two action-packed 2-page spreads,
 # one with
-#     allocproc userinit growproc fork
+#     userinit growproc fork exit wait
 # and another with
 #     scheduler sched yield forkret sleep wakeup1 wakeup
-right: proc.c   # VERY important
+left: proc.c   # VERY important
+odd: proc.c   # VERY important
 
 # setjmp.S either
 # vm.c either