blob: 7e9b05ec6177d8f074ff7bda3c4a90e9cf6f7d14 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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;
}
}
|