#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. */
/* 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. */
};
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);
{
struct thread *t;
struct thread_root_frame *rf;
+ struct switch_thunk_frame *tf;
struct switch_frame *sf;
ASSERT (function != NULL);
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);
idle ();
next->status = THREAD_RUNNING;
- prev = thread_switch (cur, next);
+ prev = switch_threads (cur, next);
/* Prevent GCC from reordering anything around the thread
switch. */
if (t->status == THREAD_READY)
list_remove (&t->rq_elem);
t->status = THREAD_RUNNING;
- thread_switch (NULL, t);
+ switch_threads (NULL, t);
}
void