[syslinux:lwip] thread: Add magic number, debugging code, min stack size

syslinux-bot for H. Peter Anvin hpa at zytor.com
Fri Mar 30 16:12:03 PDT 2012


Commit-ID:  47b686b858f09b9bcb3949cf1a2d5ad4ca479819
Gitweb:     http://www.syslinux.org/commit/47b686b858f09b9bcb3949cf1a2d5ad4ca479819
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Fri, 30 Mar 2012 16:09:03 -0700
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Fri, 30 Mar 2012 16:09:03 -0700

thread: Add magic number, debugging code, min stack size

Add a magic number to the thread control block; this helps check for
memory overwrites.

Add dprintf()s to the scheduler.

Force a minimum stack size.

Signed-off-by: H. Peter Anvin <hpa at zytor.com>

---
 core/include/thread.h      |    3 +++
 core/thread/root_thread.c  |    1 +
 core/thread/schedule.c     |   33 +++++++++++++++++++++++++++++++--
 core/thread/start_thread.c |    9 ++++++++-
 4 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/core/include/thread.h b/core/include/thread.h
index 85f2daf..6bfdfaa 100644
--- a/core/include/thread.h
+++ b/core/include/thread.h
@@ -39,8 +39,11 @@ struct thread_block {
     bool timed_out;
 };
 
+#define THREAD_MAGIC 0x3568eb7d
+
 struct thread {
     struct thread_stack *esp;	/* Must be first; stack pointer */
+    unsigned int thread_magic;
     const char *name;		/* Name (for debugging) */
     struct thread_list  list;
     struct thread_block *blocked;
diff --git a/core/thread/root_thread.c b/core/thread/root_thread.c
index 60f3492..2bba7c2 100644
--- a/core/thread/root_thread.c
+++ b/core/thread/root_thread.c
@@ -1,6 +1,7 @@
 #include "thread.h"
 
 struct thread __root_thread = {
+    .thread_magic = THREAD_MAGIC,
     .name = "root",
     .list = { .next = &__root_thread.list, .prev = &__root_thread.list },
     .blocked = NULL,
diff --git a/core/thread/schedule.c b/core/thread/schedule.c
index 8991305..67d45aa 100644
--- a/core/thread/schedule.c
+++ b/core/thread/schedule.c
@@ -1,6 +1,7 @@
 #include <sys/cpu.h>
 #include "thread.h"
 #include "core.h"
+#include <dprintf.h>
 
 void (*sched_hook_func)(void);
 
@@ -13,6 +14,13 @@ void __schedule(void)
     struct thread *curr = current();
     struct thread *st, *nt, *best;
 
+#if DEBUG
+    if (unlikely(irq_state() & 0x200)) {
+	dprintf("In __schedule with interrupts on!\n");
+	kaboom();
+    }
+#endif
+
     /*
      * Are we called from inside sched_hook_func()?  If so we'll
      * schedule anyway on the way out.
@@ -20,6 +28,8 @@ void __schedule(void)
     if (in_sched_hook)
 	return;
 
+    dprintf("Schedule ");
+
     /* Possibly update the information on which we make
      * scheduling decisions.
      */
@@ -37,17 +47,36 @@ void __schedule(void)
     best = NULL;
     nt = st = container_of(curr->list.next, struct thread, list);
     do {
-	if (!nt->blocked)
+	if (unlikely(nt->thread_magic != THREAD_MAGIC)) {
+	    dprintf("Invalid thread on thread list %p magic = 0x%08x\n",
+		    nt, nt->thread_magic);
+	    kaboom();
+	}
+
+	dprintf("Thread %p (%s) ", nt, nt->name);
+	if (!nt->blocked) {
+	    dprintf("runnable priority %d\n", nt->prio);
 	    if (!best || nt->prio < best->prio)
 		best = nt;
+	} else {
+	    dprintf("blocked\n");
+	}
 	nt = container_of(nt->list.next, struct thread, list);
     } while (nt != st);
 
     if (!best)
 	kaboom();		/* No runnable thread */
 
-    if (best != curr)
+    if (best != curr) {
+	uint64_t tsc;
+	
+	asm volatile("rdtsc" : "=A" (tsc));
+	
+	dprintf("@ %llu -> %p (%s)\n", tsc, best, best->name);
 	__switch_to(best);
+    } else {
+	dprintf("no change\n");
+    }
 }
 
 /*
diff --git a/core/thread/start_thread.c b/core/thread/start_thread.c
index 328d6e7..2e4320a 100644
--- a/core/thread/start_thread.c
+++ b/core/thread/start_thread.c
@@ -5,6 +5,8 @@
 #include "thread.h"
 
 #define REAL_MODE_STACK_SIZE	4096
+#define MIN_STACK_SIZE		16384
+#define THREAD_ALIGN		64 	/* Thread alignment */
 
 extern void __start_thread(void);
 
@@ -14,9 +16,12 @@ struct thread *start_thread(const char *name, size_t stack_size, int prio,
     irq_state_t irq;
     struct thread *curr, *t;
     char *stack, *rmstack;
-    const size_t thread_mask = 31; /* Alignment mask */
+    const size_t thread_mask = THREAD_ALIGN - 1;
     struct thread_stack *sp;
 
+    if (stack_size < MIN_STACK_SIZE)
+	stack_size = MIN_STACK_SIZE;
+
     stack_size = (stack_size + thread_mask) & ~thread_mask;
     stack = malloc(stack_size + sizeof(struct thread));
     if (!stack)
@@ -50,6 +55,8 @@ struct thread *start_thread(const char *name, size_t stack_size, int prio,
     irq = irq_save();
     curr = current();
 
+    t->thread_magic    = THREAD_MAGIC;
+
     t->list.prev       = &curr->list;
     t->list.next       = curr->list.next;
     curr->list.next    = &t->list;


More information about the Syslinux-commits mailing list