all repos — mgba @ 9a9381bda9c2610cba5d0fd8033d1dd00e9eb02d

mGBA Game Boy Advance Emulator

PSP2: Add (untested) threading implementation
Jeffrey Pfau jeffrey@endrift.com
Sun, 05 Jul 2015 14:00:13 -0700
commit

9a9381bda9c2610cba5d0fd8033d1dd00e9eb02d

parent

883f6dbb483635069ea84c704a3736612427fcd3

2 files changed, 127 insertions(+), 0 deletions(-)

jump to
A src/platform/psp2/threading.h

@@ -0,0 +1,125 @@

+/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef SCE_THREADING_H +#define SCE_THREADING_H + +#include <psp2/kernel/threadmgr.h> + +typedef SceUID Thread; +typedef SceUID Mutex; +typedef struct { + Mutex mutex; + SceUID semaphore; + int waiting; +} Condition; +#define THREAD_ENTRY int +typedef THREAD_ENTRY (*ThreadEntry)(void*); + +static inline int MutexInit(Mutex* mutex) { + Mutex id = sceKernelCreateMutex("mutex", 0, 0, 0); + if (id < 0) { + return id; + } + *mutex = id; + return 0; +} + +static inline int MutexDeinit(Mutex* mutex) { + return sceKernelDeleteMutex(*mutex); +} + +static inline int MutexLock(Mutex* mutex) { + return sceKernelLockMutex(*mutex, 1, 0); +} + +static inline int MutexUnlock(Mutex* mutex) { + return sceKernelUnlockMutex(*mutex, 1); +} + +static inline int ConditionInit(Condition* cond) { + int res = MutexInit(&cond->mutex); + if (res < 0) { + return res; + } + cond->semaphore = sceKernelCreateSema("SceCondSema", 0, 0, 1, 0); + if (cond->semaphore < 0) { + MutexDeinit(&cond->mutex); + res = cond->semaphore; + } + cond->waiting = 0; + return res; +} + +static inline int ConditionDeinit(Condition* cond) { + MutexDeinit(&cond->mutex); + return sceKernelDeleteSema(cond->semaphore); +} + +static inline int ConditionWait(Condition* cond, Mutex* mutex) { + MutexLock(&cond->mutex); + ++cond->waiting; + MutexUnlock(mutex); + MutexUnlock(&cond->mutex); + sceKernelWaitSema(cond->semaphore, 1, 0); + MutexLock(mutex); + return 0; +} + +static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) { + MutexLock(&cond->mutex); + ++cond->waiting; + MutexUnlock(mutex); + MutexUnlock(&cond->mutex); + SceUInt timeout = 0; + if (timeoutMs > 0) { + timeout = timeoutMs; + } + sceKernelWaitSema(cond->semaphore, 1, &timeout); + MutexLock(mutex); + return 0; +} + +static inline int ConditionWake(Condition* cond) { + MutexLock(&cond->mutex); + if (cond->waiting) { + --cond->waiting; + sceKernelSignalSema(cond->semaphore, 1); + } + MutexUnlock(&cond->mutex); + return 0; +} + +struct SceThreadEntryArgs { + void* context; + ThreadEntry entry; +}; + +static inline int _sceThreadEntry(SceSize args, void* argp) { + UNUSED(args); + struct SceThreadEntryArgs* arg = argp; + return arg->entry(arg->context); +} + +static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) { + Thread id = sceKernelCreateThread("SceThread", _sceThreadEntry, 0x10000100, 0x10000, 0, 0, 0); + if (id < 0) { + return id; + } + *thread = id; + struct SceThreadEntryArgs args = { context, entry }; + sceKernelStartThread(id, sizeof(args), &args); + return 0; +} + +static inline int ThreadJoin(Thread thread) { + return sceKernelWaitThreadEnd(thread, 0); +} + +static inline int ThreadSetName(const char* name) { + UNUSED(name); + return -1; +} +#endif
M src/util/threading.hsrc/util/threading.h

@@ -13,6 +13,8 @@ #ifdef USE_PTHREADS

#include "platform/posix/threading.h" #elif _WIN32 #include "platform/windows/threading.h" +#elif PSP2 +#include "platform/psp2/threading.h" #else #define DISABLE_THREADING #endif