From 87a118b6b6cd3162de9ca9b56f927bf235b09f29 Mon Sep 17 00:00:00 2001
From: Ivan Epifanov <[EMAIL REDACTED]>
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 <psp2/kernel/threadmgr.h>
+#include <psp2/kernel/error.h>
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_mutexP(SDL_mutex * mutex)
+SDL_TryLockMutex(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");
+ }
+
+ 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
+ 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 */
}