diff options
-rw-r--r-- | include/sys/schedule.h | 1 | ||||
-rw-r--r-- | src/cpu/irq.c | 2 | ||||
-rw-r--r-- | src/sys/schedule.c | 42 | ||||
-rw-r--r-- | src/tests/test.c | 1 |
4 files changed, 43 insertions, 3 deletions
diff --git a/include/sys/schedule.h b/include/sys/schedule.h index a6e03a9..33d19dd 100644 --- a/include/sys/schedule.h +++ b/include/sys/schedule.h @@ -54,6 +54,7 @@ struct Scheduler { }; void init_scheduler(void); +unsigned char add_thread_without_duplicate(void* pc, void* arg, unsigned char priority); unsigned char add_thread(void* pc, void* arg, unsigned char priority); void uart_scheduler(void); struct Thread* next_thread(void); 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); } |