diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-09-09 21:34:28 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-09-09 21:34:28 -0700 |
commit | 9bc2d7b487cc9cb658a8e3785c67bab6bd20cfe5 (patch) | |
tree | e79b9a86ff0c09fdde196dd2a537810cfb065180 | |
parent | 7c15367c10a7f086ef9523065299a982032f1a66 (diff) | |
download | syslinux-9bc2d7b487cc9cb658a8e3785c67bab6bd20cfe5.tar.gz |
core: thread: move most thread state to stack; task switch errno
Move most our thread state to the stack. Task switch the errno
variable.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | core/include/thread.h | 6 | ||||
-rw-r--r-- | core/thread/kill_thread.c | 5 | ||||
-rw-r--r-- | core/thread/start_thread.c | 30 | ||||
-rw-r--r-- | core/thread/thread_asm.S | 22 |
4 files changed, 39 insertions, 24 deletions
diff --git a/core/include/thread.h b/core/include/thread.h index 3b34e154..c8e7f3f1 100644 --- a/core/include/thread.h +++ b/core/include/thread.h @@ -7,10 +7,6 @@ struct semaphore; -struct thread_state { - uint32_t ebx, esp, ebp, esi, edi; -}; - struct thread_list { struct thread_list *next, *prev; }; @@ -25,7 +21,7 @@ struct thread_block { }; struct thread { - struct thread_state state; + void *esp; /* Must be first; stack pointer */ struct thread_list list; struct thread_block *blocked; int prio; diff --git a/core/thread/kill_thread.c b/core/thread/kill_thread.c index ed2e05f4..83accee6 100644 --- a/core/thread/kill_thread.c +++ b/core/thread/kill_thread.c @@ -1,6 +1,9 @@ #include "thread.h" #include <limits.h> +extern void __exit_thread(void); +typedef void (*func_ptr)(void); + void kill_thread(struct thread *thread) { irq_state_t irq; @@ -15,7 +18,7 @@ void kill_thread(struct thread *thread) * Muck with the stack so that the next time the thread is run then * we end up going to __exit_thread. */ - *(size_t *)thread->state.esp = (size_t)__exit_thread; + *(func_ptr *)thread->esp = __exit_thread; thread->prio = INT_MIN; block = thread->blocked; diff --git a/core/thread/start_thread.c b/core/thread/start_thread.c index afe7ecfb..29e99722 100644 --- a/core/thread/start_thread.c +++ b/core/thread/start_thread.c @@ -2,7 +2,16 @@ #include <stdlib.h> #include "thread.h" -extern void (*__start_thread)(void); +extern void __start_thread(void); + +/* + * Stack frame used by __switch_to, see thread_asm.S + */ +struct thread_stack { + int errno; + uint32_t edi, esi, ebp, ebx; + void (*eip)(void); +}; struct thread *start_thread(size_t stack_size, int prio, void (*start_func)(void *), void *func_arg) @@ -10,23 +19,28 @@ struct thread *start_thread(size_t stack_size, int prio, irq_state_t irq; struct thread *curr, *t; char *stack; - const size_t thread_mask = __alignof__(struct thread)-1; + const size_t thread_mask = 31; /* Alignment mask */ + struct thread_stack *sp; stack_size = (stack_size + thread_mask) & ~thread_mask; stack = malloc(stack_size + sizeof(struct thread)); if (!stack) return NULL; - t = (struct thread *)(stack + stack_size); + t = (struct thread *)stack; + stack = (char *)(t + 1); /* After the thread structure */ memset(t, 0, sizeof *t); - t->state.esp = (((size_t)stack + stack_size) & ~3) - 4; - *(size_t *)t->state.esp = (size_t)&__start_thread; + /* sp allocated from the end of the stack */ + sp = (struct thread_stack *)(stack + stack_size) - 1; + t->esp = sp; - t->state.esi = (size_t)start_func; - t->state.edi = (size_t)func_arg; - t->state.ebx = irq_state(); /* Inherit the IRQ state from the spawner */ + sp->errno = 0; + sp->esi = (size_t)start_func; + sp->edi = (size_t)func_arg; + sp->ebx = irq_state(); /* Inherit the IRQ state from the spawner */ + sp->eip = __start_thread; t->prio = prio; irq = irq_save(); diff --git a/core/thread/thread_asm.S b/core/thread/thread_asm.S index 64f9c9b9..34843a51 100644 --- a/core/thread/thread_asm.S +++ b/core/thread/thread_asm.S @@ -2,18 +2,20 @@ .type __switch_to, @function __switch_to: movl __current, %edx - movl %ebx, (%edx) - movl %esp, 4(%edx) - movl %ebp, 8(%edx) - movl %esi, 12(%edx) - movl %edi, 16(%edx) + pushl %ebx + pushl %ebp + pushl %esi + pushl %edi + pushl errno /* Hack! */ + movl %esp, (%edx) - movl (%eax), %ebx - movl 4(%eax), %esp - movl 8(%eax), %ebp - movl 12(%eax), %esi - movl 16(%eax), %edi movl %eax, __current + movl (%eax), %esp + popl errno + popl %edi + popl %esi + popl %ebp + popl %ebx ret .size __switch_to, .-__switch_to |