From 70556fc300ba85dad248d20b3c79c415e2ef88e5 Mon Sep 17 00:00:00 2001 From: Egor Ananyin Date: Sat, 20 Jun 2020 09:14:40 +0300 Subject: Begin decompiling OS_mutex --- arm7/arm7.lsf | 1 + arm7/asm/OS_mutex.s | 131 -------------------------------------- arm7/asm/OS_mutex_s.s | 121 +++++++++++++++++++++++++++++++++++ arm7/lib/include/OS_mutex.h | 9 +++ arm7/lib/src/OS_mutex.c | 8 +++ include/nitro/OS_context_shared.h | 25 ++++++++ include/nitro/OS_mutex_shared.h | 14 ++++ include/nitro/OS_thread_shared.h | 93 +++++++++++++++++++++++++++ 8 files changed, 271 insertions(+), 131 deletions(-) delete mode 100644 arm7/asm/OS_mutex.s create mode 100644 arm7/asm/OS_mutex_s.s create mode 100644 arm7/lib/include/OS_mutex.h create mode 100644 arm7/lib/src/OS_mutex.c create mode 100644 include/nitro/OS_context_shared.h create mode 100644 include/nitro/OS_mutex_shared.h create mode 100644 include/nitro/OS_thread_shared.h diff --git a/arm7/arm7.lsf b/arm7/arm7.lsf index 46486c4f..e5809c12 100644 --- a/arm7/arm7.lsf +++ b/arm7/arm7.lsf @@ -22,6 +22,7 @@ Autoload WRAM Object OS_thread.o Object OS_context.o Object OS_message.o + Object OS_mutex_s.o Object OS_mutex.o Object OS_init.o Object OS_arena.o diff --git a/arm7/asm/OS_mutex.s b/arm7/asm/OS_mutex.s deleted file mode 100644 index 981842b8..00000000 --- a/arm7/asm/OS_mutex.s +++ /dev/null @@ -1,131 +0,0 @@ - .include "asm/macros.inc" - .include "global.inc" - - .text - - arm_func_start OSi_DequeueItem -OSi_DequeueItem: ; 0x037F99E8 - ldr r2, [r1, #16] - ldr r1, [r1, #20] - cmp r2, #0 - streq r1, [r0, #112] ; 0x70 - strne r1, [r2, #20] - cmp r1, #0 - streq r2, [r0, #108] ; 0x6c - strne r2, [r1, #16] - bx lr - - arm_func_start OSi_EnqueueTail -OSi_EnqueueTail: ; 0x037F9A0C - ldr r2, [r0, #112] ; 0x70 - cmp r2, #0 - streq r1, [r0, #108] ; 0x6c - strne r1, [r2, #16] - str r2, [r1, #20] - mov r2, #0 - str r2, [r1, #16] - str r1, [r0, #112] ; 0x70 - bx lr - - arm_func_start OSi_UnlockAllMutex -OSi_UnlockAllMutex: ; 0x037F9A30 - stmdb sp!, {r4, r5, r6, lr} - mov r6, r0 - add r5, r6, #108 ; 0x6c - mov r4, #0 - b _037F9A58 -_037F9A44: - mov r0, r5 - bl OSi_RemoveMutexLinkFromQueue - str r4, [r0, #12] - str r4, [r0, #8] - bl OS_WakeupThread -_037F9A58: - ldr r0, [r6, #108] ; 0x6c - cmp r0, #0 - bne _037F9A44 - ldmia sp!, {r4, r5, r6, lr} - bx lr - - arm_func_start OS_UnlockMutex -OS_UnlockMutex: ; 0x037F9A6C - stmdb sp!, {r4, r5, lr} - sub sp, sp, #4 - mov r5, r0 - bl OS_DisableInterrupts - mov r4, r0 - ldr r0, _037F9AD8 ; =OSi_ThreadInfo - ldr r0, [r0, #4] - ldr r1, [r5, #8] - cmp r1, r0 - bne _037F9AC4 - ldr r1, [r5, #12] - sub r1, r1, #1 - str r1, [r5, #12] - ldr r1, [r5, #12] - cmp r1, #0 - bne _037F9AC4 - mov r1, r5 - bl OSi_DequeueItem - mov r0, #0 - str r0, [r5, #8] - mov r0, r5 - bl OS_WakeupThread -_037F9AC4: - mov r0, r4 - bl OS_RestoreInterrupts - add sp, sp, #4 - ldmia sp!, {r4, r5, lr} - bx lr -_037F9AD8: .word OSi_ThreadInfo - - arm_func_start OS_LockMutex -OS_LockMutex: ; 0x037F9ADC - stmdb sp!, {r4, r5, r6, r7, lr} - sub sp, sp, #4 - mov r5, r0 - bl OS_DisableInterrupts - mov r4, r0 - ldr r0, _037F9B64 ; =OSi_ThreadInfo - ldr r7, [r0, #4] - mov r6, #0 -_037F9AFC: - ldr r0, [r5, #8] - cmp r0, #0 - bne _037F9B28 - str r7, [r5, #8] - ldr r0, [r5, #12] - add r0, r0, #1 - str r0, [r5, #12] - mov r0, r7 - mov r1, r5 - bl OSi_EnqueueTail - b _037F9B50 -_037F9B28: - cmp r0, r7 - ldreq r0, [r5, #12] - addeq r0, r0, #1 - streq r0, [r5, #12] - beq _037F9B50 - str r5, [r7, #104] ; 0x68 - mov r0, r5 - bl OS_SleepThread - str r6, [r7, #104] ; 0x68 - b _037F9AFC -_037F9B50: - mov r0, r4 - bl OS_RestoreInterrupts - add sp, sp, #4 - ldmia sp!, {r4, r5, r6, r7, lr} - bx lr -_037F9B64: .word OSi_ThreadInfo - - arm_func_start OS_InitMutex -OS_InitMutex: ; 0x037F9B68 - mov r2, #0 - str r2, [r0, #4] - ldr r1, [r0, #4] - str r1, [r0] - str r2, [r0, #8] - str r2, [r0, #12] - bx lr diff --git a/arm7/asm/OS_mutex_s.s b/arm7/asm/OS_mutex_s.s new file mode 100644 index 00000000..22ac4ef6 --- /dev/null +++ b/arm7/asm/OS_mutex_s.s @@ -0,0 +1,121 @@ + .include "asm/macros.inc" + .include "global.inc" + + .text + + arm_func_start OSi_DequeueItem +OSi_DequeueItem: ; 0x037F99E8 + ldr r2, [r1, #16] + ldr r1, [r1, #20] + cmp r2, #0 + streq r1, [r0, #112] ; 0x70 + strne r1, [r2, #20] + cmp r1, #0 + streq r2, [r0, #108] ; 0x6c + strne r2, [r1, #16] + bx lr + + arm_func_start OSi_EnqueueTail +OSi_EnqueueTail: ; 0x037F9A0C + ldr r2, [r0, #112] ; 0x70 + cmp r2, #0 + streq r1, [r0, #108] ; 0x6c + strne r1, [r2, #16] + str r2, [r1, #20] + mov r2, #0 + str r2, [r1, #16] + str r1, [r0, #112] ; 0x70 + bx lr + + arm_func_start OSi_UnlockAllMutex +OSi_UnlockAllMutex: ; 0x037F9A30 + stmdb sp!, {r4, r5, r6, lr} + mov r6, r0 + add r5, r6, #108 ; 0x6c + mov r4, #0 + b _037F9A58 +_037F9A44: + mov r0, r5 + bl OSi_RemoveMutexLinkFromQueue + str r4, [r0, #12] + str r4, [r0, #8] + bl OS_WakeupThread +_037F9A58: + ldr r0, [r6, #108] ; 0x6c + cmp r0, #0 + bne _037F9A44 + ldmia sp!, {r4, r5, r6, lr} + bx lr + + arm_func_start OS_UnlockMutex +OS_UnlockMutex: ; 0x037F9A6C + stmdb sp!, {r4, r5, lr} + sub sp, sp, #4 + mov r5, r0 + bl OS_DisableInterrupts + mov r4, r0 + ldr r0, _037F9AD8 ; =OSi_ThreadInfo + ldr r0, [r0, #4] + ldr r1, [r5, #8] + cmp r1, r0 + bne _037F9AC4 + ldr r1, [r5, #12] + sub r1, r1, #1 + str r1, [r5, #12] + ldr r1, [r5, #12] + cmp r1, #0 + bne _037F9AC4 + mov r1, r5 + bl OSi_DequeueItem + mov r0, #0 + str r0, [r5, #8] + mov r0, r5 + bl OS_WakeupThread +_037F9AC4: + mov r0, r4 + bl OS_RestoreInterrupts + add sp, sp, #4 + ldmia sp!, {r4, r5, lr} + bx lr +_037F9AD8: .word OSi_ThreadInfo + + arm_func_start OS_LockMutex +OS_LockMutex: ; 0x037F9ADC + stmdb sp!, {r4, r5, r6, r7, lr} + sub sp, sp, #4 + mov r5, r0 + bl OS_DisableInterrupts + mov r4, r0 + ldr r0, _037F9B64 ; =OSi_ThreadInfo + ldr r7, [r0, #4] + mov r6, #0 +_037F9AFC: + ldr r0, [r5, #8] + cmp r0, #0 + bne _037F9B28 + str r7, [r5, #8] + ldr r0, [r5, #12] + add r0, r0, #1 + str r0, [r5, #12] + mov r0, r7 + mov r1, r5 + bl OSi_EnqueueTail + b _037F9B50 +_037F9B28: + cmp r0, r7 + ldreq r0, [r5, #12] + addeq r0, r0, #1 + streq r0, [r5, #12] + beq _037F9B50 + str r5, [r7, #104] ; 0x68 + mov r0, r5 + bl OS_SleepThread + str r6, [r7, #104] ; 0x68 + b _037F9AFC +_037F9B50: + mov r0, r4 + bl OS_RestoreInterrupts + add sp, sp, #4 + ldmia sp!, {r4, r5, r6, r7, lr} + bx lr +_037F9B64: .word OSi_ThreadInfo diff --git a/arm7/lib/include/OS_mutex.h b/arm7/lib/include/OS_mutex.h new file mode 100644 index 00000000..6b8da6a8 --- /dev/null +++ b/arm7/lib/include/OS_mutex.h @@ -0,0 +1,9 @@ +#ifndef GUARD_OS_MUTEX_H +#define GUARD_OS_MUTEX_H + +#include "nitro/OS_mutex_shared.h" +#include "nitro/types.h" + +void OS_InitMutex(OSMutex* mutex); + +#endif diff --git a/arm7/lib/src/OS_mutex.c b/arm7/lib/src/OS_mutex.c new file mode 100644 index 00000000..8fe167f3 --- /dev/null +++ b/arm7/lib/src/OS_mutex.c @@ -0,0 +1,8 @@ +#include "function_target.h" +#include "OS_mutex.h" + +ARM_FUNC void OS_InitMutex(OSMutex* mutex) { + OS_InitThreadQueue(&mutex->queue); + mutex->thread = NULL; + mutex->count = 0; +} diff --git a/include/nitro/OS_context_shared.h b/include/nitro/OS_context_shared.h new file mode 100644 index 00000000..3ec722eb --- /dev/null +++ b/include/nitro/OS_context_shared.h @@ -0,0 +1,25 @@ +#ifndef GUARD_OS_CONTEXT_SHARED_H +#define GUARD_OS_CONTEXT_SHARED_H + +#include "nitro/types.h" + +typedef struct CPContext { + u64 div_numer; + u64 div_denom; + u64 sqrt; + u16 div_mode; + u16 sqrt_mode; +} CPContext; + +typedef struct OSContext +{ + u32 cpsr; + u32 r[13]; + u32 sp; + u32 lr; + u32 pc_plus4; + u32 sp_svc; + CPContext cp_context; +} OSContext; + +#endif diff --git a/include/nitro/OS_mutex_shared.h b/include/nitro/OS_mutex_shared.h new file mode 100644 index 00000000..bd181f55 --- /dev/null +++ b/include/nitro/OS_mutex_shared.h @@ -0,0 +1,14 @@ +#ifndef GUARD_OS_SHARED_MUTEX_H +#define GUARD_OS_SHARED_MUTEX_H + +#include "nitro/types.h" +#include "nitro/OS_thread_shared.h" + +struct OSMutex { + OSThreadQueue queue; + OSThread *thread; + s32 count; + OSMutexLink link; +}; + +#endif diff --git a/include/nitro/OS_thread_shared.h b/include/nitro/OS_thread_shared.h new file mode 100644 index 00000000..5855ee21 --- /dev/null +++ b/include/nitro/OS_thread_shared.h @@ -0,0 +1,93 @@ +#ifndef GUARD_OS_THREAD_SHARED_H +#define GUARD_OS_THREAD_SHARED_H + +#include "nitro/types.h" +#include "nitro/OS_context_shared.h" + +typedef struct OSiAlarm OSAlarm; + +typedef struct _OSThread OSThread; + +typedef struct _OSThreadQueue OSThreadQueue; +typedef struct _OSThreadLink OSThreadLink; +typedef struct _OSMutexQueue OSMutexQueue; +typedef struct _OSMutexLink OSMutexLink; +typedef struct OSMutex OSMutex; + +struct _OSThreadQueue +{ + OSThread *head; + OSThread *tail; +}; + +struct _OSThreadLink +{ + OSThread *prev; + OSThread *next; +}; + +struct _OSMutexQueue +{ + OSMutex *head; + OSMutex *tail; +}; + +struct _OSMutexLink +{ + OSMutex *next; + OSMutex *prev; +}; + +typedef struct OSThreadInfo { + u16 isNeedRescheduling; + u16 irqDepth; + OSThread* current; + OSThread* list; + void* switchCallback; // type: OSSwitchThreadCallback +} OSThreadInfo; + +typedef enum { + OS_THREAD_STATE_WAITING = 0, + OS_THREAD_STATE_READY = 1, + OS_THREAD_STATE_TERMINATED = 2 +} OSThreadState; + +typedef void (*OSSwitchThreadCallback) (OSThread *from, OSThread *to); + +typedef void (*OSThreadDestructor) (void *); + +struct _OSThread +{ + OSContext context; + OSThreadState state; + OSThread *next; + u32 id; + u32 priority; + void *profiler; + + OSThreadQueue *queue; + OSThreadLink link; + + OSMutex *mutex; + OSMutexQueue mutexQueue; + + u32 stackTop; + u32 stackBottom; + u32 stackWarningOffset; + + OSThreadQueue joinQueue; + + void *specific[3]; + OSAlarm *alarmForSleep; + OSThreadDestructor destructor; + void *userParameter; + + u32 systemErrno; +}; + +static inline void OS_InitThreadQueue(OSThreadQueue * queue) +{ + queue->head = queue->tail = NULL; +} + +#endif -- cgit v1.2.3 From 9fba6d2b34c67d4b14bb1a17d0b1d6d5d6d19b08 Mon Sep 17 00:00:00 2001 From: Egor Ananyin Date: Sat, 20 Jun 2020 11:00:20 +0300 Subject: OS_mutext done! --- arm7/arm7.lsf | 1 - arm7/asm/OS_mutex_s.s | 121 -------------------------------------------- arm7/lib/include/OS_mutex.h | 4 ++ arm7/lib/src/OS_mutex.c | 87 +++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 122 deletions(-) delete mode 100644 arm7/asm/OS_mutex_s.s diff --git a/arm7/arm7.lsf b/arm7/arm7.lsf index bfc823a6..cbffa45a 100644 --- a/arm7/arm7.lsf +++ b/arm7/arm7.lsf @@ -22,7 +22,6 @@ Autoload WRAM Object OS_thread.o Object OS_context.o Object OS_message.o - Object OS_mutex_s.o Object OS_mutex.o Object OS_init.o Object OS_arena.o diff --git a/arm7/asm/OS_mutex_s.s b/arm7/asm/OS_mutex_s.s deleted file mode 100644 index 22ac4ef6..00000000 --- a/arm7/asm/OS_mutex_s.s +++ /dev/null @@ -1,121 +0,0 @@ - .include "asm/macros.inc" - .include "global.inc" - - .text - - arm_func_start OSi_DequeueItem -OSi_DequeueItem: ; 0x037F99E8 - ldr r2, [r1, #16] - ldr r1, [r1, #20] - cmp r2, #0 - streq r1, [r0, #112] ; 0x70 - strne r1, [r2, #20] - cmp r1, #0 - streq r2, [r0, #108] ; 0x6c - strne r2, [r1, #16] - bx lr - - arm_func_start OSi_EnqueueTail -OSi_EnqueueTail: ; 0x037F9A0C - ldr r2, [r0, #112] ; 0x70 - cmp r2, #0 - streq r1, [r0, #108] ; 0x6c - strne r1, [r2, #16] - str r2, [r1, #20] - mov r2, #0 - str r2, [r1, #16] - str r1, [r0, #112] ; 0x70 - bx lr - - arm_func_start OSi_UnlockAllMutex -OSi_UnlockAllMutex: ; 0x037F9A30 - stmdb sp!, {r4, r5, r6, lr} - mov r6, r0 - add r5, r6, #108 ; 0x6c - mov r4, #0 - b _037F9A58 -_037F9A44: - mov r0, r5 - bl OSi_RemoveMutexLinkFromQueue - str r4, [r0, #12] - str r4, [r0, #8] - bl OS_WakeupThread -_037F9A58: - ldr r0, [r6, #108] ; 0x6c - cmp r0, #0 - bne _037F9A44 - ldmia sp!, {r4, r5, r6, lr} - bx lr - - arm_func_start OS_UnlockMutex -OS_UnlockMutex: ; 0x037F9A6C - stmdb sp!, {r4, r5, lr} - sub sp, sp, #4 - mov r5, r0 - bl OS_DisableInterrupts - mov r4, r0 - ldr r0, _037F9AD8 ; =OSi_ThreadInfo - ldr r0, [r0, #4] - ldr r1, [r5, #8] - cmp r1, r0 - bne _037F9AC4 - ldr r1, [r5, #12] - sub r1, r1, #1 - str r1, [r5, #12] - ldr r1, [r5, #12] - cmp r1, #0 - bne _037F9AC4 - mov r1, r5 - bl OSi_DequeueItem - mov r0, #0 - str r0, [r5, #8] - mov r0, r5 - bl OS_WakeupThread -_037F9AC4: - mov r0, r4 - bl OS_RestoreInterrupts - add sp, sp, #4 - ldmia sp!, {r4, r5, lr} - bx lr -_037F9AD8: .word OSi_ThreadInfo - - arm_func_start OS_LockMutex -OS_LockMutex: ; 0x037F9ADC - stmdb sp!, {r4, r5, r6, r7, lr} - sub sp, sp, #4 - mov r5, r0 - bl OS_DisableInterrupts - mov r4, r0 - ldr r0, _037F9B64 ; =OSi_ThreadInfo - ldr r7, [r0, #4] - mov r6, #0 -_037F9AFC: - ldr r0, [r5, #8] - cmp r0, #0 - bne _037F9B28 - str r7, [r5, #8] - ldr r0, [r5, #12] - add r0, r0, #1 - str r0, [r5, #12] - mov r0, r7 - mov r1, r5 - bl OSi_EnqueueTail - b _037F9B50 -_037F9B28: - cmp r0, r7 - ldreq r0, [r5, #12] - addeq r0, r0, #1 - streq r0, [r5, #12] - beq _037F9B50 - str r5, [r7, #104] ; 0x68 - mov r0, r5 - bl OS_SleepThread - str r6, [r7, #104] ; 0x68 - b _037F9AFC -_037F9B50: - mov r0, r4 - bl OS_RestoreInterrupts - add sp, sp, #4 - ldmia sp!, {r4, r5, r6, r7, lr} - bx lr -_037F9B64: .word OSi_ThreadInfo diff --git a/arm7/lib/include/OS_mutex.h b/arm7/lib/include/OS_mutex.h index 216da68c..920d5594 100644 --- a/arm7/lib/include/OS_mutex.h +++ b/arm7/lib/include/OS_mutex.h @@ -4,7 +4,11 @@ #include "OS_context.h" #include "nitro/OS_mutex_shared.h" +void OSi_DequeueItem(OSThread * thread, OSMutex * mutex); +void OSi_EnqueueTail(OSThread * thread, OSMutex * mutex); void OS_InitMutex(OSMutex* mutex); +void OS_LockMutex(OSMutex* mutex); +void OS_UnlockMutex(OSMutex* mutex); void OSi_UnlockAllMutex(OSThread * thread); #endif //POKEDIAMOND_ARM7_OS_MUTEX_H 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; + } +} -- cgit v1.2.3 From 3e4a9b1e3d8daa07bae5a82a406099c330211075 Mon Sep 17 00:00:00 2001 From: Egor Ananyin Date: Sat, 20 Jun 2020 11:10:42 +0300 Subject: We don't need this --- include/nitro/OS_context_shared.h | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 include/nitro/OS_context_shared.h diff --git a/include/nitro/OS_context_shared.h b/include/nitro/OS_context_shared.h deleted file mode 100644 index 3ec722eb..00000000 --- a/include/nitro/OS_context_shared.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef GUARD_OS_CONTEXT_SHARED_H -#define GUARD_OS_CONTEXT_SHARED_H - -#include "nitro/types.h" - -typedef struct CPContext { - u64 div_numer; - u64 div_denom; - u64 sqrt; - u16 div_mode; - u16 sqrt_mode; -} CPContext; - -typedef struct OSContext -{ - u32 cpsr; - u32 r[13]; - u32 sp; - u32 lr; - u32 pc_plus4; - u32 sp_svc; - CPContext cp_context; -} OSContext; - -#endif -- cgit v1.2.3