From fa64046e54f5af3d482d2dbcb2dcbff3458a952a Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Thu, 17 Mar 2022 20:20:13 -0700 Subject: Implemented semaphore --- include/cpu.h | 2 ++ include/sys/schedule.h | 2 ++ src/sys/schedule.c | 39 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 9bda3e8..393fe2f 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -94,5 +94,7 @@ static inline void* getirqstack(void) #define SYS_FREE_STACK 3 #define SYS_LOCK 4 #define SYS_UNLOCK 5 +#define SYS_SEMAPHORE_P 6 +#define SYS_SEMAPHORE_V 7 #endif diff --git a/include/sys/schedule.h b/include/sys/schedule.h index 12c8fec..d0d938c 100644 --- a/include/sys/schedule.h +++ b/include/sys/schedule.h @@ -62,6 +62,8 @@ extern void schedule(void); extern void cleanup(void); void yield(void); void sched_mutex_yield(void* m); +void sched_semaphore_yield(void* s); void sched_mutex_resurrect(void* m); +void sched_semaphore_resurrect(void* s); #endif diff --git a/src/sys/schedule.c b/src/sys/schedule.c index 0a62350..389aa1d 100644 --- a/src/sys/schedule.c +++ b/src/sys/schedule.c @@ -194,14 +194,14 @@ struct ThreadEntry* find_mutex_wait_next(void* m) return 0; } -struct ThreadEntry* find_signal_wait_next(void* m) +struct ThreadEntry* find_signal_wait_next(void* s) { 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) + if (entry->thread->mptr == s) return prev; prev = entry; entry = entry->next; @@ -404,6 +404,23 @@ void sched_mutex_yield(void* m) } } +void sched_semaphore_yield(void* s) +{ + struct Thread* rthread = scheduler.rthread; + // usrloopthread should not be yielded + if (rthread == &usrloopthread) + return; + unsigned char priority = rthread->priority; + // Signify which lock this thread is waiting for + rthread->mptr = s; + struct ThreadEntry* rt; + // Remove from top of running queue + rt = pop_from_queue(THREAD_READY, priority); + if (rt != 0) + // Push to bottom of wait queue + push_to_queue(rt->thread, THREAD_SWAIT, priority); +} + void sched_mutex_resurrect(void* m) { // Find any mutex to resurrect @@ -432,3 +449,21 @@ void sched_mutex_resurrect(void* m) prepend_to_queue(tentry->thread, THREAD_READY, op); } } + +void sched_semaphore_resurrect(void* s) +{ + // Find any signal/ semaphore to resurrect + struct ThreadEntry* prev = find_signal_wait_next(s); + if (prev == 0) + return; + struct ThreadEntry* entry = prev->next; + struct Thread* thread = entry->thread; + // Resurrect the thread + thread->mptr = 0; + // Remove from wait queue + entry = remove_next_from_queue(prev); + if (entry == 0) + return; + // Add to ready queue + push_to_queue(entry->thread, THREAD_READY, entry->thread->priority); +} -- cgit v1.2.1