From 0c3837ef8fe77b0d65094f6a2cf3d7b17bcc7cbf Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Fri, 18 Mar 2022 13:39:56 -0700 Subject: Added mutex management queues --- include/globals.h | 5 +++-- include/lib/queue.h | 1 + include/util/mutex.h | 7 +++++++ src/globals.c | 3 ++- src/util/mutex.c | 56 ++++++++++++++++++++++++++++++++++++++-------------- 5 files changed, 54 insertions(+), 18 deletions(-) diff --git a/include/globals.h b/include/globals.h index 24bd4f5..6c7e1f1 100644 --- a/include/globals.h +++ b/include/globals.h @@ -13,12 +13,13 @@ extern unsigned long nextpid; extern unsigned long stimel; extern unsigned long stimeh; extern struct Scheduler scheduler; +extern struct MutexManager mutex_manager; extern struct Thread usrloopthread; extern unsigned int gwidth, gheight, gpitch, gisrgb; +extern struct Mutex mutexs[MAX_MUTEXS]; +extern struct Entry mutex_entries[MAX_MUTEXS]; extern struct Thread threads[MAX_THREADS]; extern struct Entry thread_entries[MAX_THREADS]; -extern unsigned long mutex_table[MAX_MUTEXS]; -extern struct Mutex mutexs[MAX_MUTEXS]; #endif #endif diff --git a/include/lib/queue.h b/include/lib/queue.h index 5e57613..1d4899a 100644 --- a/include/lib/queue.h +++ b/include/lib/queue.h @@ -27,6 +27,7 @@ struct Entry* pop_from_queue(struct Queue* q); // Remove the entry after this one from its queue struct Entry* remove_next_from_queue(struct Entry* e); // Find an entry in a queue +// Returns the entry before the target entry struct Entry* find_value(void* value, struct Queue* q); #endif diff --git a/include/util/mutex.h b/include/util/mutex.h index c0dd17b..8ab3235 100644 --- a/include/util/mutex.h +++ b/include/util/mutex.h @@ -1,5 +1,6 @@ #ifndef UTIL_MUTEX_H #define UTIL_MUTEX_H +#include #define NULL_PID 0 #define CORE0_PID 1 @@ -17,6 +18,12 @@ struct Mutex { void* addr; } __attribute__((packed, aligned(4))); +struct MutexManager { + struct Queue free; + struct Queue used; +}; + +void mutex_init(void); struct Mutex* create_mutex(void* addr); unsigned char delete_mutex(struct Mutex* m); diff --git a/src/globals.c b/src/globals.c index 944f01e..5118e96 100644 --- a/src/globals.c +++ b/src/globals.c @@ -12,12 +12,13 @@ __attribute__((section(".bss"))) unsigned long nextpid; __attribute__((section(".bss"))) unsigned long stimel; __attribute__((section(".bss"))) unsigned long stimeh; __attribute__((section(".bss"))) struct Scheduler scheduler; +__attribute__((section(".bss"))) struct MutexManager mutex_manager; __attribute__((section(".bss"))) struct Thread usrloopthread; __attribute__((section(".bss"))) unsigned int gwidth; __attribute__((section(".bss"))) unsigned int gheight; __attribute__((section(".bss"))) unsigned int gpitch; __attribute__((section(".bss"))) unsigned int gisrgb; -__attribute__((section(".bss.mutexl"))) unsigned long mutex_table[MAX_MUTEXS]; __attribute__((section(".bss.mutexs"))) struct Mutex mutexs[MAX_MUTEXS]; +__attribute__((section(".bss.mutexe"))) struct Entry mutex_entries[MAX_MUTEXS]; __attribute__((section(".bss.threads"))) struct Thread threads[MAX_THREADS]; __attribute__((section(".bss.threade"))) struct Entry thread_entries[MAX_THREADS]; diff --git a/src/util/mutex.c b/src/util/mutex.c index 3171501..226bfbc 100644 --- a/src/util/mutex.c +++ b/src/util/mutex.c @@ -1,26 +1,52 @@ #include #include -struct Mutex* create_mutex(void* addr) +void mutex_init(void) { for (unsigned long m = 0; m < MAX_MUTEXS; m++) { - if (mutex_table[m] == 0) { - mutex_table[m] = (unsigned long)addr; - mutexs[m].pid = 0; - mutexs[m].addr = addr; - return &mutexs[m]; - } + mutexs[m].pid = 0; + mutexs[m].addr = 0; + mutex_entries[m].value = &mutexs[m]; + mutex_entries[m].entry_type = VALUE_ENTRY; + mutex_entries[m].next = &mutex_entries[(m+1)%MAX_MUTEXS]; } - return 0; + // Initialize Free Mutexs + mutex_manager.free.start.value = 0; + mutex_manager.free.start.next = &mutex_entries[0]; + mutex_manager.free.start.entry_type = START_ENTRY; + mutex_manager.free.end.value = 0; + mutex_manager.free.end.next = &mutex_entries[MAX_MUTEXS-1]; + mutex_entries[MAX_MUTEXS-1].next = &mutex_manager.free.end; + mutex_manager.free.end.entry_type = END_ENTRY; + // Initialize In-use Mutexs + mutex_manager.used.start.value = 0; + mutex_manager.used.start.next = &mutex_manager.used.end; + mutex_manager.used.start.entry_type = START_ENTRY; + mutex_manager.used.end.value = 0; + mutex_manager.used.end.next = &mutex_manager.used.start; + mutex_manager.used.end.entry_type = END_ENTRY; +} + +struct Mutex* create_mutex(void* addr) +{ + struct Entry* e = pop_from_queue(&mutex_manager.free); + if (e == 0) + return 0; + struct Mutex* m = e->value; + m->pid = 0; + m->addr = addr; + push_to_queue(e, &mutex_manager.used); + return e->value; } unsigned char delete_mutex(struct Mutex* m) { - for (unsigned long i = 0; i < MAX_MUTEXS; i++) { - if (mutex_table[i] == (unsigned long)m->addr) { - mutex_table[i] = 0; - return 0; - } - } - return 1; + struct Entry* entry = find_value(m, &mutex_manager.used); + if (entry == 0) + return 1; + // Remove it from the queue + remove_next_from_queue(entry); + // Add it to the free queue + prepend_to_queue(entry, &mutex_manager.free); + return 0; } -- cgit v1.2.1