aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/globals.h5
-rw-r--r--include/lib/queue.h1
-rw-r--r--include/util/mutex.h7
-rw-r--r--src/globals.c3
-rw-r--r--src/util/mutex.c56
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 <lib/queue.h>
#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 <util/mutex.h>
#include <globals.h>
-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;
}