aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Cunningham <cc@localhost>2022-03-17 20:20:13 -0700
committerChristian Cunningham <cc@localhost>2022-03-17 20:20:13 -0700
commitfa64046e54f5af3d482d2dbcb2dcbff3458a952a (patch)
tree870a5e958603ea76ab488c25a99fa8f031f99390
parentc7f1e83a4273403a7974cc412934b7d73ad3297d (diff)
Implemented semaphore
-rw-r--r--include/cpu.h2
-rw-r--r--include/sys/schedule.h2
-rw-r--r--src/sys/schedule.c39
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);
+}