aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cpu/irq.c2
-rw-r--r--src/sys/schedule.c42
-rw-r--r--src/tests/test.c1
3 files changed, 42 insertions, 3 deletions
diff --git a/src/cpu/irq.c b/src/cpu/irq.c
index 80ca7dd..694742a 100644
--- a/src/cpu/irq.c
+++ b/src/cpu/irq.c
@@ -61,7 +61,7 @@ void c_irq_handler(void)
static char timer_lock = 0;
if (!timer_lock) {
timer_lock = 1;
- add_thread(test_entry, 0, 2);
+ add_thread_without_duplicate(test_entry, 0, 2);
timer_lock = 0;
}
*nexttime = *timer_chi + 8000000;
diff --git a/src/sys/schedule.c b/src/sys/schedule.c
index ea677e4..75e7d91 100644
--- a/src/sys/schedule.c
+++ b/src/sys/schedule.c
@@ -175,6 +175,22 @@ struct ThreadEntry* find_mutex_wait_next(void* m)
return 0;
}
+struct ThreadEntry* find_signal_wait_next(void* m)
+{
+ for (unsigned char p = 0; p < PRIORITIES; p++) {
+ struct ThreadQueue* queue = &scheduler.swait[p];
+ struct ThreadEntry* prev = &queue->start;
+ struct ThreadEntry* entry = prev->next;
+ while (entry->entry_type != END_ENTRY) {
+ if (entry->thread->mptr == m)
+ return prev;
+ prev = entry;
+ entry = entry->next;
+ }
+ }
+ return 0;
+}
+
struct Thread* get_unused_thread(void)
{
for(unsigned long i = 0; i < MAX_THREADS; i++) {
@@ -184,6 +200,28 @@ struct Thread* get_unused_thread(void)
return 0;
}
+unsigned char find_duplicate(void* pc)
+{
+ for (unsigned char p = 0; p < PRIORITIES; p++) {
+ struct ThreadQueue* queue = &scheduler.ready[p];
+ struct ThreadEntry* entry = queue->start.next;
+ while (entry->entry_type == THREAD_ENTRY) {
+ if (entry->thread->pc == pc) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+unsigned char add_thread_without_duplicate(void* pc, void* arg, unsigned char priority)
+{
+ if (!find_duplicate(pc)) {
+ return add_thread(pc, arg, priority);
+ }
+ return 1;
+}
+
unsigned char add_thread(void* pc, void* arg, unsigned char priority)
{
struct Thread* thread = get_unused_thread();
@@ -288,8 +326,6 @@ struct Thread* next_thread(void)
void c_cleanup(void)
{
struct Thread* rt = scheduler.rthread;
- struct ThreadEntry* rte = &thread_entries[rt->offset];
- struct ThreadQueue* queue = &scheduler.ready[rt->priority];
pop_from_queue(THREAD_READY, rt->priority);
// Mark Thread Unused
thread_table[rt->offset] = 0;
@@ -351,6 +387,7 @@ void sched_mutex_yield(void* m)
void sched_mutex_resurrect(void* m)
{
+ // Find any mutex to resurrect
struct ThreadEntry* prev = find_mutex_wait_next(m);
if (prev == 0)
return;
@@ -368,6 +405,7 @@ void sched_mutex_resurrect(void* m)
struct Thread* rthread = scheduler.rthread;
unsigned long p = rthread->priority;
unsigned long op = rthread->old_priority;
+ // Restore the original priority level
if (op != 0xFF) {
struct ThreadEntry* tentry = pop_from_queue(THREAD_READY, p);
push_to_queue(tentry->thread, THREAD_READY, p);
diff --git a/src/tests/test.c b/src/tests/test.c
index 4402ed3..172e411 100644
--- a/src/tests/test.c
+++ b/src/tests/test.c
@@ -109,5 +109,6 @@ void ctest4(void)
void btest(void)
{
+ x = 0;
add_thread(ctest1, 0, 3);
}