mirror of
https://github.com/Ryujinx/SDL.git
synced 2024-12-23 14:35:40 +00:00
Use native mutexes
This commit is contained in:
parent
7423ae1ac7
commit
87a118b6b6
|
@ -22,17 +22,15 @@
|
||||||
|
|
||||||
#if SDL_THREAD_VITA
|
#if SDL_THREAD_VITA
|
||||||
|
|
||||||
/* An implementation of mutexes using semaphores */
|
|
||||||
|
|
||||||
#include "SDL_thread.h"
|
#include "SDL_thread.h"
|
||||||
#include "SDL_systhread_c.h"
|
#include "SDL_systhread_c.h"
|
||||||
|
|
||||||
|
#include <psp2/kernel/threadmgr.h>
|
||||||
|
#include <psp2/kernel/error.h>
|
||||||
|
|
||||||
struct SDL_mutex
|
struct SDL_mutex
|
||||||
{
|
{
|
||||||
int recursive;
|
SceUID uid;
|
||||||
SDL_threadID owner;
|
|
||||||
SDL_sem *sem;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Create a mutex */
|
/* Create a mutex */
|
||||||
|
@ -44,13 +42,16 @@ SDL_CreateMutex(void)
|
||||||
/* Allocate mutex memory */
|
/* Allocate mutex memory */
|
||||||
mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
|
mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
|
||||||
if (mutex) {
|
if (mutex) {
|
||||||
/* Create the mutex semaphore, with initial value 1 */
|
|
||||||
mutex->sem = SDL_CreateSemaphore(1);
|
mutex->uid = sceKernelCreateMutex("SDL mutex",
|
||||||
mutex->recursive = 0;
|
SCE_KERNEL_MUTEX_ATTR_TH_PRIO | SCE_KERNEL_MUTEX_ATTR_RECURSIVE,
|
||||||
mutex->owner = 0;
|
0,
|
||||||
if (!mutex->sem) {
|
NULL
|
||||||
SDL_free(mutex);
|
);
|
||||||
mutex = NULL;
|
|
||||||
|
if (mutex->uid <= 0) {
|
||||||
|
printf("Error creating mutex: %x\n", mutex->uid);
|
||||||
|
SDL_OutOfMemory(); // TODO: proper error
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SDL_OutOfMemory();
|
SDL_OutOfMemory();
|
||||||
|
@ -63,37 +64,56 @@ void
|
||||||
SDL_DestroyMutex(SDL_mutex * mutex)
|
SDL_DestroyMutex(SDL_mutex * mutex)
|
||||||
{
|
{
|
||||||
if (mutex) {
|
if (mutex) {
|
||||||
if (mutex->sem) {
|
sceKernelDeleteMutex(mutex->uid);
|
||||||
SDL_DestroySemaphore(mutex->sem);
|
|
||||||
}
|
|
||||||
SDL_free(mutex);
|
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
|
int
|
||||||
SDL_mutexP(SDL_mutex * mutex)
|
SDL_mutexP(SDL_mutex * mutex)
|
||||||
{
|
{
|
||||||
#if SDL_THREADS_DISABLED
|
#if SDL_THREADS_DISABLED
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
SDL_threadID this_thread;
|
SceInt32 res = 0;
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_SetError("Passed a NULL mutex");
|
return SDL_SetError("Passed a NULL mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
this_thread = SDL_ThreadID();
|
res = sceKernelLockMutex(mutex->uid, 1, NULL);
|
||||||
if (mutex->owner == this_thread) {
|
if (res != SCE_KERNEL_OK) {
|
||||||
++mutex->recursive;
|
return SDL_SetError("Error trying to lock mutex: %x", res);
|
||||||
} 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -107,26 +127,17 @@ SDL_mutexV(SDL_mutex * mutex)
|
||||||
#if SDL_THREADS_DISABLED
|
#if SDL_THREADS_DISABLED
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
|
SceInt32 res = 0;
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_SetError("Passed a NULL mutex");
|
return SDL_SetError("Passed a NULL mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we don't own the mutex, we can't unlock it */
|
res = sceKernelUnlockMutex(mutex->uid, 1);
|
||||||
if (SDL_ThreadID() != mutex->owner) {
|
if (res != 0) {
|
||||||
return SDL_SetError("mutex not owned by this thread");
|
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;
|
return 0;
|
||||||
#endif /* SDL_THREADS_DISABLED */
|
#endif /* SDL_THREADS_DISABLED */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue