From 9a9381bda9c2610cba5d0fd8033d1dd00e9eb02d Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Sun, 5 Jul 2015 14:00:13 -0700 Subject: [PATCH] PSP2: Add (untested) threading implementation --- src/platform/psp2/threading.h | 125 ++++++++++++++++++++++++++++++++++ src/util/threading.h | 2 + 2 files changed, 127 insertions(+) create mode 100644 src/platform/psp2/threading.h diff --git a/src/platform/psp2/threading.h b/src/platform/psp2/threading.h new file mode 100644 index 000000000..6ab950064 --- /dev/null +++ b/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 + +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 diff --git a/src/util/threading.h b/src/util/threading.h index b65708720..a4404927d 100644 --- a/src/util/threading.h +++ b/src/util/threading.h @@ -13,6 +13,8 @@ #include "platform/posix/threading.h" #elif _WIN32 #include "platform/windows/threading.h" +#elif PSP2 +#include "platform/psp2/threading.h" #else #define DISABLE_THREADING #endif