summaryrefslogtreecommitdiff
path: root/arm7/lib/src
diff options
context:
space:
mode:
authorEgor Ananyin <ananinegor@gmail.com>2020-06-20 11:00:20 +0300
committerEgor Ananyin <ananinegor@gmail.com>2020-06-20 11:00:20 +0300
commit9fba6d2b34c67d4b14bb1a17d0b1d6d5d6d19b08 (patch)
tree4fe4daf2baef42c3954f54db7ebe21294a4ba738 /arm7/lib/src
parentabd2d1e16494867989e710e5235c6425fa4e8c34 (diff)
OS_mutext done!
Diffstat (limited to 'arm7/lib/src')
-rw-r--r--arm7/lib/src/OS_mutex.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/arm7/lib/src/OS_mutex.c b/arm7/lib/src/OS_mutex.c
index 8fe167f3..7e9b05ec 100644
--- a/arm7/lib/src/OS_mutex.c
+++ b/arm7/lib/src/OS_mutex.c
@@ -1,8 +1,95 @@
#include "function_target.h"
#include "OS_mutex.h"
+#include "OS_system.h"
+#include "OS_thread.h"
ARM_FUNC void OS_InitMutex(OSMutex* mutex) {
OS_InitThreadQueue(&mutex->queue);
mutex->thread = NULL;
mutex->count = 0;
}
+
+ARM_FUNC void OS_LockMutex(OSMutex* mutex) {
+ OSIntrMode mode;
+ OSThread* current;
+
+ mode = OS_DisableInterrupts();
+ current = OS_GetCurrentThread();
+ while (1) {
+ OSThread* owner = mutex->thread;
+ if (owner == NULL) {
+ mutex->thread = current;
+ mutex->count++;
+ OSi_EnqueueTail(current, mutex);
+ break;
+ }
+ else if (owner == current) {
+ mutex->count++;
+ break;
+ }
+ else {
+ current->mutex = mutex;
+ OS_SleepThread(&mutex->queue);
+ current->mutex = NULL;
+ }
+ }
+ (void)OS_RestoreInterrupts(mode);
+}
+
+ARM_FUNC void OS_UnlockMutex(OSMutex* mutex) {
+ OSIntrMode mode;
+ OSThread* current;
+
+ mode = OS_DisableInterrupts();
+ current = OS_GetCurrentThread();
+ if (mutex->thread == current) {
+ if (--mutex->count == 0) {
+ OSi_DequeueItem(current, mutex);
+ mutex->thread = NULL;
+ OS_WakeupThread(&mutex->queue);
+ }
+ }
+ (void)OS_RestoreInterrupts(mode);
+}
+
+ARM_FUNC void OSi_UnlockAllMutex(OSThread * thread) {
+ OSMutex * mutex;
+ while (thread->mutexQueue.head) {
+ mutex = OSi_RemoveMutexLinkFromQueue(&thread->mutexQueue);
+ mutex->count = 0;
+ mutex->thread = NULL;
+ OS_WakeupThread(&mutex->queue);
+ }
+}
+
+ARM_FUNC void OSi_EnqueueTail(OSThread * thread, OSMutex * mutex) {
+ OSMutex * tail = thread->mutexQueue.tail;
+ if (tail == NULL) {
+ thread->mutexQueue.head = mutex;
+ }
+ else {
+ tail->link.next = mutex;
+ }
+ mutex->link.prev = tail;
+ mutex->link.next = NULL;
+ thread->mutexQueue.tail = mutex;
+}
+
+ARM_FUNC void OSi_DequeueItem(OSThread * thread, OSMutex * mutex) {
+ OSMutex *next = mutex->link.next;
+ OSMutex *prev = mutex->link.prev;
+
+ if (next == NULL) {
+ thread->mutexQueue.tail = prev;
+ }
+ else {
+ next->link.prev = prev;
+ }
+
+ if (prev == NULL) {
+ thread->mutexQueue.head = next;
+ }
+ else {
+ prev->link.next = next;
+ }
+}