summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-09-09 21:34:28 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-09-09 21:34:28 -0700
commit9bc2d7b487cc9cb658a8e3785c67bab6bd20cfe5 (patch)
treee79b9a86ff0c09fdde196dd2a537810cfb065180
parent7c15367c10a7f086ef9523065299a982032f1a66 (diff)
downloadsyslinux-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.h6
-rw-r--r--core/thread/kill_thread.c5
-rw-r--r--core/thread/start_thread.c30
-rw-r--r--core/thread/thread_asm.S22
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