Use lightweight mutex
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
diff --git a/src/thread/psp/SDL_sysmutex.c b/src/thread/psp/SDL_sysmutex.c
index 2f40107..69c44d0 100644
--- a/src/thread/psp/SDL_sysmutex.c
+++ b/src/thread/psp/SDL_sysmutex.c
@@ -27,30 +27,37 @@
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
+#include <pspthreadman.h>
+#include <pspkerror.h>
+
+#define SCE_KERNEL_MUTEX_ATTR_RECURSIVE 0x0200U
struct SDL_mutex
{
- int recursive;
- SDL_threadID owner;
- SDL_sem *sem;
+ SceLwMutexWorkarea lock;
};
/* Create a mutex */
SDL_mutex *
SDL_CreateMutex(void)
{
- SDL_mutex *mutex;
+ SDL_mutex *mutex = NULL;
+ SceInt32 res = 0;
/* 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;
+
+ res = sceKernelCreateLwMutex(
+ &mutex->lock,
+ "SDL mutex",
+ SCE_KERNEL_MUTEX_ATTR_RECURSIVE,
+ 0,
+ NULL
+ );
+
+ if (res < 0) {
+ SDL_SetError("Error trying to create mutex: %x", res);
}
} else {
SDL_OutOfMemory();
@@ -63,37 +70,56 @@ void
SDL_DestroyMutex(SDL_mutex * mutex)
{
if (mutex) {
- if (mutex->sem) {
- SDL_DestroySemaphore(mutex->sem);
- }
+ sceKernelDeleteLwMutex(&mutex->lock);
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 = sceKernelTryLockLwMutex(&mutex->lock, 1);
+ switch (res) {
+ case SCE_KERNEL_ERROR_OK:
+ return 0;
+ break;
+ case SCE_KERNEL_ERROR_WAIT_TIMEOUT:
+ 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 = sceKernelLockLwMutex(&mutex->lock, 1, NULL);
+ if (res != SCE_KERNEL_ERROR_OK) {
+ return SDL_SetError("Error trying to lock mutex: %x", res);
}
return 0;
@@ -107,30 +133,20 @@ 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 = sceKernelUnlockLwMutex(&mutex->lock, 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 */
}
-
#endif /* SDL_THREAD_PSP */
/* vi: set ts=4 sw=4 expandtab: */