]> Devi Nivas Git - cs3210-lab1.git/commitdiff
replace setjmp/longjmp with swtch
authorrsc <rsc>
Tue, 28 Aug 2007 12:48:33 +0000 (12:48 +0000)
committerrsc <rsc>
Tue, 28 Aug 2007 12:48:33 +0000 (12:48 +0000)
Makefile
defs.h
proc.c
proc.h
runoff.list
setjmp.S [deleted file]
swtch.S [new file with mode: 0644]

index a27ec5f6f375469e22f10ff2a0d6ae07178977c2..0e2bc0f076723f8290b0c02a2b4c3c2420eb9bed 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -14,9 +14,9 @@ OBJS = \
        picirq.o\
        pipe.o\
        proc.o\
-       setjmp.o\
        spinlock.o\
        string.o\
+       swtch.o\
        syscall.o\
        sysfile.o\
        sysproc.o\
@@ -67,7 +67,7 @@ initcode: initcode.S
 kernel: $(OBJS) bootother initcode
        $(LD) -Ttext 0x100000 -e main -o kernel $(OBJS) -b binary initcode bootother
        $(OBJDUMP) -S kernel > kernel.asm
-       $(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* //' > kernel.sym
+       $(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym
 
 tags: $(OBJS) bootother.S _init
        etags *.S *.c
@@ -80,7 +80,7 @@ ULIB = ulib.o usys.o printf.o umalloc.o
 _%: %.o $(ULIB)
        $(LD) -N -e main -Ttext 0 -o $@ $^
        $(OBJDUMP) -S $@ > $*.asm
-       $(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* //' > $*.sym
+       $(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym
 
 _forktest: forktest.o $(ULIB)
        # forktest has less library code linked in - needs to be small
@@ -119,18 +119,7 @@ clean:
        $(UPROGS)
 
 # make a printout
-PRINT =        \
-       runoff.list \
-       README\
-       types.h param.h defs.h x86.h asm.h elf.h mmu.h spinlock.h\
-       bootasm.S bootother.S main.c init.c spinlock.c\
-       proc.h proc.c setjmp.S kalloc.c\
-       syscall.h trapasm.S traps.h trap.c vectors.pl syscall.c sysproc.c\
-       buf.h dev.h fcntl.h stat.h file.h fs.h fsvar.h file.c fs.c bio.c ide.c sysfile.c\
-       pipe.c exec.c\
-       mp.h ioapic.h mp.c lapic.c ioapic.c picirq.c\
-       console.c\
-       string.c\
+PRINT = runoff.list $(shell grep -v '^\#' runoff.list)
 
 xv6.pdf: $(PRINT)
        ./runoff
diff --git a/defs.h b/defs.h
index a72ecaf0874bc7913aa1d37036ad4ab36e3c097a..35323ea507930a0f7522b146a4d73a1a5a558222 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -1,7 +1,7 @@
 struct buf;
+struct context;
 struct file;
 struct inode;
-struct jmpbuf;
 struct pipe;
 struct proc;
 struct spinlock;
@@ -109,9 +109,8 @@ void            userinit(void);
 void            wakeup(void*);
 void            yield(void);
 
-// setjmp.S
-void            longjmp(struct jmpbuf*);
-int             setjmp(struct jmpbuf*);
+// swtch.S
+void            swtch(struct context*, struct context*);
 
 // spinlock.c
 void            acquire(struct spinlock*);
diff --git a/proc.c b/proc.c
index eb7d1f8107fcb33f88a4bd17d1204e541ba2a397..46a38bf2d9eb1fc5dfc4419d10919377c816bbd6 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -134,10 +134,10 @@ copyproc(struct proc *p)
     np->cwd = idup(p->cwd);
   }
 
-  // Set up new jmpbuf to start executing at forkret (see below).
-  memset(&np->jmpbuf, 0, sizeof(np->jmpbuf));
-  np->jmpbuf.eip = (uint)forkret;
-  np->jmpbuf.esp = (uint)np->tf - 4;
+  // Set up new context to start executing at forkret (see below).
+  memset(&np->context, 0, sizeof(np->context));
+  np->context.eip = (uint)forkret;
+  np->context.esp = (uint)np->tf;
 
   // Clear %eax so that fork system call returns 0 in child.
   np->tf->eax = 0;
@@ -206,8 +206,7 @@ scheduler(void)
       setupsegs(p);
       cp = p;
       p->state = RUNNING;
-      if(setjmp(&cpus[cpu()].jmpbuf) == 0)
-        longjmp(&p->jmpbuf);
+      swtch(&cpus[cpu()].context, &p->context);
 
       // Process is done running for now.
       // It should have changed its p->state before coming back.
@@ -232,8 +231,7 @@ sched(void)
   if(cpus[cpu()].nlock != 1)
     panic("sched locks");
 
-  if(setjmp(&cp->jmpbuf) == 0)
-    longjmp(&cpus[cpu()].jmpbuf);
+  swtch(&cp->context, &cpus[cpu()].context);
 }
 
 // Give up the CPU for one scheduling round.
@@ -458,7 +456,7 @@ procdump(void)
       state = "???";
     cprintf("%d %s %s", p->pid, state, p->name);
     if(p->state == SLEEPING) {
-      getcallerpcs((uint*)p->jmpbuf.ebp+2, pc);
+      getcallerpcs((uint*)p->context.ebp+2, pc);
       for(j=0; j<10 && pc[j] != 0; j++)
         cprintf(" %p", pc[j]);
     }
diff --git a/proc.h b/proc.h
index 84dc57d09f18e20b0f2ca01b9e726d61c688c7a1..f76e2641dbc5f231f6e236c1a75cc72e22297eac 100644 (file)
--- a/proc.h
+++ b/proc.h
 // Don't need to save all the %fs etc. segment registers,
 // because they are constant across kernel contexts.
 // Save all the regular registers so we don't need to care
-// which are caller save.
-// Don't save %eax, because that's the return register.
-// The layout of jmpbuf must match code in setjmp.S.
-struct jmpbuf {
+// which are caller save, but not the return register %eax.
+// (Not saving %eax just simplifies the switching code.)
+// The layout of context must match code in swtch.S.
+struct context {
+  int eip;
+  int esp;
   int ebx;
   int ecx;
   int edx;
   int esi;
   int edi;
-  int esp;
   int ebp;
-  int eip;
 };
 
 enum proc_state { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
@@ -38,7 +38,7 @@ struct proc {
   int killed;               // If non-zero, have been killed
   struct file *ofile[NOFILE];  // Open files
   struct inode *cwd;        // Current directory
-  struct jmpbuf jmpbuf;     // Jump here to run process
+  struct context context;   // Switch here to run process
   struct trapframe *tf;     // Trap frame for current interrupt
   char name[16];            // Process name (debugging)
 };
@@ -61,7 +61,7 @@ extern struct proc *curproc[NCPU];  // Current (running) process per CPU
 // Per-CPU state
 struct cpu {
   uchar apicid;               // Local APIC ID
-  struct jmpbuf jmpbuf;       // Jump here to enter scheduler
+  struct context context;     // Switch here to enter scheduler
   struct taskstate ts;        // Used by x86 to find stack for interrupt
   struct segdesc gdt[NSEGS];  // x86 global descriptor table
   char mpstack[MPSTACK];      // Per-CPU startup stack
index 80c8f35440f28df95b75df25e3e1b63c4c0805ef..cbc8fca4c5a602c3baa618aa5a71f2b0f4d748fc 100644 (file)
@@ -22,7 +22,7 @@ spinlock.c
 # processes
 proc.h
 proc.c
-setjmp.S
+swtch.S
 kalloc.c
 
 # system calls
diff --git a/setjmp.S b/setjmp.S
deleted file mode 100644 (file)
index 3fe23c5..0000000
--- a/setjmp.S
+++ /dev/null
@@ -1,49 +0,0 @@
-#   int  setjmp(struct jmpbuf *jmp);
-#   void longjmp(struct jmpbuf *jmp);
-# 
-# Setjmp saves its stack environment in jmp for later use by longjmp.
-# It returns 0.
-# 
-# Longjmp restores the environment saved by the last call of setjmp.
-# It then causes execution to continue as if the call of setjmp
-# had just returned 1.
-# 
-# The caller of setjmp must not itself have returned in the interim.
-# All accessible data have values as of the time longjmp was called.
-#
-#    [Description, but not code, borrowed from Plan 9.]
-
-.globl setjmp
-setjmp:
-  movl 4(%esp), %eax
-
-  movl %ebx, 0(%eax)
-  movl %ecx, 4(%eax)
-  movl %edx, 8(%eax)
-  movl %esi, 12(%eax)
-  movl %edi, 16(%eax)
-  movl %esp, 20(%eax)
-  movl %ebp, 24(%eax)
-  pushl 0(%esp)   # %eip
-  popl 28(%eax)
-
-  movl $0, %eax   # return value
-  ret
-
-.globl longjmp
-longjmp:
-  movl 4(%esp), %eax
-
-  movl 0(%eax), %ebx
-  movl 4(%eax), %ecx
-  movl 8(%eax), %edx
-  movl 12(%eax), %esi
-  movl 16(%eax), %edi
-  movl 20(%eax), %esp
-  movl 24(%eax), %ebp
-
-  addl $4, %esp   # pop and discard %eip
-  pushl 28(%eax)  # push new %eip
-
-  movl $1, %eax   # return value (appears to come from setjmp!)
-  ret
diff --git a/swtch.S b/swtch.S
new file mode 100644 (file)
index 0000000..786e9ac
--- /dev/null
+++ b/swtch.S
@@ -0,0 +1,32 @@
+#   void swtch(struct context *old, struct context *new);
+#  
+# Save current register context in old
+# and then load register context from new.
+
+.globl swtch
+swtch:
+  # Save old registers
+  movl 4(%esp), %eax
+
+  popl 0(%eax)  # %eip
+  movl %esp, 4(%eax)
+  movl %ebx, 8(%eax)
+  movl %ecx, 12(%eax)
+  movl %edx, 16(%eax)
+  movl %esi, 20(%eax)
+  movl %edi, 24(%eax)
+  movl %ebp, 28(%eax)
+
+  # Load new registers
+  movl 4(%esp), %eax  # not 8(%esp) - popped return address above
+
+  movl 28(%eax), %ebp
+  movl 24(%eax), %edi
+  movl 20(%eax), %esi
+  movl 16(%eax), %edx
+  movl 12(%eax), %ecx
+  movl 8(%eax), %ebx
+  movl 4(%eax), %esp
+  pushl 0(%eax)  # %eip
+
+  ret