[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