diff options
Diffstat (limited to 'kernel/util')
-rw-r--r-- | kernel/util/mutex.c | 68 |
1 files changed, 18 insertions, 50 deletions
diff --git a/kernel/util/mutex.c b/kernel/util/mutex.c index 8e85f8f..997d85d 100644 --- a/kernel/util/mutex.c +++ b/kernel/util/mutex.c @@ -21,13 +21,6 @@ void mutex_init(void) 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) @@ -38,70 +31,45 @@ struct Mutex* create_mutex(void* addr) struct Mutex* m = e->value; m->pid = 0; m->addr = addr; - push_to_queue(e, &mutex_manager.used); + mutex_manager.used_mutexes++; return e->value; } unsigned char delete_mutex(struct Mutex* m) { - struct Entry* entry = find_value(m, &mutex_manager.used); - if (entry == 0) + unsigned long spacing = (unsigned long)&mutexs[1] - (unsigned long)&mutexs[0]; + unsigned long difference = (unsigned long)m - (unsigned long)&mutexs[0]; + unsigned long index = difference/spacing; + if (index >= MAX_MUTEXS) return 1; - // Remove it from the queue - struct Entry* theentry = remove_next_from_queue(entry); + struct Entry* entry = &mutex_entries[index]; // Add it to the free queue - prepend_to_queue(theentry, &mutex_manager.free); + prepend_to_queue(entry, &mutex_manager.free); return 0; } void uart_mutexes(void) { - struct Entry* entry = mutex_manager.used.start.next; - while (entry->entry_type == VALUE_ENTRY) - { - struct Mutex* m = entry->value; - uart_hex((unsigned long)m); - uart_char(' '); - uart_hex(m->pid); - uart_char(' '); - uart_hexn((unsigned long)m->addr); - entry = entry->next; - } - unsigned long count = 0; - entry = mutex_manager.free.start.next; - while (entry->entry_type == VALUE_ENTRY) { - count++; - entry = entry->next; - } - uart_hexn(count); + uart_hexn(mutex_manager.used_mutexes); } -void lock_mutex(struct Mutex* m) +unsigned char lock_mutex(struct Mutex* m) { struct Thread* rthread = scheduler.rthread; - unsigned long rpid = rthread->pid; unsigned long mode = getmode() & 0x1F; if (mode == 0x10) { - // Find this mutex - struct Entry* mentry = find_value(m, &mutex_manager.used); + unsigned long spacing = (unsigned long)&mutexs[1] - (unsigned long)&mutexs[0]; + unsigned long difference = (unsigned long)m - (unsigned long)&mutexs[0]; + unsigned long index = difference/spacing; // If it is not a managed mutex, break away - if (mentry == 0) - return; - struct Entry* entry = mutex_manager.used.start.next; - // Ensure this thread locks all mutexs sequentially - // To avoid a deadlock - while (entry->entry_type == VALUE_ENTRY) { - struct Mutex* vmutex = entry->value; - // If this thread had locked it - // Toggle the lock to prevent deadlock - if (vmutex->pid == rpid) { - sys1(SYS_UNLOCK, vmutex); - sys1(SYS_LOCK, vmutex); - } - entry = entry->next; - } + if (index >= MAX_MUTEXS) + return 1; + if ((unsigned char) index > rthread->highest_mutex) + return 2; sys1(SYS_LOCK, m); + return 0; } + return 3; } void unlock_mutex(struct Mutex* m) |