From ce2e7515552adca3a60e349de2931112736d17bf Mon Sep 17 00:00:00 2001
From: rsc <rsc>
Date: Thu, 27 Sep 2007 20:29:50 +0000
Subject: [PATCH] test: store curproc at top of stack

I don't actually think this is worthwhile, but I figured
I would check it in before reverting it, so that it can
be in the revision history.

Pros:
  * curproc doesn't need to turn on/off interrupts
  * scheduler doesn't have to edit curproc anymore

Cons:
  * it's ugly
  * all the stack computation is more complicated.
  * it doesn't actually simplify anything but curproc,
    and even curproc is harder to follow.
---
 main.c |  8 +++++---
 proc.c | 17 +++++++----------
 proc.h |  5 ++++-
 3 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/main.c b/main.c
index 464112b..0f1acc8 100644
--- a/main.c
+++ b/main.c
@@ -42,12 +42,14 @@ main(void)
   userinit();      // first user process
 
   // Allocate scheduler stacks and boot the other CPUs.
-  for(i=0; i<ncpu; i++)
+  for(i=0; i<ncpu; i++){
     cpus[i].stack = kalloc(KSTACKSIZE);
+    *(void**)(cpus[i].stack + KSTACKTOP) = 0;
+  }
   bootothers();
 
   // Switch to our scheduler stack and continue with mpmain.
-  asm volatile("movl %0, %%esp" : : "r" (cpus[bcpu].stack+KSTACKSIZE));
+  asm volatile("movl %0, %%esp" : : "r" (cpus[bcpu].stack+KSTACKTOP));
   mpmain();
 }
 
@@ -84,7 +86,7 @@ bootothers(void)
       continue;
 
     // Fill in %esp, %eip and start code on cpu.
-    *(void**)(code-4) = c->stack + KSTACKSIZE;
+    *(void**)(code-4) = c->stack + KSTACKTOP;
     *(void**)(code-8) = mpmain;
     lapic_startap(c->apicid, (uint)code);
 
diff --git a/proc.c b/proc.c
index e139c39..d937258 100644
--- a/proc.c
+++ b/proc.c
@@ -75,7 +75,7 @@ setupsegs(struct proc *p)
   c = &cpus[cpu()];
   c->ts.ss0 = SEG_PROCSTACK << 3;
   if(p)
-    c->ts.esp0 = (uint)(p->kstack + KSTACKSIZE);
+    c->ts.esp0 = (uint)(p->kstack + KSTACKTOP);
   else
     c->ts.esp0 = 0xffffffff;
 
@@ -118,7 +118,8 @@ copyproc(struct proc *p)
     np->state = UNUSED;
     return 0;
   }
-  np->tf = (struct trapframe*)(np->kstack + KSTACKSIZE) - 1;
+  *(void**)(np->kstack + KSTACKTOP) = np;
+  np->tf = (struct trapframe*)(np->kstack + KSTACKTOP) - 1;
 
   if(p){  // Copy process state from p.
     np->parent = p;
@@ -187,12 +188,10 @@ userinit(void)
 struct proc*
 curproc(void)
 {
-  struct proc *p;
+  uint esp;
 
-  pushcli();
-  p = cpus[cpu()].curproc;
-  popcli();
-  return p;
+  asm volatile("movl %%esp, %0" : "=a" (esp));
+  return *(struct proc**)((esp & ~(KSTACKSIZE-1)) + KSTACKTOP);
 }
 
 //PAGEBREAK: 42
@@ -223,14 +222,12 @@ scheduler(void)
       // Switch to chosen process.  It is the process's job
       // to release proc_table_lock and then reacquire it
       // before jumping back to us.
-      c->curproc = p;
       setupsegs(p);
       p->state = RUNNING;
       swtch(&c->context, &p->context);
 
       // Process is done running for now.
       // It should have changed its p->state before coming back.
-      c->curproc = 0;
       setupsegs(0);
     }
 
@@ -239,7 +236,7 @@ scheduler(void)
 }
 
 // Enter scheduler.  Must already hold proc_table_lock
-// and have changed curproc[cpu()]->state.
+// and have changed cp->state.
 void
 sched(void)
 {
diff --git a/proc.h b/proc.h
index 2063baa..a2abb82 100644
--- a/proc.h
+++ b/proc.h
@@ -46,6 +46,10 @@ struct proc {
   char name[16];            // Process name (debugging)
 };
 
+// The word at kstack + KSTACKTOP is a pointer to the struct proc.
+#define KSTACKTOP (KSTACKSIZE-4)
+
+
 // Process memory is laid out contiguously, low addresses first:
 //   text
 //   original data and bss
@@ -55,7 +59,6 @@ struct proc {
 // Per-CPU state
 struct cpu {
   uchar apicid;               // Local APIC ID
-  struct proc *curproc;       // Process currently running.
   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
-- 
GitLab