[syslinux:lwip] core: thread: move most thread state to stack; task switch errno
syslinux-bot for H. Peter Anvin
hpa at zytor.com
Fri Apr 22 20:05:06 PDT 2011
Commit-ID: 6f2535876ff37db8a4a215f0e06a88b2671be0bc
Gitweb: http://syslinux.zytor.com/commit/6f2535876ff37db8a4a215f0e06a88b2671be0bc
Author: H. Peter Anvin <hpa at zytor.com>
AuthorDate: Wed, 9 Sep 2009 21:34:28 -0700
Committer: Eric W. Biederman <ebiederm at xmission.com>
CommitDate: Sat, 9 Apr 2011 18:27:06 -0700
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 at zytor.com>
---
core/include/thread.h | 6 +-----
core/thread/kill_thread.c | 5 ++++-
core/thread/start_thread.c | 30 ++++++++++++++++++++++--------
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 514c30b..e644b9f 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 ed2e05f..83accee 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 afe7ecf..29e9972 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 64f9c9b..34843a5 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
More information about the Syslinux-commits
mailing list