diff options
author | H. Peter Anvin <hpa@zytor.com> | 2012-03-30 16:09:03 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2012-03-30 16:13:02 -0700 |
commit | 12b2033fc541241f1b5a286a1a80dd309fe2a708 (patch) | |
tree | cb1b086db734708b092d70a7a6682c50b1f82a9f | |
parent | 9787a5c552d37b26550de38578c338fa92232545 (diff) | |
download | syslinux-12b2033fc541241f1b5a286a1a80dd309fe2a708.tar.gz syslinux-12b2033fc541241f1b5a286a1a80dd309fe2a708.tar.xz syslinux-12b2033fc541241f1b5a286a1a80dd309fe2a708.zip |
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@zytor.com>
-rw-r--r-- | core/include/thread.h | 3 | ||||
-rw-r--r-- | core/thread/root_thread.c | 1 | ||||
-rw-r--r-- | core/thread/schedule.c | 34 | ||||
-rw-r--r-- | core/thread/start_thread.c | 9 |
4 files changed, 44 insertions, 3 deletions
diff --git a/core/include/thread.h b/core/include/thread.h index 85f2dafc..6bfdfaa7 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 60f34927..2bba7c26 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 8991305c..5a426f11 100644 --- a/core/thread/schedule.c +++ b/core/thread/schedule.c @@ -1,6 +1,8 @@ +#include <klibc/compiler.h> #include <sys/cpu.h> #include "thread.h" #include "core.h" +#include <dprintf.h> void (*sched_hook_func)(void); @@ -13,6 +15,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 +29,8 @@ void __schedule(void) if (in_sched_hook) return; + dprintf("Schedule "); + /* Possibly update the information on which we make * scheduling decisions. */ @@ -37,17 +48,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 328d6e7b..2e4320a4 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; |