More clean up stack frame handling.
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 26 Aug 2004 21:53:33 +0000 (21:53 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 26 Aug 2004 21:53:33 +0000 (21:53 +0000)
src/threads/switch.S
src/threads/switch.h
src/threads/thread.c

index 5b661ec1f1fd88924704dc95c2238987479dc6ab..b00823af50044cd4e2cfb0a1f73fbd5802d18fd5 100644 (file)
@@ -1,7 +1,7 @@
 #include "switch.h"
 
-        .globl thread_switch 
-thread_switch:
+        .globl switch_threads 
+switch_threads:
        # Save caller's register state.
        # Note that the SVR4 ABI allows us to destroy %eax, %ecx, %edx.
        # This stack frame must match the one set up by thread_create().
@@ -31,3 +31,8 @@ thread_switch:
        popl %ebp
        popl %ebx
         ret
+
+       .globl switch_thunk
+switch_thunk:
+       addl $8, %esp
+       ret
index c285e78164971d5dd7e011d0356599be0d32f328..c9ae4ab8b108bbd2b9165058f36b13dfd0319d6a 100644 (file)
@@ -2,7 +2,7 @@
 #define HEADER_SWITCH_H 1
 
 #ifndef __ASSEMBLER__
-/* thread_switch()'s stack frame. */
+/* switch_thread()'s stack frame. */
 struct switch_frame 
   {
     uint32_t ebx;               /*  0: Saved %ebx. */
@@ -17,7 +17,16 @@ struct switch_frame
 /* Switches from CUR, which must be the running thread, to NEXT,
    which must also be running thread_switch(), returning CUR in
    NEXT's context. */
-struct thread *thread_switch (struct thread *cur, struct thread *next);
+struct thread *switch_threads (struct thread *cur, struct thread *next);
+
+struct switch_thunk_frame 
+  {
+    void (*eip) (void);
+  };
+
+/* Pops the CUR and NEXT arguments off the stack, for use in
+   initializing threads. */
+void switch_thunk (void);
 #endif
 
 /* Offsets used by switch.S. */
index 52f566ac0309802d602da4f6ceb8362fa0a62b74..04b446f9f475d0225b45b4f6e6d797a12defbd87 100644 (file)
@@ -26,8 +26,7 @@ struct thread_root_frame
   };
 
 static void
-thread_root (struct thread *cur UNUSED, struct thread *next UNUSED,
-             void (*function) (void *aux), void *aux) 
+thread_root (void (*function) (void *aux), void *aux) 
 {
   ASSERT (function != NULL);
   
@@ -67,6 +66,7 @@ thread_create (const char *name, void (*function) (void *aux), void *aux)
 {
   struct thread *t;
   struct thread_root_frame *rf;
+  struct switch_thunk_frame *tf;
   struct switch_frame *sf;
 
   ASSERT (function != NULL);
@@ -79,9 +79,13 @@ thread_create (const char *name, void (*function) (void *aux), void *aux)
   rf->function = function;
   rf->aux = aux;
 
+  /* Stack frame for switch_thunk(). */
+  tf = alloc_frame (t, sizeof *tf);
+  tf->eip = (void (*) (void)) thread_root;
+
   /* Stack frame for thread_switch(). */
   sf = alloc_frame (t, sizeof *sf);
-  sf->eip = (void (*) (void)) thread_root;
+  sf->eip = (void (*) (void)) switch_thunk;
 
   /* Add to run queue. */
   thread_ready (t);
@@ -162,7 +166,7 @@ thread_schedule (void)
     idle ();
 
   next->status = THREAD_RUNNING;
-  prev = thread_switch (cur, next);
+  prev = switch_threads (cur, next);
 
   /* Prevent GCC from reordering anything around the thread
      switch. */
@@ -196,7 +200,7 @@ thread_start (struct thread *t)
   if (t->status == THREAD_READY) 
     list_remove (&t->rq_elem);
   t->status = THREAD_RUNNING;
-  thread_switch (NULL, t);
+  switch_threads (NULL, t);
 }
 
 void