Merge commit '852f2a6343518919e5ca8d3c1bbcab9f493e3cd8'

This commit is contained in:
2024-01-17 17:02:59 +01:00
1244 changed files with 50102 additions and 28146 deletions

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -37,7 +37,7 @@ void *SDL_GetTLS(SDL_TLSID id)
SDL_TLSData *storage;
storage = SDL_SYS_GetTLSData();
if (storage == NULL || id == 0 || id > storage->limit) {
if (!storage || id == 0 || id > storage->limit) {
return NULL;
}
return storage->array[id - 1].data;
@ -52,15 +52,17 @@ int SDL_SetTLS(SDL_TLSID id, const void *value, void(SDLCALL *destructor)(void *
}
storage = SDL_SYS_GetTLSData();
if (storage == NULL || (id > storage->limit)) {
if (!storage || (id > storage->limit)) {
unsigned int i, oldlimit, newlimit;
SDL_TLSData *new_storage;
oldlimit = storage ? storage->limit : 0;
newlimit = (id + TLS_ALLOC_CHUNKSIZE);
storage = (SDL_TLSData *)SDL_realloc(storage, sizeof(*storage) + (newlimit - 1) * sizeof(storage->array[0]));
if (storage == NULL) {
return SDL_OutOfMemory();
new_storage = (SDL_TLSData *)SDL_realloc(storage, sizeof(*storage) + (newlimit - 1) * sizeof(storage->array[0]));
if (!new_storage) {
return -1;
}
storage = new_storage;
storage->limit = newlimit;
for (i = oldlimit; i < newlimit; ++i) {
storage->array[i].data = NULL;
@ -118,14 +120,14 @@ SDL_TLSData *SDL_Generic_GetTLSData(void)
SDL_TLSData *storage = NULL;
#ifndef SDL_THREADS_DISABLED
if (SDL_generic_TLS_mutex == NULL) {
if (!SDL_generic_TLS_mutex) {
static SDL_SpinLock tls_lock;
SDL_AtomicLock(&tls_lock);
if (SDL_generic_TLS_mutex == NULL) {
if (!SDL_generic_TLS_mutex) {
SDL_Mutex *mutex = SDL_CreateMutex();
SDL_MemoryBarrierRelease();
SDL_generic_TLS_mutex = mutex;
if (SDL_generic_TLS_mutex == NULL) {
if (!SDL_generic_TLS_mutex) {
SDL_AtomicUnlock(&tls_lock);
return NULL;
}
@ -159,10 +161,10 @@ int SDL_Generic_SetTLSData(SDL_TLSData *data)
prev = NULL;
for (entry = SDL_generic_TLS; entry; entry = entry->next) {
if (entry->thread == thread) {
if (data != NULL) {
if (data) {
entry->storage = data;
} else {
if (prev != NULL) {
if (prev) {
prev->next = entry->next;
} else {
SDL_generic_TLS = entry->next;
@ -173,7 +175,7 @@ int SDL_Generic_SetTLSData(SDL_TLSData *data)
}
prev = entry;
}
if (entry == NULL) {
if (!entry) {
entry = (SDL_TLSEntry *)SDL_malloc(sizeof(*entry));
if (entry) {
entry->thread = thread;
@ -184,10 +186,7 @@ int SDL_Generic_SetTLSData(SDL_TLSData *data)
}
SDL_UnlockMutex(SDL_generic_TLS_mutex);
if (entry == NULL) {
return SDL_OutOfMemory();
}
return 0;
return entry ? 0 : -1;
}
/* Non-thread-safe global error variable */
@ -213,7 +212,7 @@ static void SDLCALL SDL_FreeErrBuf(void *data)
#endif
/* Routine to get the thread-specific error variable */
SDL_error *SDL_GetErrBuf(void)
SDL_error *SDL_GetErrBuf(SDL_bool create)
{
#ifdef SDL_THREADS_DISABLED
return SDL_GetStaticErrBuf();
@ -224,6 +223,10 @@ SDL_error *SDL_GetErrBuf(void)
const SDL_error *ALLOCATION_IN_PROGRESS = (SDL_error *)-1;
SDL_error *errbuf;
if (!tls_errbuf && !create) {
return NULL;
}
/* tls_being_created is there simply to prevent recursion if SDL_CreateTLS() fails.
It also means it's possible for another thread to also use SDL_global_errbuf,
but that's very unlikely and hopefully won't cause issues.
@ -249,7 +252,7 @@ SDL_error *SDL_GetErrBuf(void)
if (errbuf == ALLOCATION_IN_PROGRESS) {
return SDL_GetStaticErrBuf();
}
if (errbuf == NULL) {
if (!errbuf) {
/* Get the original memory functions for this allocation because the lifetime
* of the error buffer may span calls to SDL_SetMemoryFunctions() by the app
*/
@ -260,7 +263,7 @@ SDL_error *SDL_GetErrBuf(void)
/* Mark that we're in the middle of allocating our buffer */
SDL_SetTLS(tls_errbuf, ALLOCATION_IN_PROGRESS, NULL);
errbuf = (SDL_error *)realloc_func(NULL, sizeof(*errbuf));
if (errbuf == NULL) {
if (!errbuf) {
SDL_SetTLS(tls_errbuf, NULL, NULL);
return SDL_GetStaticErrBuf();
}
@ -328,18 +331,16 @@ SDL_Thread *SDL_CreateThreadWithStackSize(int(SDLCALL *fn)(void *),
/* Allocate memory for the thread info structure */
thread = (SDL_Thread *)SDL_calloc(1, sizeof(*thread));
if (thread == NULL) {
SDL_OutOfMemory();
if (!thread) {
return NULL;
}
thread->status = -1;
SDL_AtomicSet(&thread->state, SDL_THREAD_STATE_ALIVE);
/* Set up the arguments for the thread */
if (name != NULL) {
if (name) {
thread->name = SDL_strdup(name);
if (thread->name == NULL) {
SDL_OutOfMemory();
if (!thread->name) {
SDL_free(thread);
return NULL;
}
@ -381,7 +382,7 @@ DECLSPEC SDL_Thread *SDLCALL SDL_CreateThread(int(SDLCALL *fn)(void *),
size_t stacksize = 0;
/* If the SDL_HINT_THREAD_STACK_SIZE exists, use it */
if (stackhint != NULL) {
if (stackhint) {
char *endp = NULL;
const Sint64 hintval = SDL_strtoll(stackhint, &endp, 10);
if ((*stackhint != '\0') && (*endp == '\0')) { /* a valid number? */
@ -450,7 +451,7 @@ void SDL_WaitThread(SDL_Thread *thread, int *status)
void SDL_DetachThread(SDL_Thread *thread)
{
if (thread == NULL) {
if (!thread) {
return;
}
@ -472,7 +473,7 @@ void SDL_DetachThread(SDL_Thread *thread)
int SDL_WaitSemaphore(SDL_Semaphore *sem)
{
return SDL_WaitSemaphoreTimeoutNS(sem, SDL_MUTEX_MAXWAIT);
return SDL_WaitSemaphoreTimeoutNS(sem, -1);
}
int SDL_TryWaitSemaphore(SDL_Semaphore *sem)
@ -494,7 +495,7 @@ int SDL_WaitSemaphoreTimeout(SDL_Semaphore *sem, Sint32 timeoutMS)
int SDL_WaitCondition(SDL_Condition *cond, SDL_Mutex *mutex)
{
return SDL_WaitConditionTimeoutNS(cond, mutex, SDL_MUTEX_MAXWAIT);
return SDL_WaitConditionTimeoutNS(cond, mutex, -1);
}
int SDL_WaitConditionTimeout(SDL_Condition *cond, SDL_Mutex *mutex, Sint32 timeoutMS)

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -64,8 +64,6 @@ SDL_Condition *SDL_CreateCondition_generic(void)
SDL_DestroyCondition_generic((SDL_Condition *)cond);
cond = NULL;
}
} else {
SDL_OutOfMemory();
}
return (SDL_Condition *)cond;
}
@ -92,7 +90,7 @@ void SDL_DestroyCondition_generic(SDL_Condition *_cond)
int SDL_SignalCondition_generic(SDL_Condition *_cond)
{
SDL_cond_generic *cond = (SDL_cond_generic *)_cond;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -116,7 +114,7 @@ int SDL_SignalCondition_generic(SDL_Condition *_cond)
int SDL_BroadcastCondition_generic(SDL_Condition *_cond)
{
SDL_cond_generic *cond = (SDL_cond_generic *)_cond;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -172,7 +170,7 @@ int SDL_WaitConditionTimeoutNS_generic(SDL_Condition *_cond, SDL_Mutex *mutex, S
SDL_cond_generic *cond = (SDL_cond_generic *)_cond;
int retval;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -20,7 +20,7 @@
*/
#include "SDL_internal.h"
/* An implementation of mutexes using semaphores */
// An implementation of mutexes using semaphores
#include "SDL_systhread_c.h"
@ -31,13 +31,9 @@ struct SDL_Mutex
SDL_Semaphore *sem;
};
/* Create a mutex */
SDL_Mutex *SDL_CreateMutex(void)
{
SDL_Mutex *mutex;
/* Allocate mutex memory */
mutex = (SDL_Mutex *)SDL_calloc(1, sizeof(*mutex));
SDL_Mutex *mutex = (SDL_Mutex *)SDL_calloc(1, sizeof(*mutex));
#ifndef SDL_THREADS_DISABLED
if (mutex) {
@ -49,15 +45,12 @@ SDL_Mutex *SDL_CreateMutex(void)
SDL_free(mutex);
mutex = NULL;
}
} else {
SDL_OutOfMemory();
}
#endif /* !SDL_THREADS_DISABLED */
#endif // !SDL_THREADS_DISABLED
return mutex;
}
/* Free the mutex */
void SDL_DestroyMutex(SDL_Mutex *mutex)
{
if (mutex) {
@ -68,94 +61,72 @@ void SDL_DestroyMutex(SDL_Mutex *mutex)
}
}
/* Lock the mutex */
int SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SDL_threadID this_thread;
if (mutex == NULL) {
return 0;
}
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_WaitSemaphore(mutex->sem);
mutex->owner = this_thread;
mutex->recursive = 0;
}
return 0;
#endif /* SDL_THREADS_DISABLED */
}
/* try Lock the mutex */
int SDL_TryLockMutex(SDL_Mutex *mutex)
{
#ifdef SDL_THREADS_DISABLED
return 0;
#else
int retval = 0;
SDL_threadID this_thread;
if (mutex == NULL) {
return 0;
}
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.
*/
retval = SDL_WaitSemaphore(mutex->sem);
if (retval == 0) {
#ifndef SDL_THREADS_DISABLED
if (mutex != NULL) {
SDL_threadID 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_WaitSemaphore(mutex->sem);
mutex->owner = this_thread;
mutex->recursive = 0;
}
}
return retval;
#endif /* SDL_THREADS_DISABLED */
}
/* Unlock the mutex */
int SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
int SDL_TryLockMutex(SDL_Mutex *mutex)
{
#ifdef SDL_THREADS_DISABLED
return 0;
#else
if (mutex == NULL) {
return 0;
int retval = 0;
#ifndef SDL_THREADS_DISABLED
if (mutex) {
SDL_threadID 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.
*/
retval = SDL_TryWaitSemaphore(mutex->sem);
if (retval == 0) {
mutex->owner = this_thread;
mutex->recursive = 0;
}
}
}
/* 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");
}
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_PostSemaphore(mutex->sem);
}
return 0;
#endif /* SDL_THREADS_DISABLED */
#endif // SDL_THREADS_DISABLED
return retval;
}
void SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
#ifndef SDL_THREADS_DISABLED
if (mutex != NULL) {
// If we don't own the mutex, we can't unlock it
if (SDL_ThreadID() != mutex->owner) {
SDL_assert(!"Tried to unlock a mutex we don't own!");
return; // (undefined behavior!) SDL_SetError("mutex not owned by this thread");
}
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_PostSemaphore(mutex->sem);
}
}
#endif // SDL_THREADS_DISABLED
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -20,7 +20,7 @@
*/
#include "SDL_internal.h"
/* An implementation of rwlocks using mutexes, condition variables, and atomics. */
// An implementation of rwlocks using mutexes, condition variables, and atomics.
#include "SDL_systhread_c.h"
@ -30,7 +30,7 @@
* will be chosen at runtime), the function names need to be
* suffixed
*/
/* !!! FIXME: this is quite a tapdance with macros and the build system, maybe we can simplify how we do this. --ryan. */
// !!! FIXME: this is quite a tapdance with macros and the build system, maybe we can simplify how we do this. --ryan.
#ifndef SDL_THREAD_GENERIC_RWLOCK_SUFFIX
#define SDL_CreateRWLock_generic SDL_CreateRWLock
#define SDL_DestroyRWLock_generic SDL_DestroyRWLock
@ -59,7 +59,6 @@ SDL_RWLock *SDL_CreateRWLock_generic(void)
SDL_RWLock *rwlock = (SDL_RWLock *) SDL_calloc(1, sizeof (*rwlock));
if (!rwlock) {
SDL_OutOfMemory();
return NULL;
}
@ -95,63 +94,48 @@ void SDL_DestroyRWLock_generic(SDL_RWLock *rwlock)
}
}
int SDL_LockRWLockForReading_generic(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_LockRWLockForReading_generic(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
#ifndef SDL_THREADS_DISABLED
if (!rwlock) {
return SDL_InvalidParamError("rwlock");
} else if (SDL_LockMutex(rwlock->lock) == -1) {
return -1;
if (rwlock) {
// !!! FIXME: these don't have to be atomic, we always gate them behind a mutex.
SDL_LockMutex(rwlock->lock);
SDL_assert(SDL_AtomicGet(&rwlock->writer_count) == 0); // shouldn't be able to grab lock if there's a writer!
SDL_AtomicAdd(&rwlock->reader_count, 1);
SDL_UnlockMutex(rwlock->lock); // other readers can attempt to share the lock.
}
SDL_assert(SDL_AtomicGet(&rwlock->writer_count) == 0); /* shouldn't be able to grab lock if there's a writer! */
SDL_AtomicAdd(&rwlock->reader_count, 1);
SDL_UnlockMutex(rwlock->lock); /* other readers can attempt to share the lock. */
#endif
return 0;
}
int SDL_LockRWLockForWriting_generic(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_LockRWLockForWriting_generic(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
#ifndef SDL_THREADS_DISABLED
if (!rwlock) {
return SDL_InvalidParamError("rwlock");
} else if (SDL_LockMutex(rwlock->lock) == -1) {
return -1;
}
if (rwlock) {
SDL_LockMutex(rwlock->lock);
while (SDL_AtomicGet(&rwlock->reader_count) > 0) { // while something is holding the shared lock, keep waiting.
SDL_WaitCondition(rwlock->condition, rwlock->lock); // release the lock and wait for readers holding the shared lock to release it, regrab the lock.
}
while (SDL_AtomicGet(&rwlock->reader_count) > 0) { /* while something is holding the shared lock, keep waiting. */
SDL_WaitCondition(rwlock->condition, rwlock->lock); /* release the lock and wait for readers holding the shared lock to release it, regrab the lock. */
// we hold the lock!
SDL_AtomicAdd(&rwlock->writer_count, 1); // we let these be recursive, but the API doesn't require this. It _does_ trust you unlock correctly!
}
/* we hold the lock! */
SDL_AtomicAdd(&rwlock->writer_count, 1); /* we let these be recursive, but the API doesn't require this. It _does_ trust you unlock correctly! */
#endif
return 0;
}
int SDL_TryLockRWLockForReading_generic(SDL_RWLock *rwlock)
{
#ifndef SDL_THREADS_DISABLED
int rc;
if (rwlock) {
const int rc = SDL_TryLockMutex(rwlock->lock);
if (rc != 0) {
// !!! FIXME: there is a small window where a reader has to lock the mutex, and if we hit that, we will return SDL_RWLOCK_TIMEDOUT even though we could have shared the lock.
return rc;
}
if (!rwlock) {
return SDL_InvalidParamError("rwlock");
SDL_assert(SDL_AtomicGet(&rwlock->writer_count) == 0); // shouldn't be able to grab lock if there's a writer!
SDL_AtomicAdd(&rwlock->reader_count, 1);
SDL_UnlockMutex(rwlock->lock); // other readers can attempt to share the lock.
}
rc = SDL_TryLockMutex(rwlock->lock);
if (rc != 0) {
/* !!! FIXME: there is a small window where a reader has to lock the mutex, and if we hit that, we will return SDL_RWLOCK_TIMEDOUT even though we could have shared the lock. */
return rc;
}
SDL_assert(SDL_AtomicGet(&rwlock->writer_count) == 0); /* shouldn't be able to grab lock if there's a writer! */
SDL_AtomicAdd(&rwlock->reader_count, 1);
SDL_UnlockMutex(rwlock->lock); /* other readers can attempt to share the lock. */
#endif
return 0;
@ -160,46 +144,41 @@ int SDL_TryLockRWLockForReading_generic(SDL_RWLock *rwlock)
int SDL_TryLockRWLockForWriting_generic(SDL_RWLock *rwlock)
{
#ifndef SDL_THREADS_DISABLED
int rc;
if (rwlock) {
const int rc = SDL_TryLockMutex(rwlock->lock);
if (rc != 0) {
return rc;
}
if (!rwlock) {
return SDL_InvalidParamError("rwlock");
} else if ((rc = SDL_TryLockMutex(rwlock->lock)) != 0) {
return rc;
if (SDL_AtomicGet(&rwlock->reader_count) > 0) { // a reader is using the shared lock, treat it as unavailable.
SDL_UnlockMutex(rwlock->lock);
return SDL_RWLOCK_TIMEDOUT;
}
// we hold the lock!
SDL_AtomicAdd(&rwlock->writer_count, 1); // we let these be recursive, but the API doesn't require this. It _does_ trust you unlock correctly!
}
if (SDL_AtomicGet(&rwlock->reader_count) > 0) { /* a reader is using the shared lock, treat it as unavailable. */
SDL_UnlockMutex(rwlock->lock);
return SDL_RWLOCK_TIMEDOUT;
}
/* we hold the lock! */
SDL_AtomicAdd(&rwlock->writer_count, 1); /* we let these be recursive, but the API doesn't require this. It _does_ trust you unlock correctly! */
#endif
return 0;
}
int SDL_UnlockRWLock_generic(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_UnlockRWLock_generic(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
#ifndef SDL_THREADS_DISABLED
if (!rwlock) {
return SDL_InvalidParamError("rwlock");
if (rwlock) {
SDL_LockMutex(rwlock->lock); // recursive lock for writers, readers grab lock to make sure things are sane.
if (SDL_AtomicGet(&rwlock->reader_count) > 0) { // we're a reader
SDL_AtomicAdd(&rwlock->reader_count, -1);
SDL_BroadcastCondition(rwlock->condition); // alert any pending writers to attempt to try to grab the lock again.
} else if (SDL_AtomicGet(&rwlock->writer_count) > 0) { // we're a writer
SDL_AtomicAdd(&rwlock->writer_count, -1);
SDL_UnlockMutex(rwlock->lock); // recursive unlock.
}
SDL_UnlockMutex(rwlock->lock);
}
SDL_LockMutex(rwlock->lock); /* recursive lock for writers, readers grab lock to make sure things are sane. */
if (SDL_AtomicGet(&rwlock->reader_count) > 0) { /* we're a reader */
SDL_AtomicAdd(&rwlock->reader_count, -1);
SDL_BroadcastCondition(rwlock->condition); /* alert any pending writers to attempt to try to grab the lock again. */
} else if (SDL_AtomicGet(&rwlock->writer_count) > 0) { /* we're a writer */
SDL_AtomicAdd(&rwlock->writer_count, -1);
SDL_UnlockMutex(rwlock->lock); /* recursive unlock. */
}
SDL_UnlockMutex(rwlock->lock);
#endif
return 0;
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -27,12 +27,12 @@
SDL_RWLock *SDL_CreateRWLock_generic(void);
void SDL_DestroyRWLock_generic(SDL_RWLock *rwlock);
int SDL_LockRWLockForReading_generic(SDL_RWLock *rwlock);
int SDL_LockRWLockForWriting_generic(SDL_RWLock *rwlock);
void SDL_LockRWLockForReading_generic(SDL_RWLock *rwlock);
void SDL_LockRWLockForWriting_generic(SDL_RWLock *rwlock);
int SDL_TryLockRWLockForReading_generic(SDL_RWLock *rwlock);
int SDL_TryLockRWLockForWriting_generic(SDL_RWLock *rwlock);
int SDL_UnlockRWLock_generic(SDL_RWLock *rwlock);
void SDL_UnlockRWLock_generic(SDL_RWLock *rwlock);
#endif /* SDL_THREAD_GENERIC_RWLOCK_SUFFIX */
#endif // SDL_THREAD_GENERIC_RWLOCK_SUFFIX
#endif /* SDL_sysrwlock_c_h_ */
#endif // SDL_sysrwlock_c_h_

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -66,8 +66,7 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
SDL_Semaphore *sem;
sem = (SDL_Semaphore *)SDL_malloc(sizeof(*sem));
if (sem == NULL) {
SDL_OutOfMemory();
if (!sem) {
return NULL;
}
sem->count = initial_value;
@ -108,7 +107,7 @@ int SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS)
{
int retval;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -156,7 +155,7 @@ Uint32 SDL_GetSemaphoreValue(SDL_Semaphore *sem)
int SDL_PostSemaphore(SDL_Semaphore *sem)
{
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -37,8 +37,6 @@ SDL_Condition *SDL_CreateCondition(void)
SDL_Condition *cond = (SDL_Condition *)SDL_malloc(sizeof(SDL_Condition));
if (cond) {
CondVar_Init(&cond->cond_variable);
} else {
SDL_OutOfMemory();
}
return cond;
}
@ -54,7 +52,7 @@ void SDL_DestroyCondition(SDL_Condition *cond)
/* Restart one of the threads that are waiting on the condition variable */
int SDL_SignalCondition(SDL_Condition *cond)
{
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -65,7 +63,7 @@ int SDL_SignalCondition(SDL_Condition *cond)
/* Restart all threads that are waiting on the condition variable */
int SDL_BroadcastCondition(SDL_Condition *cond)
{
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -98,10 +96,10 @@ int SDL_WaitConditionTimeoutNS(SDL_Condition *cond, SDL_Mutex *mutex, Sint64 tim
{
Result res;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
if (mutex == NULL) {
if (!mutex) {
return SDL_InvalidParamError("mutex");
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -22,26 +22,19 @@
#ifdef SDL_THREAD_N3DS
/* An implementation of mutexes using libctru's RecursiveLock */
// An implementation of mutexes using libctru's RecursiveLock
#include "SDL_sysmutex_c.h"
/* Create a mutex */
SDL_Mutex *SDL_CreateMutex(void)
{
SDL_Mutex *mutex;
/* Allocate mutex memory */
mutex = (SDL_Mutex *)SDL_malloc(sizeof(*mutex));
SDL_Mutex *mutex = (SDL_Mutex *)SDL_malloc(sizeof(*mutex));
if (mutex) {
RecursiveLock_Init(&mutex->lock);
} else {
SDL_OutOfMemory();
}
return mutex;
}
/* Free the mutex */
void SDL_DestroyMutex(SDL_Mutex *mutex)
{
if (mutex) {
@ -49,38 +42,23 @@ void SDL_DestroyMutex(SDL_Mutex *mutex)
}
}
/* Lock the mutex */
int SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
if (mutex == NULL) {
return 0;
if (mutex != NULL) {
RecursiveLock_Lock(&mutex->lock);
}
RecursiveLock_Lock(&mutex->lock);
return 0;
}
/* try Lock the mutex */
int SDL_TryLockMutex(SDL_Mutex *mutex)
{
if (mutex == NULL) {
return 0;
}
return RecursiveLock_TryLock(&mutex->lock);
return (!mutex) ? 0 : RecursiveLock_TryLock(&mutex->lock);
}
/* Unlock the mutex */
int SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
if (mutex == NULL) {
return 0;
if (mutex != NULL) {
RecursiveLock_Unlock(&mutex->lock);
}
RecursiveLock_Unlock(&mutex->lock);
return 0;
}
#endif /* SDL_THREAD_N3DS */
#endif // SDL_THREAD_N3DS

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -43,8 +43,7 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
}
sem = (SDL_Semaphore *)SDL_malloc(sizeof(*sem));
if (sem == NULL) {
SDL_OutOfMemory();
if (!sem) {
return NULL;
}
@ -63,11 +62,11 @@ void SDL_DestroySemaphore(SDL_Semaphore *sem)
int SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS)
{
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
if (timeoutNS == SDL_MUTEX_MAXWAIT) {
if (timeoutNS == -1) { // -1 == wait indefinitely.
LightSemaphore_Acquire(&sem->semaphore, 1);
return 0;
}
@ -99,7 +98,7 @@ int WaitOnSemaphoreFor(SDL_Semaphore *sem, Sint64 timeout)
Uint32 SDL_GetSemaphoreValue(SDL_Semaphore *sem)
{
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -108,7 +107,7 @@ Uint32 SDL_GetSemaphoreValue(SDL_Semaphore *sem)
int SDL_PostSemaphore(SDL_Semaphore *sem)
{
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
LightSemaphore_Release(&sem->semaphore, 1);

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -26,9 +26,8 @@
#include "../SDL_systhread.h"
/* N3DS has very limited RAM (128MB), so we put a limit on thread stack size. */
#define N3DS_THREAD_STACK_SIZE_MAX (16 * 1024)
#define N3DS_THREAD_STACK_SIZE_DEFAULT (4 * 1024)
/* N3DS has very limited RAM (128MB), so we set a low default thread stack size. */
#define N3DS_THREAD_STACK_SIZE_DEFAULT (80 * 1024)
#define N3DS_THREAD_PRIORITY_LOW 0x3F /**< Minimum priority */
#define N3DS_THREAD_PRIORITY_MEDIUM 0x2F /**< Slightly higher than main thread (0x30) */
@ -49,18 +48,25 @@ static void ThreadEntry(void *arg)
int SDL_SYS_CreateThread(SDL_Thread *thread)
{
s32 priority;
s32 priority = 0x30;
int cpu = -1;
size_t stack_size = GetStackSize(thread->stacksize);
svcGetThreadPriority(&priority, CUR_THREAD_HANDLE);
/* prefer putting audio thread on system core */
if (thread->name && (SDL_strncmp(thread->name, "SDLAudioP", 9) == 0) && R_SUCCEEDED(APT_SetAppCpuTimeLimit(30))) {
cpu = 1;
}
thread->handle = threadCreate(ThreadEntry,
thread,
stack_size,
priority,
-1,
cpu,
false);
if (thread->handle == NULL) {
if (!thread->handle) {
return SDL_SetError("Couldn't create thread");
}
@ -73,14 +79,6 @@ static size_t GetStackSize(size_t requested_size)
return N3DS_THREAD_STACK_SIZE_DEFAULT;
}
if (requested_size > N3DS_THREAD_STACK_SIZE_MAX) {
SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM,
"Requested a thread size of %zu,"
" falling back to the maximum supported of %zu\n",
requested_size,
N3DS_THREAD_STACK_SIZE_MAX);
requested_size = N3DS_THREAD_STACK_SIZE_MAX;
}
return requested_size;
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -67,17 +67,13 @@ void SDL_DestroyMutex(SDL_Mutex *mutex)
}
/* Lock the mutex */
int SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
if (mutex == NULL) {
return 0;
if (mutex != NULL) {
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Wait();
}
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Wait();
return 0;
}
/* Try to lock the mutex */
@ -95,16 +91,12 @@ int SDL_TryLockMutex(SDL_Mutex *mutex)
#endif
/* Unlock the mutex */
int SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
if (mutex == NULL) {
return 0;
if (mutex != NULL) {
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Signal();
}
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Signal();
return 0;
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -90,7 +90,7 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
void SDL_DestroySemaphore(SDL_Semaphore *sem)
{
if (sem != NULL) {
if (sem) {
RSemaphore sema;
sema.SetHandle(sem->handle);
sema.Signal(sema.Count());
@ -102,7 +102,7 @@ void SDL_DestroySemaphore(SDL_Semaphore *sem)
int SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS)
{
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -114,7 +114,7 @@ int SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS)
return SDL_MUTEX_TIMEOUT;
}
if (timeoutNS == SDL_MUTEX_MAXWAIT) {
if (timeoutNS == -1) { // -1 == wait indefinitely.
WaitAll(sem);
return 0;
}
@ -140,7 +140,7 @@ int SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS)
Uint32 SDL_GetSemaphoreValue(SDL_Semaphore *sem)
{
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -149,7 +149,7 @@ Uint32 SDL_GetSemaphoreValue(SDL_Semaphore *sem)
int SDL_PostSemaphore(SDL_Semaphore *sem)
{
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
sem->count++;

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -26,7 +26,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <timer_alarm.h>
#include <kernel_util.h>
#include <kernel.h>
@ -35,11 +35,6 @@ struct SDL_Semaphore
s32 semid;
};
static void usercb(struct timer_alarm_t *alarm, void *arg)
{
iReleaseWaitThread((int)arg);
}
/* Create a semaphore */
SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
{
@ -47,7 +42,7 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
ee_sema_t sema;
sem = (SDL_Semaphore *)SDL_malloc(sizeof(*sem));
if (sem != NULL) {
if (sem) {
/* TODO: Figure out the limit on the maximum value. */
sema.init_count = initial_value;
sema.max_count = 255;
@ -59,8 +54,6 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
SDL_free(sem);
sem = NULL;
}
} else {
SDL_OutOfMemory();
}
return sem;
@ -69,7 +62,7 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
/* Free the semaphore */
void SDL_DestroySemaphore(SDL_Semaphore *sem)
{
if (sem != NULL) {
if (sem) {
if (sem->semid > 0) {
DeleteSema(sem->semid);
sem->semid = 0;
@ -82,10 +75,10 @@ void SDL_DestroySemaphore(SDL_Semaphore *sem)
int SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS)
{
int ret;
struct timer_alarm_t alarm;
InitializeTimerAlarm(&alarm);
u64 timeout_usec;
u64 *timeout_ptr;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -96,12 +89,14 @@ int SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS)
return 0;
}
if (timeoutNS != SDL_MUTEX_MAXWAIT) {
SetTimerAlarm(&alarm, MSec2TimerBusClock(SDL_NS_TO_MS(timeoutNS)), &usercb, (void *)GetThreadId());
timeout_ptr = NULL;
if (timeoutNS != -1) { // -1 == wait indefinitely.
timeout_usec = SDL_NS_TO_US(timeoutNS);
timeout_ptr = &timeout_usec;
}
ret = WaitSema(sem->semid);
StopTimerAlarm(&alarm);
ret = WaitSemaEx(sem->semid, 1, timeout_ptr);
if (ret < 0) {
return SDL_MUTEX_TIMEDOUT;
@ -114,7 +109,7 @@ Uint32 SDL_GetSemaphoreValue(SDL_Semaphore *sem)
{
ee_sema_t info;
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -130,7 +125,7 @@ int SDL_PostSemaphore(SDL_Semaphore *sem)
{
int res;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,204 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_THREAD_PSP
/* An implementation of condition variables using semaphores and mutexes */
/*
This implementation borrows heavily from the BeOS condition variable
implementation, written by Christopher Tate and Owen Smith. Thanks!
*/
struct SDL_Condition
{
SDL_Mutex *lock;
int waiting;
int signals;
SDL_Semaphore *wait_sem;
SDL_Semaphore *wait_done;
};
/* Create a condition variable */
SDL_Condition *SDL_CreateCondition(void)
{
SDL_Condition *cond;
cond = (SDL_Condition *)SDL_malloc(sizeof(SDL_Condition));
if (cond) {
cond->lock = SDL_CreateMutex();
cond->wait_sem = SDL_CreateSemaphore(0);
cond->wait_done = SDL_CreateSemaphore(0);
cond->waiting = cond->signals = 0;
if (!cond->lock || !cond->wait_sem || !cond->wait_done) {
SDL_DestroyCondition(cond);
cond = NULL;
}
} else {
SDL_OutOfMemory();
}
return cond;
}
/* Destroy a condition variable */
void SDL_DestroyCondition(SDL_Condition *cond)
{
if (cond) {
if (cond->wait_sem) {
SDL_DestroySemaphore(cond->wait_sem);
}
if (cond->wait_done) {
SDL_DestroySemaphore(cond->wait_done);
}
if (cond->lock) {
SDL_DestroyMutex(cond->lock);
}
SDL_free(cond);
}
}
/* Restart one of the threads that are waiting on the condition variable */
int SDL_SignalCondition(SDL_Condition *cond)
{
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
/* If there are waiting threads not already signalled, then
signal the condition and wait for the thread to respond.
*/
SDL_LockMutex(cond->lock);
if (cond->waiting > cond->signals) {
++cond->signals;
SDL_PostSemaphore(cond->wait_sem);
SDL_UnlockMutex(cond->lock);
SDL_WaitSemaphore(cond->wait_done);
} else {
SDL_UnlockMutex(cond->lock);
}
return 0;
}
/* Restart all threads that are waiting on the condition variable */
int SDL_BroadcastCondition(SDL_Condition *cond)
{
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
/* If there are waiting threads not already signalled, then
signal the condition and wait for the thread to respond.
*/
SDL_LockMutex(cond->lock);
if (cond->waiting > cond->signals) {
int i, num_waiting;
num_waiting = (cond->waiting - cond->signals);
cond->signals = cond->waiting;
for (i = 0; i < num_waiting; ++i) {
SDL_PostSemaphore(cond->wait_sem);
}
/* Now all released threads are blocked here, waiting for us.
Collect them all (and win fabulous prizes!) :-)
*/
SDL_UnlockMutex(cond->lock);
for (i = 0; i < num_waiting; ++i) {
SDL_WaitSemaphore(cond->wait_done);
}
} else {
SDL_UnlockMutex(cond->lock);
}
return 0;
}
/* Wait on the condition variable for at most 'timeoutNS' nanoseconds.
The mutex must be locked before entering this function!
The mutex is unlocked during the wait, and locked again after the wait.
Typical use:
Thread A:
SDL_LockMutex(lock);
while ( ! condition ) {
SDL_WaitCondition(cond, lock);
}
SDL_UnlockMutex(lock);
Thread B:
SDL_LockMutex(lock);
...
condition = true;
...
SDL_SignalCondition(cond);
SDL_UnlockMutex(lock);
*/
int SDL_WaitConditionTimeoutNS(SDL_Condition *cond, SDL_Mutex *mutex, Sint64 timeoutNS)
{
int retval;
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
/* Obtain the protection mutex, and increment the number of waiters.
This allows the signal mechanism to only perform a signal if there
are waiting threads.
*/
SDL_LockMutex(cond->lock);
++cond->waiting;
SDL_UnlockMutex(cond->lock);
/* Unlock the mutex, as is required by condition variable semantics */
SDL_UnlockMutex(mutex);
/* Wait for a signal */
retval = SDL_WaitSemaphoreTimeout(cond->wait_sem, timeoutNS);
/* Let the signaler know we have completed the wait, otherwise
the signaler can race ahead and get the condition semaphore
if we are stopped between the mutex unlock and semaphore wait,
giving a deadlock. See the following URL for details:
http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html
*/
SDL_LockMutex(cond->lock);
if (cond->signals > 0) {
/* If we timed out, we need to eat a condition signal */
if (retval > 0) {
SDL_WaitSemaphore(cond->wait_sem);
}
/* We always notify the signal thread that we are done */
SDL_PostSemaphore(cond->wait_done);
/* Signal handshake complete */
--cond->signals;
}
--cond->waiting;
SDL_UnlockMutex(cond->lock);
/* Lock the mutex, as is required by condition variable semantics */
SDL_LockMutex(mutex);
return retval;
}
#endif /* SDL_THREAD_PSP */

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -22,7 +22,7 @@
#ifdef SDL_THREAD_PSP
/* An implementation of mutexes using semaphores */
// An implementation of mutexes using semaphores
#include "SDL_systhread_c.h"
@ -36,17 +36,11 @@ struct SDL_Mutex
SceLwMutexWorkarea lock;
};
/* Create a mutex */
SDL_Mutex *SDL_CreateMutex(void)
{
SDL_Mutex *mutex = NULL;
SceInt32 res = 0;
/* Allocate mutex memory */
mutex = (SDL_Mutex *)SDL_malloc(sizeof(*mutex));
SDL_Mutex *mutex = (SDL_Mutex *)SDL_malloc(sizeof(*mutex));
if (mutex) {
res = sceKernelCreateLwMutex(
const SceInt32 res = sceKernelCreateLwMutex(
&mutex->lock,
"SDL mutex",
SCE_KERNEL_MUTEX_ATTR_RECURSIVE,
@ -54,15 +48,14 @@ SDL_Mutex *SDL_CreateMutex(void)
NULL);
if (res < 0) {
SDL_free(mutex);
mutex = NULL;
SDL_SetError("Error trying to create mutex: %lx", res);
}
} else {
SDL_OutOfMemory();
}
return mutex;
}
/* Free the mutex */
void SDL_DestroyMutex(SDL_Mutex *mutex)
{
if (mutex) {
@ -71,75 +64,43 @@ void SDL_DestroyMutex(SDL_Mutex *mutex)
}
}
/* Lock the mutex */
int SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
return 0;
#ifndef SDL_THREADS_DISABLED
if (mutex != NULL) {
const SceInt32 res = sceKernelLockLwMutex(&mutex->lock, 1, NULL);
SDL_assert(res == SCE_KERNEL_ERROR_OK); // assume we're in a lot of trouble if this assert fails.
}
res = sceKernelLockLwMutex(&mutex->lock, 1, NULL);
if (res != SCE_KERNEL_ERROR_OK) {
return SDL_SetError("Error trying to lock mutex: %lx", res);
}
return 0;
#endif /* SDL_THREADS_DISABLED */
#endif // SDL_THREADS_DISABLED
}
/* Try to lock the mutex */
int SDL_TryLockMutex(SDL_Mutex *mutex)
{
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
return 0;
int retval = 0;
#ifndef SDL_THREADS_DISABLED
if (mutex) {
const SceInt32 res = sceKernelTryLockLwMutex(&mutex->lock, 1);
if (res == SCE_KERNEL_ERROR_OK) {
retval = 0;
} else if (res == SCE_KERNEL_ERROR_WAIT_TIMEOUT) {
retval = SDL_MUTEX_TIMEDOUT;
} else {
SDL_assert(!"Error trying to lock mutex"); // assume we're in a lot of trouble if this assert fails.
retval = SDL_MUTEX_TIMEDOUT;
}
}
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: %lx", res);
break;
}
return -1;
#endif /* SDL_THREADS_DISABLED */
#endif // SDL_THREADS_DISABLED
return retval;
}
/* Unlock the mutex */
int SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
return 0;
#ifndef SDL_THREADS_DISABLED
if (mutex != NULL) {
const SceInt32 res = sceKernelUnlockLwMutex(&mutex->lock, 1);
SDL_assert(res == 0); // assume we're in a lot of trouble if this assert fails.
}
res = sceKernelUnlockLwMutex(&mutex->lock, 1);
if (res != 0) {
return SDL_SetError("Error trying to unlock mutex: %lx", res);
}
return 0;
#endif /* SDL_THREADS_DISABLED */
#endif // SDL_THREADS_DISABLED
}
#endif /* SDL_THREAD_PSP */
#endif // SDL_THREAD_PSP

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -41,7 +41,7 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
SDL_Semaphore *sem;
sem = (SDL_Semaphore *)SDL_malloc(sizeof(*sem));
if (sem != NULL) {
if (sem) {
/* TODO: Figure out the limit on the maximum value. */
sem->semid = sceKernelCreateSema("SDL sema", 0, initial_value, 255, NULL);
if (sem->semid < 0) {
@ -49,8 +49,6 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
SDL_free(sem);
sem = NULL;
}
} else {
SDL_OutOfMemory();
}
return sem;
@ -59,7 +57,7 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
/* Free the semaphore */
void SDL_DestroySemaphore(SDL_Semaphore *sem)
{
if (sem != NULL) {
if (sem) {
if (sem->semid > 0) {
sceKernelDeleteSema(sem->semid);
sem->semid = 0;
@ -70,7 +68,7 @@ void SDL_DestroySemaphore(SDL_Semaphore *sem)
}
/* TODO: This routine is a bit overloaded.
* If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass
* If the timeout is 0 then just poll the semaphore; if it's -1, pass
* NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout
* is specified, convert it to microseconds. */
int SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS)
@ -79,7 +77,7 @@ int SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS)
SceUInt *pTimeout;
int res;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -114,7 +112,7 @@ Uint32 SDL_GetSemaphoreValue(SDL_Semaphore *sem)
{
SceKernelSemaInfo info;
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -130,7 +128,7 @@ int SDL_PostSemaphore(SDL_Semaphore *sem)
{
int res;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -63,7 +63,7 @@ int SDL_SignalCondition(SDL_Condition *cond)
{
int retval;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -79,7 +79,7 @@ int SDL_BroadcastCondition(SDL_Condition *cond)
{
int retval;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -98,7 +98,7 @@ int SDL_WaitConditionTimeoutNS(SDL_Condition *cond, SDL_Mutex *mutex, Sint64 tim
#endif
struct timespec abstime;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -30,7 +30,7 @@ SDL_Mutex *SDL_CreateMutex(void)
SDL_Mutex *mutex;
pthread_mutexattr_t attr;
/* Allocate the structure */
// Allocate the structure
mutex = (SDL_Mutex *)SDL_calloc(1, sizeof(*mutex));
if (mutex) {
pthread_mutexattr_init(&attr);
@ -39,15 +39,13 @@ SDL_Mutex *SDL_CreateMutex(void)
#elif defined(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP)
pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
#else
/* No extra attributes necessary */
// No extra attributes necessary
#endif
if (pthread_mutex_init(&mutex->id, &attr) != 0) {
SDL_SetError("pthread_mutex_init() failed");
SDL_free(mutex);
mutex = NULL;
}
} else {
SDL_OutOfMemory();
}
return mutex;
}
@ -60,116 +58,96 @@ void SDL_DestroyMutex(SDL_Mutex *mutex)
}
}
/* Lock the mutex */
int SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
if (mutex != NULL) {
#ifdef FAKE_RECURSIVE_MUTEX
pthread_t this_thread;
#endif
if (mutex == NULL) {
return 0;
}
#ifdef FAKE_RECURSIVE_MUTEX
this_thread = pthread_self();
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.
*/
if (pthread_mutex_lock(&mutex->id) == 0) {
pthread_t this_thread = pthread_self();
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.
*/
const int rc = pthread_mutex_lock(&mutex->id);
SDL_assert(rc == 0); // assume we're in a lot of trouble if this assert fails.
mutex->owner = this_thread;
mutex->recursive = 0;
} else {
return SDL_SetError("pthread_mutex_lock() failed");
}
}
#else
if (pthread_mutex_lock(&mutex->id) != 0) {
return SDL_SetError("pthread_mutex_lock() failed");
}
const int rc = pthread_mutex_lock(&mutex->id);
SDL_assert(rc == 0); // assume we're in a lot of trouble if this assert fails.
#endif
return 0;
}
}
int SDL_TryLockMutex(SDL_Mutex *mutex)
{
int retval;
int result;
#ifdef FAKE_RECURSIVE_MUTEX
pthread_t this_thread;
#endif
int retval = 0;
if (mutex == NULL) {
return 0;
}
retval = 0;
if (mutex) {
#ifdef FAKE_RECURSIVE_MUTEX
this_thread = pthread_self();
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.
*/
result = pthread_mutex_trylock(&mutex->id);
if (result == 0) {
mutex->owner = this_thread;
mutex->recursive = 0;
} else if (result == EBUSY) {
retval = SDL_MUTEX_TIMEDOUT;
pthread_t this_thread = pthread_self();
if (mutex->owner == this_thread) {
++mutex->recursive;
} else {
retval = SDL_SetError("pthread_mutex_trylock() failed");
/* The order of operations is important.
We set the locking thread id after we obtain the lock
so unlocks from other threads will fail.
*/
const int result = pthread_mutex_trylock(&mutex->id);
if (result == 0) {
mutex->owner = this_thread;
mutex->recursive = 0;
} else if (result == EBUSY) {
retval = SDL_MUTEX_TIMEDOUT;
} else {
SDL_assert(!"Error trying to lock mutex"); // assume we're in a lot of trouble if this assert fails.
retval = SDL_MUTEX_TIMEDOUT;
}
}
}
#else
result = pthread_mutex_trylock(&mutex->id);
if (result != 0) {
if (result == EBUSY) {
retval = SDL_MUTEX_TIMEDOUT;
} else {
retval = SDL_SetError("pthread_mutex_trylock() failed");
const int result = pthread_mutex_trylock(&mutex->id);
if (result != 0) {
if (result == EBUSY) {
retval = SDL_MUTEX_TIMEDOUT;
} else {
SDL_assert(!"Error trying to lock mutex"); // assume we're in a lot of trouble if this assert fails.
retval = SDL_MUTEX_TIMEDOUT;
}
}
}
#endif
}
return retval;
}
int SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
if (mutex == NULL) {
return 0;
}
if (mutex != NULL) {
#ifdef FAKE_RECURSIVE_MUTEX
/* We can only unlock the mutex if we own it */
if (pthread_self() == mutex->owner) {
if (mutex->recursive) {
--mutex->recursive;
// We can only unlock the mutex if we own it
if (pthread_self() == mutex->owner) {
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;
pthread_mutex_unlock(&mutex->id);
}
} 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;
pthread_mutex_unlock(&mutex->id);
return SDL_SetError("mutex not owned by this thread");
}
} else {
return SDL_SetError("mutex not owned by this thread");
}
#else
if (pthread_mutex_unlock(&mutex->id) != 0) {
return SDL_SetError("pthread_mutex_unlock() failed");
const int rc = pthread_mutex_unlock(&mutex->id);
SDL_assert(rc == 0); // assume we're in a lot of trouble if this assert fails.
#endif // FAKE_RECURSIVE_MUTEX
}
#endif /* FAKE_RECURSIVE_MUTEX */
return 0;
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -41,8 +41,6 @@ SDL_RWLock *SDL_CreateRWLock(void)
SDL_free(rwlock);
rwlock = NULL;
}
} else {
SDL_OutOfMemory();
}
return rwlock;
}
@ -55,42 +53,36 @@ void SDL_DestroyRWLock(SDL_RWLock *rwlock)
}
}
int SDL_LockRWLockForReading(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_LockRWLockForReading(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
if (rwlock == NULL) {
return SDL_InvalidParamError("rwlock");
} else if (pthread_rwlock_rdlock(&rwlock->id) != 0) {
return SDL_SetError("pthread_rwlock_rdlock() failed");
if (rwlock) {
const int rc = pthread_rwlock_rdlock(&rwlock->id);
SDL_assert(rc == 0); // assume we're in a lot of trouble if this assert fails.
}
return 0;
}
int SDL_LockRWLockForWriting(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_LockRWLockForWriting(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
if (rwlock == NULL) {
return SDL_InvalidParamError("rwlock");
} else if (pthread_rwlock_wrlock(&rwlock->id) != 0) {
return SDL_SetError("pthread_rwlock_wrlock() failed");
if (rwlock) {
const int rc = pthread_rwlock_wrlock(&rwlock->id);
SDL_assert(rc == 0); // assume we're in a lot of trouble if this assert fails.
}
return 0;
}
int SDL_TryLockRWLockForReading(SDL_RWLock *rwlock)
{
int retval = 0;
if (rwlock == NULL) {
retval = SDL_InvalidParamError("rwlock");
} else {
if (rwlock) {
const int result = pthread_rwlock_tryrdlock(&rwlock->id);
if (result != 0) {
if (result == EBUSY) {
retval = SDL_RWLOCK_TIMEDOUT;
} else {
retval = SDL_SetError("pthread_rwlock_tryrdlock() failed");
retval = SDL_RWLOCK_TIMEDOUT;
if (result != EBUSY) {
SDL_assert(!"Error trying to lock rwlock for reading"); // assume we're in a lot of trouble if this assert fails.
}
}
}
return retval;
}
@ -98,15 +90,12 @@ int SDL_TryLockRWLockForWriting(SDL_RWLock *rwlock)
{
int retval = 0;
if (rwlock == NULL) {
retval = SDL_InvalidParamError("rwlock");
} else {
if (rwlock) {
const int result = pthread_rwlock_trywrlock(&rwlock->id);
if (result != 0) {
if (result == EBUSY) {
retval = SDL_RWLOCK_TIMEDOUT;
} else {
retval = SDL_SetError("pthread_rwlock_tryrdlock() failed");
retval = SDL_RWLOCK_TIMEDOUT;
if (result != EBUSY) {
SDL_assert(!"Error trying to lock rwlock for writing"); // assume we're in a lot of trouble if this assert fails.
}
}
}
@ -114,13 +103,11 @@ int SDL_TryLockRWLockForWriting(SDL_RWLock *rwlock)
return retval;
}
int SDL_UnlockRWLock(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_UnlockRWLock(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
if (rwlock == NULL) {
return SDL_InvalidParamError("rwlock");
} else if (pthread_rwlock_unlock(&rwlock->id) != 0) {
return SDL_SetError("pthread_rwlock_unlock() failed");
if (rwlock) {
const int rc = pthread_rwlock_unlock(&rwlock->id);
SDL_assert(rc == 0); // assume we're in a lot of trouble if this assert fails.
}
return 0;
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -42,21 +42,19 @@ struct SDL_Semaphore
SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_Semaphore *sem = (SDL_Semaphore *)SDL_malloc(sizeof(SDL_Semaphore));
if (sem != NULL) {
if (sem) {
if (sem_init(&sem->sem, 0, initial_value) < 0) {
SDL_SetError("sem_init() failed");
SDL_free(sem);
sem = NULL;
}
} else {
SDL_OutOfMemory();
}
return sem;
}
void SDL_DestroySemaphore(SDL_Semaphore *sem)
{
if (sem != NULL) {
if (sem) {
sem_destroy(&sem->sem);
SDL_free(sem);
}
@ -74,7 +72,7 @@ int SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS)
Uint64 end;
#endif
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -152,7 +150,7 @@ Uint32 SDL_GetSemaphoreValue(SDL_Semaphore *sem)
{
int ret = 0;
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -168,7 +166,7 @@ int SDL_PostSemaphore(SDL_Semaphore *sem)
{
int retval;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -118,10 +118,10 @@ void SDL_SYS_SetupThread(const char *name)
int i;
sigset_t mask;
if (name != NULL) {
if (name) {
#if (defined(__MACOS__) || defined(__IOS__) || defined(__LINUX__)) && defined(HAVE_DLOPEN)
SDL_assert(checked_setname);
if (ppthread_setname_np != NULL) {
if (ppthread_setname_np) {
#if defined(__MACOS__) || defined(__IOS__)
ppthread_setname_np(name);
#elif defined(__LINUX__)

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -56,7 +56,7 @@ SDL_CreateCondition(void)
extern "C" void
SDL_DestroyCondition(SDL_Condition *cond)
{
if (cond != NULL) {
if (cond) {
delete cond;
}
}
@ -65,7 +65,7 @@ SDL_DestroyCondition(SDL_Condition *cond)
extern "C" int
SDL_SignalCondition(SDL_Condition *cond)
{
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -77,7 +77,7 @@ SDL_SignalCondition(SDL_Condition *cond)
extern "C" int
SDL_BroadcastCondition(SDL_Condition *cond)
{
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -27,74 +27,51 @@ extern "C" {
#include <system_error>
#include "SDL_sysmutex_c.h"
#include <Windows.h>
#include <windows.h>
/* Create a mutex */
extern "C" SDL_Mutex *
SDL_CreateMutex(void)
extern "C" SDL_Mutex * SDL_CreateMutex(void)
{
/* Allocate and initialize the mutex */
// Allocate and initialize the mutex
try {
SDL_Mutex *mutex = new SDL_Mutex;
return mutex;
} catch (std::system_error &ex) {
SDL_SetError("unable to create a C++ mutex: code=%d; %s", ex.code(), ex.what());
return NULL;
} catch (std::bad_alloc &) {
SDL_OutOfMemory();
return NULL;
}
return NULL;
}
/* Free the mutex */
extern "C" void
SDL_DestroyMutex(SDL_Mutex *mutex)
extern "C" void SDL_DestroyMutex(SDL_Mutex *mutex)
{
if (mutex != NULL) {
if (mutex) {
delete mutex;
}
}
/* Lock the mutex */
extern "C" int
SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
extern "C" void SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
if (mutex == NULL) {
return 0;
}
try {
mutex->cpp_mutex.lock();
return 0;
} catch (std::system_error &ex) {
return SDL_SetError("unable to lock a C++ mutex: code=%d; %s", ex.code(), ex.what());
if (mutex != NULL) {
try {
mutex->cpp_mutex.lock();
} catch (std::system_error &ex) {
SDL_assert(!"Error trying to lock mutex"); // assume we're in a lot of trouble if this assert fails.
//return SDL_SetError("unable to lock a C++ mutex: code=%d; %s", ex.code(), ex.what());
}
}
}
/* TryLock the mutex */
int SDL_TryLockMutex(SDL_Mutex *mutex)
extern "C" int SDL_TryLockMutex(SDL_Mutex *mutex)
{
int retval = 0;
if (mutex == NULL) {
return 0;
}
if (mutex->cpp_mutex.try_lock() == false) {
retval = SDL_MUTEX_TIMEDOUT;
}
return retval;
return ((!mutex) || mutex->cpp_mutex.try_lock()) ? 0 : SDL_MUTEX_TIMEDOUT;
}
/* Unlock the mutex */
extern "C" int
SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
extern "C" void SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
if (mutex == NULL) {
return 0;
if (mutex != NULL) {
mutex->cpp_mutex.unlock();
}
mutex->cpp_mutex.unlock();
return 0;
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -30,10 +30,8 @@ struct SDL_RWLock
SDL_threadID write_owner;
};
/* Create a rwlock */
extern "C" SDL_RWLock *SDL_CreateRWLock(void)
{
/* Allocate and initialize the rwlock */
try {
SDL_RWLock *rwlock = new SDL_RWLock;
return rwlock;
@ -46,85 +44,71 @@ extern "C" SDL_RWLock *SDL_CreateRWLock(void)
}
}
/* Free the rwlock */
extern "C" void SDL_DestroyRWLock(SDL_RWLock *rwlock)
{
if (rwlock != NULL) {
if (rwlock) {
delete rwlock;
}
}
/* Lock the rwlock */
extern "C" int SDL_LockRWLockForReading(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
extern "C" void SDL_LockRWLockForReading(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
if (!rwlock) {
return SDL_InvalidParamError("rwlock");
}
try {
rwlock->cpp_mutex.lock_shared();
return 0;
} catch (std::system_error &ex) {
return SDL_SetError("unable to lock a C++ rwlock: code=%d; %s", ex.code(), ex.what());
if (rwlock) {
try {
rwlock->cpp_mutex.lock_shared();
} catch (std::system_error &ex) {
SDL_assert(!"Error trying to lock rwlock for reading"); // assume we're in a lot of trouble if this assert fails.
//return SDL_SetError("unable to lock a C++ rwlock: code=%d; %s", ex.code(), ex.what());
}
}
}
/* Lock the rwlock for writing */
extern "C" int SDL_LockRWLockForWriting(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
extern "C" void SDL_LockRWLockForWriting(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
if (!rwlock) {
return SDL_InvalidParamError("rwlock");
}
try {
rwlock->cpp_mutex.lock();
rwlock->write_owner = SDL_ThreadID();
return 0;
} catch (std::system_error &ex) {
return SDL_SetError("unable to lock a C++ rwlock: code=%d; %s", ex.code(), ex.what());
if (rwlock) {
try {
rwlock->cpp_mutex.lock();
rwlock->write_owner = SDL_ThreadID();
} catch (std::system_error &ex) {
SDL_assert(!"Error trying to lock rwlock for writing"); // assume we're in a lot of trouble if this assert fails.
//return SDL_SetError("unable to lock a C++ rwlock: code=%d; %s", ex.code(), ex.what());
}
}
}
/* TryLock the rwlock for reading */
int SDL_TryLockRWLockForReading(SDL_RWLock *rwlock)
extern "C" int SDL_TryLockRWLockForReading(SDL_RWLock *rwlock)
{
int retval = 0;
if (!rwlock) {
retval = SDL_InvalidParamError("rwlock");
} else if (rwlock->cpp_mutex.try_lock_shared() == false) {
retval = SDL_RWLOCK_TIMEDOUT;
if (rwlock) {
if (rwlock->cpp_mutex.try_lock_shared() == false) {
retval = SDL_RWLOCK_TIMEDOUT;
}
}
return retval;
}
/* TryLock the rwlock for writing */
int SDL_TryLockRWLockForWriting(SDL_RWLock *rwlock)
extern "C" int SDL_TryLockRWLockForWriting(SDL_RWLock *rwlock)
{
int retval = 0;
if (!rwlock) {
retval = SDL_InvalidParamError("rwlock");
} else if (rwlock->cpp_mutex.try_lock() == false) {
retval = SDL_RWLOCK_TIMEDOUT;
} else {
rwlock->write_owner = SDL_ThreadID();
if (rwlock) {
if (rwlock->cpp_mutex.try_lock() == false) {
retval = SDL_RWLOCK_TIMEDOUT;
} else {
rwlock->write_owner = SDL_ThreadID();
}
}
return retval;
}
/* Unlock the rwlock */
extern "C" int
SDL_UnlockRWLock(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
extern "C" void SDL_UnlockRWLock(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
if (!rwlock) {
return SDL_InvalidParamError("rwlock");
} else if (rwlock->write_owner == SDL_ThreadID()) {
rwlock->write_owner = 0;
rwlock->cpp_mutex.unlock();
} else {
rwlock->cpp_mutex.unlock_shared();
if (rwlock) {
if (rwlock->write_owner == SDL_ThreadID()) {
rwlock->write_owner = 0;
rwlock->cpp_mutex.unlock();
} else {
rwlock->cpp_mutex.unlock_shared();
}
}
return 0;
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,204 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_THREAD_VITA
/* An implementation of condition variables using semaphores and mutexes */
/*
This implementation borrows heavily from the BeOS condition variable
implementation, written by Christopher Tate and Owen Smith. Thanks!
*/
struct SDL_Condition
{
SDL_Mutex *lock;
int waiting;
int signals;
SDL_Semaphore *wait_sem;
SDL_Semaphore *wait_done;
};
/* Create a condition variable */
SDL_Condition *SDL_CreateCondition(void)
{
SDL_Condition *cond;
cond = (SDL_Condition *)SDL_malloc(sizeof(SDL_Condition));
if (cond != NULL) {
cond->lock = SDL_CreateMutex();
cond->wait_sem = SDL_CreateSemaphore(0);
cond->wait_done = SDL_CreateSemaphore(0);
cond->waiting = cond->signals = 0;
if (!cond->lock || !cond->wait_sem || !cond->wait_done) {
SDL_DestroyCondition(cond);
cond = NULL;
}
} else {
SDL_OutOfMemory();
}
return cond;
}
/* Destroy a condition variable */
void SDL_DestroyCondition(SDL_Condition *cond)
{
if (cond != NULL) {
if (cond->wait_sem) {
SDL_DestroySemaphore(cond->wait_sem);
}
if (cond->wait_done) {
SDL_DestroySemaphore(cond->wait_done);
}
if (cond->lock) {
SDL_DestroyMutex(cond->lock);
}
SDL_free(cond);
}
}
/* Restart one of the threads that are waiting on the condition variable */
int SDL_SignalCondition(SDL_Condition *cond)
{
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
/* If there are waiting threads not already signalled, then
signal the condition and wait for the thread to respond.
*/
SDL_LockMutex(cond->lock);
if (cond->waiting > cond->signals) {
++cond->signals;
SDL_PostSemaphore(cond->wait_sem);
SDL_UnlockMutex(cond->lock);
SDL_WaitSemaphore(cond->wait_done);
} else {
SDL_UnlockMutex(cond->lock);
}
return 0;
}
/* Restart all threads that are waiting on the condition variable */
int SDL_BroadcastCondition(SDL_Condition *cond)
{
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
/* If there are waiting threads not already signalled, then
signal the condition and wait for the thread to respond.
*/
SDL_LockMutex(cond->lock);
if (cond->waiting > cond->signals) {
int i, num_waiting;
num_waiting = (cond->waiting - cond->signals);
cond->signals = cond->waiting;
for (i = 0; i < num_waiting; ++i) {
SDL_PostSemaphore(cond->wait_sem);
}
/* Now all released threads are blocked here, waiting for us.
Collect them all (and win fabulous prizes!) :-)
*/
SDL_UnlockMutex(cond->lock);
for (i = 0; i < num_waiting; ++i) {
SDL_WaitSemaphore(cond->wait_done);
}
} else {
SDL_UnlockMutex(cond->lock);
}
return 0;
}
/* Wait on the condition variable for at most 'timeoutNS' nanoseconds.
The mutex must be locked before entering this function!
The mutex is unlocked during the wait, and locked again after the wait.
Typical use:
Thread A:
SDL_LockMutex(lock);
while ( ! condition ) {
SDL_WaitCondition(cond, lock);
}
SDL_UnlockMutex(lock);
Thread B:
SDL_LockMutex(lock);
...
condition = true;
...
SDL_SignalCondition(cond);
SDL_UnlockMutex(lock);
*/
int SDL_WaitConditionTimeoutNS(SDL_Condition *cond, SDL_Mutex *mutex, Sint64 timeoutNS)
{
int retval;
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
/* Obtain the protection mutex, and increment the number of waiters.
This allows the signal mechanism to only perform a signal if there
are waiting threads.
*/
SDL_LockMutex(cond->lock);
++cond->waiting;
SDL_UnlockMutex(cond->lock);
/* Unlock the mutex, as is required by condition variable semantics */
SDL_UnlockMutex(mutex);
/* Wait for a signal */
retval = SDL_WaitSemaphoreTimeoutNS(cond->wait_sem, timeoutNS);
/* Let the signaler know we have completed the wait, otherwise
the signaler can race ahead and get the condition semaphore
if we are stopped between the mutex unlock and semaphore wait,
giving a deadlock. See the following URL for details:
http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html
*/
SDL_LockMutex(cond->lock);
if (cond->signals > 0) {
/* If we timed out, we need to eat a condition signal */
if (retval > 0) {
SDL_WaitSemaphore(cond->wait_sem);
}
/* We always notify the signal thread that we are done */
SDL_PostSemaphore(cond->wait_done);
/* Signal handshake complete */
--cond->signals;
}
--cond->waiting;
SDL_UnlockMutex(cond->lock);
/* Lock the mutex, as is required by condition variable semantics */
SDL_LockMutex(mutex);
return retval;
}
#endif /* SDL_THREAD_VITA */

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -32,63 +32,44 @@ struct SDL_Mutex
SceKernelLwMutexWork lock;
};
/* Create a mutex */
SDL_Mutex *SDL_CreateMutex(void)
{
SDL_Mutex *mutex = NULL;
SceInt32 res = 0;
/* Allocate mutex memory */
mutex = (SDL_Mutex *)SDL_malloc(sizeof(*mutex));
if (mutex != NULL) {
res = sceKernelCreateLwMutex(
&mutex->lock,
"SDL mutex",
SCE_KERNEL_MUTEX_ATTR_RECURSIVE,
0,
NULL);
SDL_Mutex *mutex = (SDL_Mutex *)SDL_malloc(sizeof(*mutex));
if (mutex) {
const SceInt32 res = sceKernelCreateLwMutex(
&mutex->lock,
"SDL mutex",
SCE_KERNEL_MUTEX_ATTR_RECURSIVE,
0,
NULL);
if (res < 0) {
SDL_free(mutex);
mutex = NULL;
SDL_SetError("Error trying to create mutex: %x", res);
}
} else {
SDL_OutOfMemory();
}
return mutex;
}
/* Free the mutex */
void SDL_DestroyMutex(SDL_Mutex *mutex)
{
if (mutex != NULL) {
if (mutex) {
sceKernelDeleteLwMutex(&mutex->lock);
SDL_free(mutex);
}
}
/* Lock the mutex */
int SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_LockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
return 0;
#ifndef SDL_THREADS_DISABLED
if (mutex != NULL) {
const SceInt32 res = sceKernelLockLwMutex(&mutex->lock, 1, NULL);
SDL_assert(res == SCE_KERNEL_OK); // assume we're in a lot of trouble if this assert fails.
}
res = sceKernelLockLwMutex(&mutex->lock, 1, NULL);
if (res != SCE_KERNEL_OK) {
return SDL_SetError("Error trying to lock mutex: %x", res);
}
return 0;
#endif /* SDL_THREADS_DISABLED */
#endif // SDL_THREADS_DISABLED
}
/* Try to lock the mutex */
int SDL_TryLockMutex(SDL_Mutex *mutex)
{
#ifdef SDL_THREADS_DISABLED
@ -96,46 +77,30 @@ int SDL_TryLockMutex(SDL_Mutex *mutex)
#else
SceInt32 res = 0;
if (mutex == NULL) {
if (!mutex) {
return 0;
}
res = sceKernelTryLockLwMutex(&mutex->lock, 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;
case SCE_KERNEL_OK: return 0;
case SCE_KERNEL_ERROR_MUTEX_FAILED_TO_OWN: return SDL_MUTEX_TIMEDOUT;
default: break;
}
return -1;
#endif /* SDL_THREADS_DISABLED */
SDL_assert(!"Error trying to lock mutex"); // assume we're in a lot of trouble if this assert fails.
return SDL_MUTEX_TIMEDOUT;
#endif // SDL_THREADS_DISABLED
}
/* Unlock the mutex */
int SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_UnlockMutex(SDL_Mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
return 0;
#ifndef SDL_THREADS_DISABLED
if (mutex != NULL) {
const SceInt32 res = sceKernelUnlockLwMutex(&mutex->lock, 1);
SDL_assert(res == SCE_KERNEL_OK); // assume we're in a lot of trouble if this assert fails.
}
res = sceKernelUnlockLwMutex(&mutex->lock, 1);
if (res != 0) {
return SDL_SetError("Error trying to unlock mutex: %x", res);
}
return 0;
#endif /* SDL_THREADS_DISABLED */
#endif // SDL_THREADS_DISABLED
}
#endif /* SDL_THREAD_VITA */
#endif // SDL_THREAD_VITA

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -42,7 +42,7 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
SDL_Semaphore *sem;
sem = (SDL_Semaphore *)SDL_malloc(sizeof(*sem));
if (sem != NULL) {
if (sem) {
/* TODO: Figure out the limit on the maximum value. */
sem->semid = sceKernelCreateSema("SDL sema", 0, initial_value, 255, NULL);
if (sem->semid < 0) {
@ -50,8 +50,6 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
SDL_free(sem);
sem = NULL;
}
} else {
SDL_OutOfMemory();
}
return sem;
@ -60,7 +58,7 @@ SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
/* Free the semaphore */
void SDL_DestroySemaphore(SDL_Semaphore *sem)
{
if (sem != NULL) {
if (sem) {
if (sem->semid > 0) {
sceKernelDeleteSema(sem->semid);
sem->semid = 0;
@ -71,7 +69,7 @@ void SDL_DestroySemaphore(SDL_Semaphore *sem)
}
/* TODO: This routine is a bit overloaded.
* If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass
* If the timeout is 0 then just poll the semaphore; if it's -1, pass
* NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout
* is specified, convert it to microseconds. */
int SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS)
@ -80,7 +78,7 @@ int SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS)
SceUInt *pTimeout;
int res;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -116,7 +114,7 @@ Uint32 SDL_GetSemaphoreValue(SDL_Semaphore *sem)
SceKernelSemaInfo info;
info.size = sizeof(info);
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -132,7 +130,7 @@ int SDL_PostSemaphore(SDL_Semaphore *sem)
{
int res;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -80,29 +80,20 @@ typedef struct SDL_cond_cv
static SDL_Condition *SDL_CreateCondition_cv(void)
{
SDL_cond_cv *cond;
/* Relies on CONDITION_VARIABLE_INIT == 0. */
cond = (SDL_cond_cv *)SDL_calloc(1, sizeof(*cond));
if (cond == NULL) {
SDL_OutOfMemory();
}
return (SDL_Condition *)cond;
return (SDL_Condition *)SDL_calloc(1, sizeof(SDL_cond_cv));
}
static void SDL_DestroyCondition_cv(SDL_Condition *cond)
{
if (cond != NULL) {
/* There are no kernel allocated resources */
SDL_free(cond);
}
/* There are no kernel allocated resources */
SDL_free(cond);
}
static int SDL_SignalCondition_cv(SDL_Condition *_cond)
{
SDL_cond_cv *cond = (SDL_cond_cv *)_cond;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -114,7 +105,7 @@ static int SDL_SignalCondition_cv(SDL_Condition *_cond)
static int SDL_BroadcastCondition_cv(SDL_Condition *_cond)
{
SDL_cond_cv *cond = (SDL_cond_cv *)_cond;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -129,10 +120,10 @@ static int SDL_WaitConditionTimeoutNS_cv(SDL_Condition *_cond, SDL_Mutex *_mutex
DWORD timeout;
int ret;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
if (_mutex == NULL) {
if (!_mutex) {
return SDL_InvalidParamError("mutex");
}
@ -208,13 +199,13 @@ static const SDL_cond_impl_t SDL_cond_impl_generic = {
SDL_Condition *SDL_CreateCondition(void)
{
if (SDL_cond_impl_active.Create == NULL) {
if (!SDL_cond_impl_active.Create) {
const SDL_cond_impl_t *impl = NULL;
if (SDL_mutex_impl_active.Type == SDL_MUTEX_INVALID) {
/* The mutex implementation isn't decided yet, trigger it */
SDL_Mutex *mutex = SDL_CreateMutex();
if (mutex == NULL) {
if (!mutex) {
return NULL;
}
SDL_DestroyMutex(mutex);

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -58,15 +58,10 @@ static pfnTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive = NULL;
static SDL_Mutex *SDL_CreateMutex_srw(void)
{
SDL_mutex_srw *mutex;
mutex = (SDL_mutex_srw *)SDL_calloc(1, sizeof(*mutex));
if (mutex == NULL) {
SDL_OutOfMemory();
SDL_mutex_srw *mutex = (SDL_mutex_srw *)SDL_calloc(1, sizeof(*mutex));
if (mutex) {
pInitializeSRWLock(&mutex->srw);
}
pInitializeSRWLock(&mutex->srw);
return (SDL_Mutex *)mutex;
}
@ -76,12 +71,11 @@ static void SDL_DestroyMutex_srw(SDL_Mutex *mutex)
SDL_free(mutex);
}
static int SDL_LockMutex_srw(SDL_Mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
static void SDL_LockMutex_srw(SDL_Mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex;
DWORD this_thread;
const DWORD this_thread = GetCurrentThreadId();
this_thread = GetCurrentThreadId();
if (mutex->owner == this_thread) {
++mutex->count;
} else {
@ -94,16 +88,14 @@ static int SDL_LockMutex_srw(SDL_Mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /*
mutex->owner = this_thread;
mutex->count = 1;
}
return 0;
}
static int SDL_TryLockMutex_srw(SDL_Mutex *_mutex)
{
SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex;
DWORD this_thread;
const DWORD this_thread = GetCurrentThreadId();
int retval = 0;
this_thread = GetCurrentThreadId();
if (mutex->owner == this_thread) {
++mutex->count;
} else {
@ -118,7 +110,7 @@ static int SDL_TryLockMutex_srw(SDL_Mutex *_mutex)
return retval;
}
static int SDL_UnlockMutex_srw(SDL_Mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
static void SDL_UnlockMutex_srw(SDL_Mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex;
@ -128,10 +120,8 @@ static int SDL_UnlockMutex_srw(SDL_Mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS
pReleaseSRWLockExclusive(&mutex->srw);
}
} else {
return SDL_SetError("mutex not owned by this thread");
SDL_assert(!"mutex not owned by this thread"); // undefined behavior...!
}
return 0;
}
static const SDL_mutex_impl_t SDL_mutex_impl_srw = {
@ -147,64 +137,44 @@ static const SDL_mutex_impl_t SDL_mutex_impl_srw = {
* Fallback Mutex implementation using Critical Sections (before Win 7)
*/
/* Create a mutex */
static SDL_Mutex *SDL_CreateMutex_cs(void)
{
SDL_mutex_cs *mutex;
/* Allocate mutex memory */
mutex = (SDL_mutex_cs *)SDL_malloc(sizeof(*mutex));
if (mutex != NULL) {
/* Initialize */
/* On SMP systems, a non-zero spin count generally helps performance */
SDL_mutex_cs *mutex = (SDL_mutex_cs *)SDL_malloc(sizeof(*mutex));
if (mutex) {
// Initialize
// On SMP systems, a non-zero spin count generally helps performance
#ifdef __WINRT__
InitializeCriticalSectionEx(&mutex->cs, 2000, 0);
#else
InitializeCriticalSectionAndSpinCount(&mutex->cs, 2000);
#endif
} else {
SDL_OutOfMemory();
}
return (SDL_Mutex *)mutex;
}
/* Free the mutex */
static void SDL_DestroyMutex_cs(SDL_Mutex *mutex_)
{
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
DeleteCriticalSection(&mutex->cs);
SDL_free(mutex);
}
/* Lock the mutex */
static int SDL_LockMutex_cs(SDL_Mutex *mutex_) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
static void SDL_LockMutex_cs(SDL_Mutex *mutex_) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
EnterCriticalSection(&mutex->cs);
return 0;
}
/* TryLock the mutex */
static int SDL_TryLockMutex_cs(SDL_Mutex *mutex_)
{
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
int retval = 0;
if (TryEnterCriticalSection(&mutex->cs) == 0) {
retval = SDL_MUTEX_TIMEDOUT;
}
return retval;
return (TryEnterCriticalSection(&mutex->cs) == 0) ? SDL_MUTEX_TIMEDOUT : 0;
}
/* Unlock the mutex */
static int SDL_UnlockMutex_cs(SDL_Mutex *mutex_) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
static void SDL_UnlockMutex_cs(SDL_Mutex *mutex_) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
LeaveCriticalSection(&mutex->cs);
return 0;
}
static const SDL_mutex_impl_t SDL_mutex_impl_cs = {
@ -222,23 +192,23 @@ static const SDL_mutex_impl_t SDL_mutex_impl_cs = {
SDL_Mutex *SDL_CreateMutex(void)
{
if (SDL_mutex_impl_active.Create == NULL) {
/* Default to fallback implementation */
if (!SDL_mutex_impl_active.Create) {
// Default to fallback implementation
const SDL_mutex_impl_t *impl = &SDL_mutex_impl_cs;
if (!SDL_GetHintBoolean(SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS, SDL_FALSE)) {
#ifdef __WINRT__
/* Link statically on this platform */
// Link statically on this platform
impl = &SDL_mutex_impl_srw;
#else
/* Try faster implementation for Windows 7 and newer */
// Try faster implementation for Windows 7 and newer
HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll"));
if (kernel32) {
/* Requires Vista: */
// Requires Vista:
pInitializeSRWLock = (pfnInitializeSRWLock)GetProcAddress(kernel32, "InitializeSRWLock");
pReleaseSRWLockExclusive = (pfnReleaseSRWLockExclusive)GetProcAddress(kernel32, "ReleaseSRWLockExclusive");
pAcquireSRWLockExclusive = (pfnAcquireSRWLockExclusive)GetProcAddress(kernel32, "AcquireSRWLockExclusive");
/* Requires 7: */
// Requires 7:
pTryAcquireSRWLockExclusive = (pfnTryAcquireSRWLockExclusive)GetProcAddress(kernel32, "TryAcquireSRWLockExclusive");
if (pInitializeSRWLock && pReleaseSRWLockExclusive && pAcquireSRWLockExclusive && pTryAcquireSRWLockExclusive) {
impl = &SDL_mutex_impl_srw;
@ -247,7 +217,7 @@ SDL_Mutex *SDL_CreateMutex(void)
#endif
}
/* Copy instead of using pointer to save one level of indirection */
// Copy instead of using pointer to save one level of indirection
SDL_copyp(&SDL_mutex_impl_active, impl);
}
return SDL_mutex_impl_active.Create();
@ -260,31 +230,23 @@ void SDL_DestroyMutex(SDL_Mutex *mutex)
}
}
int SDL_LockMutex(SDL_Mutex *mutex)
void SDL_LockMutex(SDL_Mutex *mutex)
{
if (mutex == NULL) {
return 0;
if (mutex) {
SDL_mutex_impl_active.Lock(mutex);
}
return SDL_mutex_impl_active.Lock(mutex);
}
int SDL_TryLockMutex(SDL_Mutex *mutex)
{
if (mutex == NULL) {
return 0;
}
return SDL_mutex_impl_active.TryLock(mutex);
return mutex ? SDL_mutex_impl_active.TryLock(mutex) : 0;
}
int SDL_UnlockMutex(SDL_Mutex *mutex)
void SDL_UnlockMutex(SDL_Mutex *mutex)
{
if (mutex == NULL) {
return 0;
if (mutex) {
SDL_mutex_impl_active.Unlock(mutex);
}
return SDL_mutex_impl_active.Unlock(mutex);
}
#endif /* SDL_THREAD_WINDOWS */
#endif // SDL_THREAD_WINDOWS

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -23,9 +23,9 @@
#include "../../core/windows/SDL_windows.h"
typedef SDL_Mutex *(*pfnSDL_CreateMutex)(void);
typedef int (*pfnSDL_LockMutex)(SDL_Mutex *);
typedef void (*pfnSDL_LockMutex)(SDL_Mutex *);
typedef int (*pfnSDL_TryLockMutex)(SDL_Mutex *);
typedef int (*pfnSDL_UnlockMutex)(SDL_Mutex *);
typedef void (*pfnSDL_UnlockMutex)(SDL_Mutex *);
typedef void (*pfnSDL_DestroyMutex)(SDL_Mutex *);
typedef enum

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -57,11 +57,11 @@ static pfnTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive = NULL;
typedef SDL_RWLock *(*pfnSDL_CreateRWLock)(void);
typedef void (*pfnSDL_DestroyRWLock)(SDL_RWLock *);
typedef int (*pfnSDL_LockRWLockForReading)(SDL_RWLock *);
typedef int (*pfnSDL_LockRWLockForWriting)(SDL_RWLock *);
typedef void (*pfnSDL_LockRWLockForReading)(SDL_RWLock *);
typedef void (*pfnSDL_LockRWLockForWriting)(SDL_RWLock *);
typedef int (*pfnSDL_TryLockRWLockForReading)(SDL_RWLock *);
typedef int (*pfnSDL_TryLockRWLockForWriting)(SDL_RWLock *);
typedef int (*pfnSDL_UnlockRWLock)(SDL_RWLock *);
typedef void (*pfnSDL_UnlockRWLock)(SDL_RWLock *);
typedef struct SDL_rwlock_impl_t
{
@ -88,10 +88,9 @@ typedef struct SDL_rwlock_srw
static SDL_RWLock *SDL_CreateRWLock_srw(void)
{
SDL_rwlock_srw *rwlock = (SDL_rwlock_srw *)SDL_calloc(1, sizeof(*rwlock));
if (rwlock == NULL) {
SDL_OutOfMemory();
if (rwlock) {
pInitializeSRWLock(&rwlock->srw);
}
pInitializeSRWLock(&rwlock->srw);
return (SDL_RWLock *)rwlock;
}
@ -104,35 +103,28 @@ static void SDL_DestroyRWLock_srw(SDL_RWLock *_rwlock)
}
}
static int SDL_LockRWLockForReading_srw(SDL_RWLock *_rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
static void SDL_LockRWLockForReading_srw(SDL_RWLock *_rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
SDL_rwlock_srw *rwlock = (SDL_rwlock_srw *) _rwlock;
if (rwlock == NULL) {
return SDL_InvalidParamError("rwlock");
if (rwlock != NULL) {
pAcquireSRWLockShared(&rwlock->srw);
}
pAcquireSRWLockShared(&rwlock->srw);
return 0;
}
static int SDL_LockRWLockForWriting_srw(SDL_RWLock *_rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
static void SDL_LockRWLockForWriting_srw(SDL_RWLock *_rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
SDL_rwlock_srw *rwlock = (SDL_rwlock_srw *) _rwlock;
if (rwlock == NULL) {
return SDL_InvalidParamError("rwlock");
if (rwlock != NULL) {
pAcquireSRWLockExclusive(&rwlock->srw);
rwlock->write_owner = SDL_ThreadID();
}
pAcquireSRWLockExclusive(&rwlock->srw);
rwlock->write_owner = SDL_ThreadID();
return 0;
}
static int SDL_TryLockRWLockForReading_srw(SDL_RWLock *_rwlock)
{
SDL_rwlock_srw *rwlock = (SDL_rwlock_srw *) _rwlock;
int retval = 0;
if (rwlock == NULL) {
retval = SDL_InvalidParamError("rwlock");
} else {
if (rwlock) {
retval = pTryAcquireSRWLockShared(&rwlock->srw) ? 0 : SDL_RWLOCK_TIMEDOUT;
}
return retval;
@ -142,27 +134,23 @@ static int SDL_TryLockRWLockForWriting_srw(SDL_RWLock *_rwlock)
{
SDL_rwlock_srw *rwlock = (SDL_rwlock_srw *) _rwlock;
int retval = 0;
if (rwlock == NULL) {
retval = SDL_InvalidParamError("rwlock");
} else {
if (rwlock) {
retval = pTryAcquireSRWLockExclusive(&rwlock->srw) ? 0 : SDL_RWLOCK_TIMEDOUT;
}
return retval;
}
static int SDL_UnlockRWLock_srw(SDL_RWLock *_rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
static void SDL_UnlockRWLock_srw(SDL_RWLock *_rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
SDL_rwlock_srw *rwlock = (SDL_rwlock_srw *) _rwlock;
if (rwlock == NULL) {
return SDL_InvalidParamError("rwlock");
} else if (rwlock->write_owner == SDL_ThreadID()) {
rwlock->write_owner = 0;
pReleaseSRWLockExclusive(&rwlock->srw);
} else {
pReleaseSRWLockShared(&rwlock->srw);
if (rwlock != NULL) {
if (rwlock->write_owner == SDL_ThreadID()) {
rwlock->write_owner = 0;
pReleaseSRWLockExclusive(&rwlock->srw);
} else {
pReleaseSRWLockShared(&rwlock->srw);
}
}
return 0;
}
static const SDL_rwlock_impl_t SDL_rwlock_impl_srw = {
@ -193,7 +181,7 @@ static const SDL_rwlock_impl_t SDL_rwlock_impl_generic = {
SDL_RWLock *SDL_CreateRWLock(void)
{
if (SDL_rwlock_impl_active.Create == NULL) {
if (!SDL_rwlock_impl_active.Create) {
const SDL_rwlock_impl_t *impl;
#ifdef __WINRT__
@ -229,30 +217,39 @@ SDL_RWLock *SDL_CreateRWLock(void)
void SDL_DestroyRWLock(SDL_RWLock *rwlock)
{
SDL_rwlock_impl_active.Destroy(rwlock);
if (rwlock) {
SDL_rwlock_impl_active.Destroy(rwlock);
}
}
int SDL_LockRWLockForReading(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_LockRWLockForReading(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
return SDL_rwlock_impl_active.LockForReading(rwlock);
if (rwlock != NULL) {
SDL_rwlock_impl_active.LockForReading(rwlock);
}
}
int SDL_LockRWLockForWriting(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_LockRWLockForWriting(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
return SDL_rwlock_impl_active.LockForWriting(rwlock);
if (rwlock != NULL) {
SDL_rwlock_impl_active.LockForWriting(rwlock);
}
}
int SDL_TryLockRWLockForReading(SDL_RWLock *rwlock)
{
return SDL_rwlock_impl_active.TryLockForReading(rwlock);
return rwlock ? SDL_rwlock_impl_active.TryLockForReading(rwlock) : 0;
}
int SDL_TryLockRWLockForWriting(SDL_RWLock *rwlock)
{
return SDL_rwlock_impl_active.TryLockForWriting(rwlock);
return rwlock ? SDL_rwlock_impl_active.TryLockForWriting(rwlock) : 0;
}
int SDL_UnlockRWLock(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
void SDL_UnlockRWLock(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS // clang doesn't know about NULL mutexes
{
return SDL_rwlock_impl_active.Unlock(rwlock);
if (rwlock != NULL) {
SDL_rwlock_impl_active.Unlock(rwlock);
}
}

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -83,19 +83,15 @@ static SDL_Semaphore *SDL_CreateSemaphore_atom(Uint32 initial_value)
SDL_sem_atom *sem;
sem = (SDL_sem_atom *)SDL_malloc(sizeof(*sem));
if (sem != NULL) {
if (sem) {
sem->count = initial_value;
} else {
SDL_OutOfMemory();
}
return (SDL_Semaphore *)sem;
}
static void SDL_DestroySemaphore_atom(SDL_Semaphore *sem)
{
if (sem != NULL) {
SDL_free(sem);
}
SDL_free(sem);
}
static int SDL_WaitSemaphoreTimeoutNS_atom(SDL_Semaphore *_sem, Sint64 timeoutNS)
@ -106,7 +102,7 @@ static int SDL_WaitSemaphoreTimeoutNS_atom(SDL_Semaphore *_sem, Sint64 timeoutNS
Uint64 deadline;
DWORD timeout_eff;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -176,7 +172,7 @@ static Uint32 SDL_GetSemaphoreValue_atom(SDL_Semaphore *_sem)
{
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -188,7 +184,7 @@ static int SDL_PostSemaphore_atom(SDL_Semaphore *_sem)
{
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -224,8 +220,9 @@ static SDL_Semaphore *SDL_CreateSemaphore_kern(Uint32 initial_value)
/* Allocate sem memory */
sem = (SDL_sem_kern *)SDL_malloc(sizeof(*sem));
if (sem != NULL) {
if (sem) {
/* Create the semaphore, with max value 32K */
// !!! FIXME: CreateSemaphoreEx is available in Vista and later, so if XP support is dropped, we can lose this #ifdef.
#ifdef __WINRT__
sem->id = CreateSemaphoreEx(NULL, initial_value, 32 * 1024, NULL, 0, SEMAPHORE_ALL_ACCESS);
#else
@ -237,8 +234,6 @@ static SDL_Semaphore *SDL_CreateSemaphore_kern(Uint32 initial_value)
SDL_free(sem);
sem = NULL;
}
} else {
SDL_OutOfMemory();
}
return (SDL_Semaphore *)sem;
}
@ -247,7 +242,7 @@ static SDL_Semaphore *SDL_CreateSemaphore_kern(Uint32 initial_value)
static void SDL_DestroySemaphore_kern(SDL_Semaphore *_sem)
{
SDL_sem_kern *sem = (SDL_sem_kern *)_sem;
if (sem != NULL) {
if (sem) {
if (sem->id) {
CloseHandle(sem->id);
sem->id = 0;
@ -262,7 +257,7 @@ static int SDL_WaitSemaphoreTimeoutNS_kern(SDL_Semaphore *_sem, Sint64 timeoutNS
int retval;
DWORD dwMilliseconds;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -290,7 +285,7 @@ static int SDL_WaitSemaphoreTimeoutNS_kern(SDL_Semaphore *_sem, Sint64 timeoutNS
static Uint32 SDL_GetSemaphoreValue_kern(SDL_Semaphore *_sem)
{
SDL_sem_kern *sem = (SDL_sem_kern *)_sem;
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -300,7 +295,7 @@ static Uint32 SDL_GetSemaphoreValue_kern(SDL_Semaphore *_sem)
static int SDL_PostSemaphore_kern(SDL_Semaphore *_sem)
{
SDL_sem_kern *sem = (SDL_sem_kern *)_sem;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
/* Increase the counter in the first place, because
@ -330,7 +325,7 @@ static const SDL_sem_impl_t SDL_sem_impl_kern = {
SDL_Semaphore *SDL_CreateSemaphore(Uint32 initial_value)
{
if (SDL_sem_impl_active.Create == NULL) {
if (!SDL_sem_impl_active.Create) {
/* Default to fallback implementation */
const SDL_sem_impl_t *impl = &SDL_sem_impl_kern;

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -47,7 +47,7 @@ static DWORD RunThread(void *data)
SDL_Thread *thread = (SDL_Thread *)data;
pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread)thread->endfunc;
SDL_RunThread(thread);
if (pfnEndThread != NULL) {
if (pfnEndThread) {
pfnEndThread(0);
}
return 0;
@ -96,7 +96,7 @@ int SDL_SYS_CreateThread(SDL_Thread *thread)
RunThreadViaCreateThread,
thread, flags, &threadid);
}
if (thread->handle == NULL) {
if (!thread->handle) {
return SDL_SetError("Not enough resources to create thread");
}
return 0;
@ -116,7 +116,7 @@ typedef HRESULT(WINAPI *pfnSetThreadDescription)(HANDLE, PCWSTR);
void SDL_SYS_SetupThread(const char *name)
{
if (name != NULL) {
if (name) {
#ifndef __WINRT__ /* !!! FIXME: There's no LoadLibrary() in WinRT; don't know if SetThreadDescription is available there at all at the moment. */
static pfnSetThreadDescription pSetThreadDescription = NULL;
static HMODULE kernel32 = NULL;
@ -128,7 +128,7 @@ void SDL_SYS_SetupThread(const char *name)
}
}
if (pSetThreadDescription != NULL) {
if (pSetThreadDescription) {
WCHAR *strw = WIN_UTF8ToStringW(name);
if (strw) {
pSetThreadDescription(GetCurrentThread(), strw);

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages