forked from devkitPro/libogc
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlwpc_sem.c
More file actions
74 lines (59 loc) · 1.18 KB
/
lwpc_sem.c
File metadata and controls
74 lines (59 loc) · 1.18 KB
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
#include "lwpc_common.h"
#include <ogc/semaphore.h>
static u64 lwpc_sem_used;
static s32 lwpc_sem_table[64];
static KThrQueue lwpc_sem_queue;
s32 LWP_SemInit(sem_t* sem, u32 start, u32 max)
{
int slot = lwpc_alloc_slot(&lwpc_sem_used);
if (slot < 0) {
*sem = LWP_SEM_NULL;
return -1;
}
*sem = slot+1;
lwpc_sem_table[slot] = start;
return 0;
}
s32 LWP_SemDestroy(sem_t sem)
{
if (!sem || sem == LWP_SEM_NULL) {
return -1;
}
lwpc_free_slot(&lwpc_sem_used, sem-1);
return 0;
}
s32 LWP_SemWait(sem_t sem)
{
if (!sem || sem == LWP_SEM_NULL) {
return -1;
}
s32* obj = &lwpc_sem_table[sem-1];
PPCIrqState st = PPCIrqLockByMsr();
if (--(*obj) < 0) {
KThrQueueBlock(&lwpc_sem_queue, sem);
}
PPCIrqUnlockByMsr(st);
return 0;
}
s32 LWP_SemGetValue(sem_t sem, u32* value)
{
if (!sem || sem == LWP_SEM_NULL) {
return -1;
}
s32* obj = &lwpc_sem_table[sem-1];
*value = *obj >= 0 ? *obj : 0;
return 0;
}
s32 LWP_SemPost(sem_t sem)
{
if (!sem || sem == LWP_SEM_NULL) {
return -1;
}
s32* obj = &lwpc_sem_table[sem-1];
PPCIrqState st = PPCIrqLockByMsr();
if ((*obj)++ < 0) {
KThrQueueUnblockOneByValue(&lwpc_sem_queue, sem);
}
PPCIrqUnlockByMsr(st);
return 0;
}