aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2012-03-30 16:09:03 -0700
committerH. Peter Anvin <hpa@zytor.com>2012-03-30 16:13:02 -0700
commit12b2033fc541241f1b5a286a1a80dd309fe2a708 (patch)
treecb1b086db734708b092d70a7a6682c50b1f82a9f
parent9787a5c552d37b26550de38578c338fa92232545 (diff)
downloadsyslinux-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.h3
-rw-r--r--core/thread/root_thread.c1
-rw-r--r--core/thread/schedule.c34
-rw-r--r--core/thread/start_thread.c9
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;