arm9 OS_mutex

This commit is contained in:
red031000
2020-07-27 16:54:00 +01:00
committed by PikalaxALT
parent 1de7208cff
commit 30586b4e9f
6 changed files with 161 additions and 18 deletions

View File

@@ -4,20 +4,10 @@
#include "OS_context.h"
#include "nitro/OS_thread_shared.h"
static s32 OSi_GetUnusedThreadId(void);
static void OSi_InsertLinkToQueue(OSThreadQueue *queue, OSThread *thread);
static OSThread *OSi_RemoveLinkFromQueue(OSThreadQueue *queue);
static OSThread *OSi_RemoveSpecifiedLinkFromQueue(OSThreadQueue *queue, OSThread *thread);
OSMutex *OSi_RemoveMutexLinkFromQueue(OSMutexQueue *queue);
static void OSi_InsertThreadToList(OSThread *thread);
static void OSi_RemoveThreadFromList(OSThread *thread);
static void OSi_RescheduleThread(void);
void OS_InitThread(void);
void OS_CreateThread(OSThread *thread, void (*func) (void *), void *arg, void *stack, u32 stackSize, u32 prio);
void OS_ExitThread(void);
static void OSi_ExitThread_ArgSpecified(OSThread *thread, void *arg);
static void OSi_ExitThread(void *arg);
static void OSi_ExitThread_Destroy(void);
void OS_JoinThread(OSThread *thread);
BOOL OS_IsThreadTerminated(const OSThread *thread);
void OS_SleepThread(OSThreadQueue *queue);
@@ -27,7 +17,6 @@ OSThread *OS_SelectThread(void);
void OS_RescheduleThread(void);
BOOL OS_SetThreadPriority(OSThread *thread, u32 prio);
void OS_Sleep(u32 msec);
static void OSi_SleepAlarmCallback(void *arg);
OSSwitchThreadCallback OS_SetSwitchThreadCallback(OSSwitchThreadCallback callback);
u32 OS_DisableScheduler(void);
u32 OS_EnableScheduler(void);

View File

@@ -29,6 +29,18 @@ static s32 OSi_ThreadIdCount = 0;
OSThread OSi_LauncherThread;
OSThread OSi_IdleThread;
static s32 OSi_GetUnusedThreadId(void);
static void OSi_InsertLinkToQueue(OSThreadQueue *queue, OSThread *thread);
static OSThread *OSi_RemoveLinkFromQueue(OSThreadQueue *queue);
static OSThread *OSi_RemoveSpecifiedLinkFromQueue(OSThreadQueue *queue, OSThread *thread);
static void OSi_InsertThreadToList(OSThread *thread);
static void OSi_RemoveThreadFromList(OSThread *thread);
static void OSi_RescheduleThread(void);
static void OSi_ExitThread_ArgSpecified(OSThread *thread, void *arg);
static void OSi_ExitThread(void *arg);
static void OSi_ExitThread_Destroy(void);
static void OSi_SleepAlarmCallback(void *arg);
ARM_FUNC static s32 OSi_GetUnusedThreadId(void)
{
return ++OSi_ThreadIdCount;

View File

@@ -4,7 +4,14 @@
#include "OS_thread.h"
#include "OS_context.h"
#include "nitro/OS_mutex_shared.h"
#include "nitro/types.h"
void OS_InitMutex(OSMutex *mutex);
void OS_LockMutex(OSMutex *mutex);
void OS_UnlockMutex(OSMutex *mutex);
void OSi_UnlockAllMutex(OSThread * thread);
BOOL OS_TryLockMutex(OSMutex *mutex);
void OSi_EnqueueTail(OSThread *thread, OSMutex *mutex);
void OSi_DequeueItem(OSThread *thread, OSMutex *mutex);
#endif //POKEDIAMOND_ARM9_OS_MUTEX_H

142
arm9/lib/src/OS_mutex.c Normal file
View File

@@ -0,0 +1,142 @@
#include "nitro/types.h"
#include "function_target.h"
#include "OS_mutex.h"
#include "OS_system.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 prevIntrMode = OS_DisableInterrupts();
OSThread *currentThread = OS_GetCurrentThread();
OSThread *ownerThread;
for (;;)
{
ownerThread = ((volatile OSMutex *)mutex)->thread;
if (ownerThread == NULL)
{
mutex->thread = currentThread;
mutex->count++;
OSi_EnqueueTail(currentThread, mutex);
break;
}
else if (ownerThread == currentThread)
{
mutex->count++;
break;
}
else
{
currentThread->mutex = mutex;
OS_SleepThread(&mutex->queue);
currentThread->mutex = NULL;
}
}
(void)OS_RestoreInterrupts(prevIntrMode);
}
ARM_FUNC void OS_UnlockMutex(OSMutex *mutex)
{
OSIntrMode prevIntrMode = OS_DisableInterrupts();
OSThread *currentThread = OS_GetCurrentThread();
if (mutex->thread == currentThread && --mutex->count == 0)
{
OSi_DequeueItem(currentThread, mutex);
mutex->thread = NULL;
OS_WakeupThread(&mutex->queue);
}
(void)OS_RestoreInterrupts(prevIntrMode);
}
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 BOOL OS_TryLockMutex(OSMutex *mutex)
{
OSIntrMode prevIntrMode = OS_DisableInterrupts();
OSThread *currentThread = OS_GetCurrentThread();
BOOL locked;
if (mutex->thread == NULL)
{
mutex->thread = currentThread;
mutex->count++;
OSi_EnqueueTail(currentThread, mutex);
locked = TRUE;
}
else if (mutex->thread == currentThread)
{
mutex->count++;
locked = TRUE;
}
else
{
locked = FALSE;
}
(void)OS_RestoreInterrupts(prevIntrMode);
return locked;
}
ARM_FUNC void OSi_EnqueueTail(OSThread *thread, OSMutex *mutex)
{
OSMutex *prev = thread->mutexQueue.tail;
if (!prev)
{
thread->mutexQueue.head = mutex;
}
else
{
prev->link.next = mutex;
}
mutex->link.prev = prev;
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)
{
thread->mutexQueue.tail = prev;
}
else
{
next->link.prev = prev;
}
if(!prev)
{
thread->mutexQueue.head = next;
}
else
{
prev->link.next = next;
}
}

View File

@@ -1,8 +1,6 @@
#include "SND_bank.h"
#include "OS_mutex.h"
void OS_LockMutex(struct OSMutex *);
void OS_UnlockMutex(struct OSMutex *);
void DC_StoreRange(const void *, u32);
/*

View File

@@ -8,11 +8,6 @@
static struct OSMutex sSndMutex;
static s32 sSndInitialized;
// TODO remove these declarations once we have the functions in the headers
void OS_InitMutex(struct OSMutex *);
void OS_UnlockMutex(struct OSMutex *);
void OS_LockMutex(struct OSMutex *);
ARM_FUNC void SND_Init(void) {
if (sSndInitialized)
return;