From: Ben Pfaff Date: Thu, 26 Aug 2004 21:53:33 +0000 (+0000) Subject: More clean up stack frame handling. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=987024569c1e5e9468238849dd79ec8d386352e6;p=pintos-anon More clean up stack frame handling. --- diff --git a/src/threads/switch.S b/src/threads/switch.S index 5b661ec..b00823a 100644 --- a/src/threads/switch.S +++ b/src/threads/switch.S @@ -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 diff --git a/src/threads/switch.h b/src/threads/switch.h index c285e78..c9ae4ab 100644 --- a/src/threads/switch.h +++ b/src/threads/switch.h @@ -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. */ diff --git a/src/threads/thread.c b/src/threads/thread.c index 52f566a..04b446f 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -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