From 87a118b6b6cd3162de9ca9b56f927bf235b09f29 Mon Sep 17 00:00:00 2001 From: Ivan Epifanov Date: Wed, 20 Jan 2021 23:33:28 +0300 Subject: [PATCH] Use native mutexes --- src/thread/vita/SDL_sysmutex.c | 97 +++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/src/thread/vita/SDL_sysmutex.c b/src/thread/vita/SDL_sysmutex.c index 6584fb2bf..f91853776 100644 --- a/src/thread/vita/SDL_sysmutex.c +++ b/src/thread/vita/SDL_sysmutex.c @@ -22,17 +22,15 @@ #if SDL_THREAD_VITA -/* An implementation of mutexes using semaphores */ - #include "SDL_thread.h" #include "SDL_systhread_c.h" +#include +#include struct SDL_mutex { - int recursive; - SDL_threadID owner; - SDL_sem *sem; + SceUID uid; }; /* Create a mutex */ @@ -44,13 +42,16 @@ SDL_CreateMutex(void) /* Allocate mutex memory */ mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); if (mutex) { - /* Create the mutex semaphore, with initial value 1 */ - mutex->sem = SDL_CreateSemaphore(1); - mutex->recursive = 0; - mutex->owner = 0; - if (!mutex->sem) { - SDL_free(mutex); - mutex = NULL; + + mutex->uid = sceKernelCreateMutex("SDL mutex", + SCE_KERNEL_MUTEX_ATTR_TH_PRIO | SCE_KERNEL_MUTEX_ATTR_RECURSIVE, + 0, + NULL + ); + + if (mutex->uid <= 0) { + printf("Error creating mutex: %x\n", mutex->uid); + SDL_OutOfMemory(); // TODO: proper error } } else { SDL_OutOfMemory(); @@ -63,37 +64,56 @@ void SDL_DestroyMutex(SDL_mutex * mutex) { if (mutex) { - if (mutex->sem) { - SDL_DestroySemaphore(mutex->sem); - } + sceKernelDeleteMutex(mutex->uid); SDL_free(mutex); } } -/* Lock the semaphore */ +/* Try to lock the mutex */ +int +SDL_TryLockMutex(SDL_mutex * mutex) +{ +#if SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + if (mutex == NULL) { + return SDL_SetError("Passed a NULL mutex"); + } + + res = sceKernelTryLockMutex(mutex->uid, 1); + switch (res) { + case SCE_KERNEL_OK: + return 0; + break; + case SCE_KERNEL_ERROR_MUTEX_FAILED_TO_OWN: + return SDL_MUTEX_TIMEDOUT; + break; + default: + return SDL_SetError("Error trying to lock mutex: %x", res); + break; + } + + return -1; +#endif /* SDL_THREADS_DISABLED */ +} + + +/* Lock the mutex */ int SDL_mutexP(SDL_mutex * mutex) { #if SDL_THREADS_DISABLED return 0; #else - SDL_threadID this_thread; - + SceInt32 res = 0; if (mutex == NULL) { return SDL_SetError("Passed a NULL mutex"); } - this_thread = SDL_ThreadID(); - if (mutex->owner == this_thread) { - ++mutex->recursive; - } else { - /* The order of operations is important. - We set the locking thread id after we obtain the lock - so unlocks from other threads will fail. - */ - SDL_SemWait(mutex->sem); - mutex->owner = this_thread; - mutex->recursive = 0; + res = sceKernelLockMutex(mutex->uid, 1, NULL); + if (res != SCE_KERNEL_OK) { + return SDL_SetError("Error trying to lock mutex: %x", res); } return 0; @@ -107,26 +127,17 @@ SDL_mutexV(SDL_mutex * mutex) #if SDL_THREADS_DISABLED return 0; #else + SceInt32 res = 0; + if (mutex == NULL) { return SDL_SetError("Passed a NULL mutex"); } - /* If we don't own the mutex, we can't unlock it */ - if (SDL_ThreadID() != mutex->owner) { - return SDL_SetError("mutex not owned by this thread"); + res = sceKernelUnlockMutex(mutex->uid, 1); + if (res != 0) { + return SDL_SetError("Error trying to unlock mutex: %x", res); } - if (mutex->recursive) { - --mutex->recursive; - } else { - /* The order of operations is important. - First reset the owner so another thread doesn't lock - the mutex and set the ownership before we reset it, - then release the lock semaphore. - */ - mutex->owner = 0; - SDL_SemPost(mutex->sem); - } return 0; #endif /* SDL_THREADS_DISABLED */ }