update sdl to 2.32.6

This commit is contained in:
AzaezelX 2025-05-24 13:39:03 -05:00
parent e557f5962b
commit ddc1f8c1e2
1339 changed files with 53966 additions and 19207 deletions

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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
@ -59,12 +59,18 @@ extern void SDL_SYS_WaitThread(SDL_Thread *thread);
/* Mark thread as cleaned up as soon as it exits, without joining. */
extern void SDL_SYS_DetachThread(SDL_Thread *thread);
/* Initialize the global TLS data */
extern void SDL_SYS_InitTLSData(void);
/* Get the thread local storage for this thread */
extern SDL_TLSData *SDL_SYS_GetTLSData(void);
/* Set the thread local storage for this thread */
extern int SDL_SYS_SetTLSData(SDL_TLSData *data);
/* Quit the global TLS data */
extern void SDL_SYS_QuitTLSData(void);
/* This is for internal SDL use, so we don't need #ifdefs everywhere. */
extern SDL_Thread *
SDL_CreateThreadInternal(int(SDLCALL *fn)(void *), const char *name,

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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
@ -28,7 +28,16 @@
#include "SDL_hints.h"
#include "../SDL_error_c.h"
SDL_TLSID SDL_TLSCreate()
/* The storage is local to the thread, but the IDs are global for the process */
static SDL_atomic_t SDL_tls_allocated;
void SDL_InitTLSData(void)
{
SDL_SYS_InitTLSData();
}
SDL_TLSID SDL_TLSCreate(void)
{
static SDL_atomic_t SDL_tls_id;
return SDL_AtomicIncRef(&SDL_tls_id) + 1;
@ -39,13 +48,13 @@ void *SDL_TLSGet(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;
}
int SDL_TLSSet(SDL_TLSID id, const void *value, void(SDLCALL *destructor)(void *))
int SDL_TLSSet(SDL_TLSID id, const void *value, SDL_TLSDestructorCallback destructor)
{
SDL_TLSData *storage;
@ -53,14 +62,21 @@ int SDL_TLSSet(SDL_TLSID id, const void *value, void(SDLCALL *destructor)(void *
return SDL_InvalidParamError("id");
}
/* Make sure TLS is initialized.
* There's a race condition here if you are calling this from non-SDL threads
* and haven't called SDL_Init() on your main thread, but such is life.
*/
SDL_InitTLSData();
/* Get the storage for the current thread */
storage = SDL_SYS_GetTLSData();
if (storage == NULL || (id > storage->limit)) {
if (!storage || (id > storage->limit)) {
unsigned int i, oldlimit, newlimit;
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) {
if (!storage) {
return SDL_OutOfMemory();
}
storage->limit = newlimit;
@ -69,8 +85,10 @@ int SDL_TLSSet(SDL_TLSID id, const void *value, void(SDLCALL *destructor)(void *
storage->array[i].destructor = NULL;
}
if (SDL_SYS_SetTLSData(storage) != 0) {
SDL_free(storage);
return -1;
}
SDL_AtomicIncRef(&SDL_tls_allocated);
}
storage->array[id - 1].data = SDL_const_cast(void *, value);
@ -78,10 +96,11 @@ int SDL_TLSSet(SDL_TLSID id, const void *value, void(SDLCALL *destructor)(void *
return 0;
}
void SDL_TLSCleanup()
void SDL_TLSCleanup(void)
{
SDL_TLSData *storage;
/* Cleanup the storage for the current thread */
storage = SDL_SYS_GetTLSData();
if (storage) {
unsigned int i;
@ -92,6 +111,18 @@ void SDL_TLSCleanup()
}
SDL_SYS_SetTLSData(NULL);
SDL_free(storage);
(void)SDL_AtomicDecRef(&SDL_tls_allocated);
}
}
void SDL_QuitTLSData(void)
{
SDL_TLSCleanup();
if (SDL_AtomicGet(&SDL_tls_allocated) == 0) {
SDL_SYS_QuitTLSData();
} else {
/* Some thread hasn't called SDL_CleanupTLS() */
}
}
@ -113,40 +144,27 @@ typedef struct SDL_TLSEntry
static SDL_mutex *SDL_generic_TLS_mutex;
static SDL_TLSEntry *SDL_generic_TLS;
void SDL_Generic_InitTLSData(void)
{
if (!SDL_generic_TLS_mutex) {
SDL_generic_TLS_mutex = SDL_CreateMutex();
}
}
SDL_TLSData *SDL_Generic_GetTLSData(void)
{
SDL_threadID thread = SDL_ThreadID();
SDL_TLSEntry *entry;
SDL_TLSData *storage = NULL;
#if !SDL_THREADS_DISABLED
if (SDL_generic_TLS_mutex == NULL) {
static SDL_SpinLock tls_lock;
SDL_AtomicLock(&tls_lock);
if (SDL_generic_TLS_mutex == NULL) {
SDL_mutex *mutex = SDL_CreateMutex();
SDL_MemoryBarrierRelease();
SDL_generic_TLS_mutex = mutex;
if (SDL_generic_TLS_mutex == NULL) {
SDL_AtomicUnlock(&tls_lock);
return NULL;
}
}
SDL_AtomicUnlock(&tls_lock);
}
SDL_MemoryBarrierAcquire();
SDL_LockMutex(SDL_generic_TLS_mutex);
#endif /* SDL_THREADS_DISABLED */
for (entry = SDL_generic_TLS; entry; entry = entry->next) {
if (entry->thread == thread) {
storage = entry->storage;
break;
}
}
#if !SDL_THREADS_DISABLED
SDL_UnlockMutex(SDL_generic_TLS_mutex);
#endif
return storage;
}
@ -155,16 +173,16 @@ int SDL_Generic_SetTLSData(SDL_TLSData *data)
{
SDL_threadID thread = SDL_ThreadID();
SDL_TLSEntry *prev, *entry;
int retval = 0;
/* SDL_Generic_GetTLSData() is always called first, so we can assume SDL_generic_TLS_mutex */
SDL_LockMutex(SDL_generic_TLS_mutex);
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;
@ -175,25 +193,48 @@ int SDL_Generic_SetTLSData(SDL_TLSData *data)
}
prev = entry;
}
if (entry == NULL) {
if (!entry && data) {
entry = (SDL_TLSEntry *)SDL_malloc(sizeof(*entry));
if (entry) {
entry->thread = thread;
entry->storage = data;
entry->next = SDL_generic_TLS;
SDL_generic_TLS = entry;
} else {
retval = SDL_OutOfMemory();
}
}
SDL_UnlockMutex(SDL_generic_TLS_mutex);
if (entry == NULL) {
return SDL_OutOfMemory();
return retval;
}
void SDL_Generic_QuitTLSData(void)
{
SDL_TLSEntry *entry;
/* This should have been cleaned up by the time we get here */
SDL_assert(!SDL_generic_TLS);
if (SDL_generic_TLS) {
SDL_LockMutex(SDL_generic_TLS_mutex);
for (entry = SDL_generic_TLS; entry; ) {
SDL_TLSEntry *next = entry->next;
SDL_free(entry->storage);
SDL_free(entry);
entry = next;
}
SDL_generic_TLS = NULL;
SDL_UnlockMutex(SDL_generic_TLS_mutex);
}
if (SDL_generic_TLS_mutex) {
SDL_DestroyMutex(SDL_generic_TLS_mutex);
SDL_generic_TLS_mutex = NULL;
}
return 0;
}
/* Non-thread-safe global error variable */
static SDL_error *SDL_GetStaticErrBuf()
static SDL_error *SDL_GetStaticErrBuf(void)
{
static SDL_error SDL_global_error;
static char SDL_global_error_str[128];
@ -202,7 +243,7 @@ static SDL_error *SDL_GetStaticErrBuf()
return &SDL_global_error;
}
#if !SDL_THREADS_DISABLED
#ifndef SDL_THREADS_DISABLED
static void SDLCALL SDL_FreeErrBuf(void *data)
{
SDL_error *errbuf = (SDL_error *)data;
@ -217,7 +258,7 @@ static void SDLCALL SDL_FreeErrBuf(void *data)
/* Routine to get the thread-specific error variable */
SDL_error *SDL_GetErrBuf(void)
{
#if SDL_THREADS_DISABLED
#ifdef SDL_THREADS_DISABLED
return SDL_GetStaticErrBuf();
#else
static SDL_SpinLock tls_lock;
@ -251,7 +292,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
*/
@ -262,7 +303,7 @@ SDL_error *SDL_GetErrBuf(void)
/* Mark that we're in the middle of allocating our buffer */
SDL_TLSSet(tls_errbuf, ALLOCATION_IN_PROGRESS, NULL);
errbuf = (SDL_error *)realloc_func(NULL, sizeof(*errbuf));
if (errbuf == NULL) {
if (!errbuf) {
SDL_TLSSet(tls_errbuf, NULL, NULL);
return SDL_GetStaticErrBuf();
}
@ -328,9 +369,11 @@ SDL_Thread *SDL_CreateThreadWithStackSize(int(SDLCALL *fn)(void *),
SDL_Thread *thread;
int ret;
SDL_InitMainThread();
/* Allocate memory for the thread info structure */
thread = (SDL_Thread *)SDL_calloc(1, sizeof(*thread));
if (thread == NULL) {
if (!thread) {
SDL_OutOfMemory();
return NULL;
}
@ -338,9 +381,9 @@ SDL_Thread *SDL_CreateThreadWithStackSize(int(SDLCALL *fn)(void *),
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) {
if (!thread->name) {
SDL_OutOfMemory();
SDL_free(thread);
return NULL;
@ -383,7 +426,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? */
@ -452,7 +495,7 @@ void SDL_WaitThread(SDL_Thread *thread, int *status)
void SDL_DetachThread(SDL_Thread *thread)
{
if (thread == NULL) {
if (!thread) {
return;
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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,25 +26,25 @@
#include "SDL_thread.h"
/* Need the definitions of SYS_ThreadHandle */
#if SDL_THREADS_DISABLED
#ifdef SDL_THREADS_DISABLED
#include "generic/SDL_systhread_c.h"
#elif SDL_THREAD_PTHREAD
#elif defined(SDL_THREAD_PTHREAD)
#include "pthread/SDL_systhread_c.h"
#elif SDL_THREAD_WINDOWS
#elif defined(SDL_THREAD_WINDOWS)
#include "windows/SDL_systhread_c.h"
#elif SDL_THREAD_PS2
#elif defined(SDL_THREAD_PS2)
#include "ps2/SDL_systhread_c.h"
#elif SDL_THREAD_PSP
#elif defined(SDL_THREAD_PSP)
#include "psp/SDL_systhread_c.h"
#elif SDL_THREAD_VITA
#elif defined(SDL_THREAD_VITA)
#include "vita/SDL_systhread_c.h"
#elif SDL_THREAD_N3DS
#elif defined(SDL_THREAD_N3DS)
#include "n3ds/SDL_systhread_c.h"
#elif SDL_THREAD_STDCPP
#elif defined(SDL_THREAD_STDCPP)
#include "stdcpp/SDL_systhread_c.h"
#elif SDL_THREAD_OS2
#elif defined(SDL_THREAD_OS2)
#include "os2/SDL_systhread_c.h"
#elif SDL_THREAD_NGAGE
#elif defined(SDL_THREAD_NGAGE)
#include "ngage/SDL_systhread_c.h"
#else
#error Need thread implementation for this platform
@ -93,17 +93,17 @@ typedef struct
/* This is how many TLS entries we allocate at once */
#define TLS_ALLOC_CHUNKSIZE 4
/* Get cross-platform, slow, thread local storage for this thread.
This is only intended as a fallback if getting real thread-local
storage fails or isn't supported on this platform.
*/
extern SDL_TLSData *SDL_Generic_GetTLSData(void);
extern void SDL_InitTLSData(void);
extern void SDL_QuitTLSData(void);
/* Set cross-platform, slow, thread local storage for this thread.
/* Generic TLS support.
This is only intended as a fallback if getting real thread-local
storage fails or isn't supported on this platform.
*/
extern void SDL_Generic_InitTLSData(void);
extern SDL_TLSData *SDL_Generic_GetTLSData(void);
extern int SDL_Generic_SetTLSData(SDL_TLSData *data);
extern void SDL_Generic_QuitTLSData(void);
#endif /* SDL_thread_c_h_ */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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
@ -34,7 +34,7 @@
* will be chosen at runtime), the function names need to be
* suffixed
*/
#if !SDL_THREAD_GENERIC_COND_SUFFIX
#ifndef SDL_THREAD_GENERIC_COND_SUFFIX
#define SDL_CreateCond_generic SDL_CreateCond
#define SDL_DestroyCond_generic SDL_DestroyCond
#define SDL_CondSignal_generic SDL_CondSignal
@ -95,7 +95,7 @@ void SDL_DestroyCond_generic(SDL_cond *_cond)
int SDL_CondSignal_generic(SDL_cond *_cond)
{
SDL_cond_generic *cond = (SDL_cond_generic *)_cond;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -119,7 +119,7 @@ int SDL_CondSignal_generic(SDL_cond *_cond)
int SDL_CondBroadcast_generic(SDL_cond *_cond)
{
SDL_cond_generic *cond = (SDL_cond_generic *)_cond;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -175,7 +175,7 @@ int SDL_CondWaitTimeout_generic(SDL_cond *_cond, SDL_mutex *mutex, Uint32 ms)
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-2025 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
@ -25,7 +25,7 @@
#ifndef SDL_syscond_generic_h_
#define SDL_syscond_generic_h_
#if SDL_THREAD_GENERIC_COND_SUFFIX
#ifdef SDL_THREAD_GENERIC_COND_SUFFIX
SDL_cond *SDL_CreateCond_generic(void);
void SDL_DestroyCond_generic(SDL_cond *cond);

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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
@ -40,7 +40,7 @@ SDL_mutex *SDL_CreateMutex(void)
/* Allocate mutex memory */
mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex));
#if !SDL_THREADS_DISABLED
#ifndef SDL_THREADS_DISABLED
if (mutex) {
/* Create the mutex semaphore, with initial value 1 */
mutex->sem = SDL_CreateSemaphore(1);
@ -72,7 +72,7 @@ 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 */
{
#if SDL_THREADS_DISABLED
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SDL_threadID this_thread;
@ -101,13 +101,13 @@ int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn
/* try Lock the mutex */
int SDL_TryLockMutex(SDL_mutex *mutex)
{
#if SDL_THREADS_DISABLED
#ifdef SDL_THREADS_DISABLED
return 0;
#else
int retval = 0;
SDL_threadID this_thread;
if (mutex == NULL) {
if (!mutex) {
return 0;
}
@ -133,7 +133,7 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
/* Unlock the mutex */
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
#if SDL_THREADS_DISABLED
#ifdef SDL_THREADS_DISABLED
return 0;
#else
if (mutex == NULL) {

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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 "SDL_thread.h"
#include "SDL_systhread_c.h"
#if SDL_THREADS_DISABLED
#ifdef SDL_THREADS_DISABLED
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
@ -78,7 +78,7 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
SDL_sem *sem;
sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
if (sem == NULL) {
if (!sem) {
SDL_OutOfMemory();
return NULL;
}
@ -120,7 +120,7 @@ int SDL_SemTryWait(SDL_sem *sem)
{
int retval;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -139,7 +139,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
int retval;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -184,7 +184,7 @@ Uint32 SDL_SemValue(SDL_sem *sem)
int SDL_SemPost(SDL_sem *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-2025 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-2025 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-2025 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,6 +22,11 @@
#include "../../SDL_internal.h"
#include "../SDL_thread_c.h"
void SDL_SYS_InitTLSData(void)
{
SDL_Generic_InitTLSData();
}
SDL_TLSData *SDL_SYS_GetTLSData(void)
{
return SDL_Generic_GetTLSData();
@ -32,4 +37,9 @@ int SDL_SYS_SetTLSData(SDL_TLSData *data)
return SDL_Generic_SetTLSData(data);
}
void SDL_SYS_QuitTLSData(void)
{
SDL_Generic_QuitTLSData();
}
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,127 +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_N3DS
/* An implementation of condition variables using libctru's CondVar */
#include "SDL_sysmutex_c.h"
struct SDL_cond
{
CondVar cond_variable;
};
/* Create a condition variable */
SDL_cond *SDL_CreateCond(void)
{
SDL_cond *cond = (SDL_cond *)SDL_malloc(sizeof(SDL_cond));
if (cond) {
CondVar_Init(&cond->cond_variable);
} else {
SDL_OutOfMemory();
}
return cond;
}
/* Destroy a condition variable */
void SDL_DestroyCond(SDL_cond *cond)
{
if (cond) {
SDL_free(cond);
}
}
/* Restart one of the threads that are waiting on the condition variable */
int SDL_CondSignal(SDL_cond *cond)
{
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
CondVar_Signal(&cond->cond_variable);
return 0;
}
/* Restart all threads that are waiting on the condition variable */
int SDL_CondBroadcast(SDL_cond *cond)
{
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
CondVar_Broadcast(&cond->cond_variable);
return 0;
}
/* Wait on the condition variable for at most 'ms' milliseconds.
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_CondWait(cond, lock);
}
SDL_UnlockMutex(lock);
Thread B:
SDL_LockMutex(lock);
...
condition = true;
...
SDL_CondSignal(cond);
SDL_UnlockMutex(lock);
*/
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
{
Result res;
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
}
res = 0;
if (ms == SDL_MUTEX_MAXWAIT) {
CondVar_Wait(&cond->cond_variable, &mutex->lock.lock);
} else {
res = CondVar_WaitTimeout(&cond->cond_variable, &mutex->lock.lock,
(s64)ms * 1000000LL);
}
return R_SUCCEEDED(res) ? 0 : SDL_MUTEX_TIMEDOUT;
}
/* Wait on the condition variable forever */
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}
#endif /* SDL_THREAD_N3DS */
/* vi: set sts=4 ts=4 sw=4 expandtab: */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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,7 +64,7 @@ int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn
/* try Lock the mutex */
int SDL_TryLockMutex(SDL_mutex *mutex)
{
if (mutex == NULL) {
if (!mutex) {
return 0;
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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
@ -46,7 +46,7 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
}
sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
if (sem == NULL) {
if (!sem) {
SDL_OutOfMemory();
return NULL;
}
@ -66,7 +66,7 @@ void SDL_DestroySemaphore(SDL_sem *sem)
int SDL_SemTryWait(SDL_sem *sem)
{
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -81,7 +81,7 @@ int SDL_SemTryWait(SDL_sem *sem)
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -122,7 +122,7 @@ int SDL_SemWait(SDL_sem *sem)
Uint32 SDL_SemValue(SDL_sem *sem)
{
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -131,7 +131,7 @@ Uint32 SDL_SemValue(SDL_sem *sem)
int SDL_SemPost(SDL_sem *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-2025 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-2025 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-2025 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-2025 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
@ -92,7 +92,7 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
void SDL_DestroySemaphore(SDL_sem *sem)
{
if (sem != NULL) {
if (sem) {
RSemaphore sema;
sema.SetHandle(sem->handle);
sema.Signal(sema.Count());
@ -104,7 +104,7 @@ void SDL_DestroySemaphore(SDL_sem *sem)
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -134,7 +134,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
int SDL_SemTryWait(SDL_sem *sem)
{
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -151,7 +151,7 @@ int SDL_SemWait(SDL_sem *sem)
Uint32 SDL_SemValue(SDL_sem *sem)
{
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -160,7 +160,7 @@ Uint32 SDL_SemValue(SDL_sem *sem)
int SDL_SemPost(SDL_sem *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-2025 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"
#if SDL_THREAD_NGAGE
#ifdef SDL_THREAD_NGAGE
/* N-Gage thread management routines for SDL */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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"
#if SDL_THREAD_OS2
#ifdef SDL_THREAD_OS2
/* An implementation of mutexes for OS/2 */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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"
#if SDL_THREAD_OS2
#ifdef SDL_THREAD_OS2
/* An implementation of semaphores for OS/2 */
@ -44,7 +44,7 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
ULONG ulRC;
SDL_sem *pSDLSem = SDL_malloc(sizeof(SDL_sem));
if (pSDLSem == NULL) {
if (!pSDLSem) {
SDL_OutOfMemory();
return NULL;
}
@ -85,7 +85,7 @@ int SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
ULONG ulTimeout;
ULONG cPost;
if (sem == NULL)
if (!sem)
return SDL_InvalidParamError("sem");
if (timeout != SEM_INDEFINITE_WAIT)
@ -140,7 +140,7 @@ Uint32 SDL_SemValue(SDL_sem * sem)
{
ULONG ulRC;
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -159,7 +159,7 @@ int SDL_SemPost(SDL_sem * sem)
{
ULONG ulRC;
if (sem == NULL)
if (!sem)
return SDL_InvalidParamError("sem");
ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT);

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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"
#if SDL_THREAD_OS2
#ifdef SDL_THREAD_OS2
/* Thread management routines for SDL */
@ -45,7 +45,7 @@ static void RunThread(void *data)
SDL_Thread *thread = (SDL_Thread *) data;
pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread) thread->endfunc;
if (ppSDLTLSData != NULL)
if (ppSDLTLSData)
*ppSDLTLSData = NULL;
SDL_RunThread(thread);

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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
@ -21,7 +21,7 @@
#include "../../SDL_internal.h"
#if SDL_THREAD_OS2
#ifdef SDL_THREAD_OS2
#include "../../core/os2/SDL_os2.h"
@ -34,45 +34,22 @@
SDL_TLSData **ppSDLTLSData = NULL;
static ULONG cTLSAlloc = 0;
/* SDL_OS2TLSAlloc() called from SDL_InitSubSystem() */
void SDL_OS2TLSAlloc(void)
void SDL_SYS_InitTLSData(void)
{
ULONG ulRC;
if (cTLSAlloc == 0 || ppSDLTLSData == NULL) {
/* First call - allocate the thread local memory (1 DWORD) */
if (!ppSDLTLSData) {
/* Allocate the thread local memory (1 DWORD) */
ulRC = DosAllocThreadLocalMemory(1, (PULONG *)&ppSDLTLSData);
if (ulRC != NO_ERROR) {
debug_os2("DosAllocThreadLocalMemory() failed, rc = %u", ulRC);
}
}
cTLSAlloc++;
}
/* SDL_OS2TLSFree() called from SDL_QuitSubSystem() */
void SDL_OS2TLSFree(void)
{
ULONG ulRC;
if (cTLSAlloc != 0)
cTLSAlloc--;
if (cTLSAlloc == 0 && ppSDLTLSData != NULL) {
/* Last call - free the thread local memory */
ulRC = DosFreeThreadLocalMemory((PULONG)ppSDLTLSData);
if (ulRC != NO_ERROR) {
debug_os2("DosFreeThreadLocalMemory() failed, rc = %u", ulRC);
} else {
ppSDLTLSData = NULL;
}
}
}
SDL_TLSData *SDL_SYS_GetTLSData(void)
{
return (ppSDLTLSData == NULL)? NULL : *ppSDLTLSData;
return ppSDLTLSData ? *ppSDLTLSData : NULL;
}
int SDL_SYS_SetTLSData(SDL_TLSData *data)
@ -84,6 +61,21 @@ int SDL_SYS_SetTLSData(SDL_TLSData *data)
return 0;
}
void SDL_SYS_QuitTLSData(void)
{
ULONG ulRC;
if (ppSDLTLSData) {
/* Free the thread local memory */
ulRC = DosFreeThreadLocalMemory((PULONG)ppSDLTLSData);
if (ulRC != NO_ERROR) {
debug_os2("DosFreeThreadLocalMemory() failed, rc = %u", ulRC);
} else {
ppSDLTLSData = NULL;
}
}
}
#endif /* SDL_THREAD_OS2 */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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
@ -21,18 +21,10 @@
#include "../../SDL_internal.h"
#if SDL_THREAD_OS2
#ifdef SDL_THREAD_OS2
#include "../SDL_thread_c.h"
extern SDL_TLSData **ppSDLTLSData;
/* SDL_OS2TLSAlloc() called from SDL_InitSubSystem() */
void SDL_OS2TLSAlloc(void);
/* SDL_OS2TLSFree() called from SDL_QuitSubSystem() */
void SDL_OS2TLSFree(void);
#endif /* SDL_THREAD_OS2 */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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,13 +20,13 @@
*/
#include "../../SDL_internal.h"
#if SDL_THREAD_PS2
#ifdef SDL_THREAD_PS2
/* Semaphore functions for the PS2. */
#include <stdio.h>
#include <stdlib.h>
#include <timer_alarm.h>
#include <kernel_util.h>
#include "SDL_error.h"
#include "SDL_thread.h"
@ -38,11 +38,6 @@ struct SDL_semaphore
s32 semid;
};
static void usercb(struct timer_alarm_t *alarm, void *arg)
{
iReleaseWaitThread((int)arg);
}
/* Create a semaphore */
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
@ -50,7 +45,7 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
ee_sema_t sema;
sem = (SDL_sem *)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;
@ -72,7 +67,7 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
/* Free the semaphore */
void SDL_DestroySemaphore(SDL_sem *sem)
{
if (sem != NULL) {
if (sem) {
if (sem->semid > 0) {
DeleteSema(sem->semid);
sem->semid = 0;
@ -85,10 +80,10 @@ void SDL_DestroySemaphore(SDL_sem *sem)
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
int ret;
struct timer_alarm_t alarm;
InitializeTimerAlarm(&alarm);
u64 timeout_usec;
u64 *timeout_ptr;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -99,12 +94,14 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
return 0;
}
timeout_ptr = NULL;
if (timeout != SDL_MUTEX_MAXWAIT) {
SetTimerAlarm(&alarm, MSec2TimerBusClock(timeout), &usercb, (void *)GetThreadId());
timeout_usec = timeout * 1000;
timeout_ptr = &timeout_usec;
}
ret = WaitSema(sem->semid);
StopTimerAlarm(&alarm);
ret = WaitSemaEx(sem->semid, 1, timeout_ptr);
if (ret < 0) {
return SDL_MUTEX_TIMEDOUT;
@ -127,7 +124,7 @@ Uint32 SDL_SemValue(SDL_sem *sem)
{
ee_sema_t info;
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -143,7 +140,7 @@ int SDL_SemPost(SDL_sem *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-2025 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"
#if SDL_THREAD_PS2
#ifdef SDL_THREAD_PS2
/* PS2 thread management routines for SDL */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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,218 +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"
#if 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!
*/
#include "SDL_thread.h"
struct SDL_cond
{
SDL_mutex *lock;
int waiting;
int signals;
SDL_sem *wait_sem;
SDL_sem *wait_done;
};
/* Create a condition variable */
SDL_cond *SDL_CreateCond(void)
{
SDL_cond *cond;
cond = (SDL_cond *)SDL_malloc(sizeof(SDL_cond));
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_DestroyCond(cond);
cond = NULL;
}
} else {
SDL_OutOfMemory();
}
return cond;
}
/* Destroy a condition variable */
void SDL_DestroyCond(SDL_cond *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_CondSignal(SDL_cond *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_SemPost(cond->wait_sem);
SDL_UnlockMutex(cond->lock);
SDL_SemWait(cond->wait_done);
} else {
SDL_UnlockMutex(cond->lock);
}
return 0;
}
/* Restart all threads that are waiting on the condition variable */
int SDL_CondBroadcast(SDL_cond *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_SemPost(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_SemWait(cond->wait_done);
}
} else {
SDL_UnlockMutex(cond->lock);
}
return 0;
}
/* Wait on the condition variable for at most 'ms' milliseconds.
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_CondWait(cond, lock);
}
SDL_UnlockMutex(lock);
Thread B:
SDL_LockMutex(lock);
...
condition = true;
...
SDL_CondSignal(cond);
SDL_UnlockMutex(lock);
*/
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
{
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 */
if (ms == SDL_MUTEX_MAXWAIT) {
retval = SDL_SemWait(cond->wait_sem);
} else {
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
}
/* 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_SemWait(cond->wait_sem);
}
/* We always notify the signal thread that we are done */
SDL_SemPost(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;
}
/* Wait on the condition variable forever */
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}
#endif /* SDL_THREAD_PSP */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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"
#if SDL_THREAD_PSP
#ifdef SDL_THREAD_PSP
/* An implementation of mutexes using semaphores */
@ -75,7 +75,7 @@ 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 */
{
#if SDL_THREADS_DISABLED
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
@ -96,12 +96,12 @@ int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn
/* Try to lock the mutex */
int SDL_TryLockMutex(SDL_mutex *mutex)
{
#if SDL_THREADS_DISABLED
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
if (!mutex) {
return 0;
}
@ -125,7 +125,7 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
/* Unlock the mutex */
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
#if SDL_THREADS_DISABLED
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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"
#if SDL_THREAD_PSP
#ifdef SDL_THREAD_PSP
/* Semaphore functions for the PSP. */
@ -44,7 +44,7 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
SDL_sem *sem;
sem = (SDL_sem *)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) {
@ -62,7 +62,7 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
/* Free the semaphore */
void SDL_DestroySemaphore(SDL_sem *sem)
{
if (sem != NULL) {
if (sem) {
if (sem->semid > 0) {
sceKernelDeleteSema(sem->semid);
sem->semid = 0;
@ -81,7 +81,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
Uint32 *pTimeout;
int res;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -126,7 +126,7 @@ Uint32 SDL_SemValue(SDL_sem *sem)
{
SceKernelSemaInfo info;
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -142,7 +142,7 @@ int SDL_SemPost(SDL_sem *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-2025 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"
#if SDL_THREAD_PSP
#ifdef SDL_THREAD_PSP
/* PSP thread management routines for SDL */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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,7 +64,7 @@ int SDL_CondSignal(SDL_cond *cond)
{
int retval;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -80,7 +80,7 @@ int SDL_CondBroadcast(SDL_cond *cond)
{
int retval;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -99,7 +99,7 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
#endif
struct timespec abstime;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -114,7 +114,7 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
abstime.tv_sec = delta.tv_sec + (ms / 1000);
abstime.tv_nsec = (long)(delta.tv_usec + (ms % 1000) * 1000) * 1000;
#endif
if (abstime.tv_nsec > 1000000000) {
if (abstime.tv_nsec >= 1000000000) {
abstime.tv_sec += 1;
abstime.tv_nsec -= 1000000000;
}
@ -141,7 +141,7 @@ tryagain:
*/
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
} else if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) {
return SDL_SetError("pthread_cond_wait() failed");

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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
@ -25,15 +25,15 @@
#include "SDL_thread.h"
#if !SDL_THREAD_PTHREAD_RECURSIVE_MUTEX && \
!SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP
#define FAKE_RECURSIVE_MUTEX 1
#if !(defined(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX) || \
defined(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP))
#define FAKE_RECURSIVE_MUTEX
#endif
struct SDL_mutex
{
pthread_mutex_t id;
#if FAKE_RECURSIVE_MUTEX
#ifdef FAKE_RECURSIVE_MUTEX
int recursive;
pthread_t owner;
#endif
@ -48,9 +48,9 @@ SDL_mutex *SDL_CreateMutex(void)
mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex));
if (mutex) {
pthread_mutexattr_init(&attr);
#if SDL_THREAD_PTHREAD_RECURSIVE_MUTEX
#ifdef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
#elif SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP
#elif defined(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP)
pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
#else
/* No extra attributes necessary */
@ -77,7 +77,7 @@ 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 */
{
#if FAKE_RECURSIVE_MUTEX
#ifdef FAKE_RECURSIVE_MUTEX
pthread_t this_thread;
#endif
@ -85,7 +85,7 @@ int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn
return 0;
}
#if FAKE_RECURSIVE_MUTEX
#ifdef FAKE_RECURSIVE_MUTEX
this_thread = pthread_self();
if (mutex->owner == this_thread) {
++mutex->recursive;
@ -113,16 +113,16 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
{
int retval;
int result;
#if FAKE_RECURSIVE_MUTEX
#ifdef FAKE_RECURSIVE_MUTEX
pthread_t this_thread;
#endif
if (mutex == NULL) {
if (!mutex) {
return 0;
}
retval = 0;
#if FAKE_RECURSIVE_MUTEX
#ifdef FAKE_RECURSIVE_MUTEX
this_thread = pthread_self();
if (mutex->owner == this_thread) {
++mutex->recursive;
@ -160,7 +160,7 @@ int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doe
return 0;
}
#if FAKE_RECURSIVE_MUTEX
#ifdef FAKE_RECURSIVE_MUTEX
/* We can only unlock the mutex if we own it */
if (pthread_self() == mutex->owner) {
if (mutex->recursive) {

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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
@ -45,7 +45,7 @@ struct SDL_semaphore
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem = (SDL_sem *)SDL_malloc(sizeof(SDL_sem));
if (sem != NULL) {
if (sem) {
if (sem_init(&sem->sem, 0, initial_value) < 0) {
SDL_SetError("sem_init() failed");
SDL_free(sem);
@ -59,7 +59,7 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
void SDL_DestroySemaphore(SDL_sem *sem)
{
if (sem != NULL) {
if (sem) {
sem_destroy(&sem->sem);
SDL_free(sem);
}
@ -69,7 +69,7 @@ int SDL_SemTryWait(SDL_sem *sem)
{
int retval;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
retval = SDL_MUTEX_TIMEDOUT;
@ -83,7 +83,7 @@ int SDL_SemWait(SDL_sem *sem)
{
int retval;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -109,7 +109,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
Uint32 end;
#endif
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -141,7 +141,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
#endif
/* Wrap the second if needed */
if (ts_timeout.tv_nsec > 1000000000) {
if (ts_timeout.tv_nsec >= 1000000000) {
ts_timeout.tv_sec += 1;
ts_timeout.tv_nsec -= 1000000000;
}
@ -175,7 +175,7 @@ Uint32 SDL_SemValue(SDL_sem *sem)
{
int ret = 0;
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -191,7 +191,7 @@ int SDL_SemPost(SDL_sem *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-2025 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
@ -25,7 +25,7 @@
#include <pthread.h>
#if HAVE_PTHREAD_NP_H
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
@ -41,7 +41,7 @@
#include "../../core/linux/SDL_dbus.h"
#endif /* __LINUX__ */
#if (defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__)) && defined(HAVE_DLOPEN)
#if (defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__ANDROID__)) && defined(HAVE_DLOPEN)
#include <dlfcn.h>
#ifndef RTLD_DEFAULT
#define RTLD_DEFAULT NULL
@ -80,7 +80,7 @@ static void *RunThread(void *data)
#if (defined(__MACOSX__) || defined(__IPHONEOS__)) && defined(HAVE_DLOPEN)
static SDL_bool checked_setname = SDL_FALSE;
static int (*ppthread_setname_np)(const char *) = NULL;
#elif defined(__LINUX__) && defined(HAVE_DLOPEN)
#elif (defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_DLOPEN)
static SDL_bool checked_setname = SDL_FALSE;
static int (*ppthread_setname_np)(pthread_t, const char *) = NULL;
#endif
@ -89,17 +89,17 @@ int SDL_SYS_CreateThread(SDL_Thread *thread)
pthread_attr_t type;
/* do this here before any threads exist, so there's no race condition. */
#if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)) && defined(HAVE_DLOPEN)
#if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_DLOPEN)
if (!checked_setname) {
void *fn = dlsym(RTLD_DEFAULT, "pthread_setname_np");
#if defined(__MACOSX__) || defined(__IPHONEOS__)
ppthread_setname_np = (int(*)(const char*)) fn;
#elif defined(__LINUX__)
#elif defined(__LINUX__) || defined(__ANDROID__)
ppthread_setname_np = (int(*)(pthread_t, const char*)) fn;
#endif
checked_setname = SDL_TRUE;
}
#endif
#endif
/* Set the thread attributes */
if (pthread_attr_init(&type) != 0) {
@ -127,13 +127,13 @@ void SDL_SYS_SetupThread(const char *name)
sigset_t mask;
#endif /* !__NACL__ */
if (name != NULL) {
#if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)) && defined(HAVE_DLOPEN)
if (name) {
#if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_DLOPEN)
SDL_assert(checked_setname);
if (ppthread_setname_np != NULL) {
#if defined(__MACOSX__) || defined(__IPHONEOS__)
if (ppthread_setname_np) {
#if defined(__MACOSX__) || defined(__IPHONEOS__)
ppthread_setname_np(name);
#elif defined(__LINUX__)
#elif defined(__LINUX__) || defined(__ANDROID__)
if (ppthread_setname_np(pthread_self(), name) == ERANGE) {
char namebuf[16]; /* Limited to 16 char */
SDL_strlcpy(namebuf, name, sizeof(namebuf));
@ -141,7 +141,7 @@ void SDL_SYS_SetupThread(const char *name)
}
#endif
}
#elif HAVE_PTHREAD_SETNAME_NP
#elif defined(HAVE_PTHREAD_SETNAME_NP)
#if defined(__NETBSD__)
pthread_setname_np(pthread_self(), "%s", name);
#else
@ -151,7 +151,7 @@ void SDL_SYS_SetupThread(const char *name)
pthread_setname_np(pthread_self(), namebuf);
}
#endif
#elif HAVE_PTHREAD_SET_NAME_NP
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
pthread_set_name_np(pthread_self(), name);
#elif defined(__HAIKU__)
/* The docs say the thread name can't be longer than B_OS_NAME_LENGTH. */
@ -188,7 +188,7 @@ SDL_threadID SDL_ThreadID(void)
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
#if __NACL__ || __RISCOS__ || __OS2__
#if defined(__NACL__) || defined(__RISCOS__) || defined(__OS2__)
/* FIXME: Setting thread priority does not seem to be supported in NACL */
return 0;
#else
@ -246,7 +246,7 @@ int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
policy = pri_policy;
}
#if __LINUX__
#ifdef __LINUX__
{
pid_t linuxTid = syscall(SYS_gettid);
return SDL_LinuxSetThreadPriorityAndPolicy(linuxTid, priority, policy);

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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,27 +30,27 @@
static pthread_key_t thread_local_storage = INVALID_PTHREAD_KEY;
static SDL_bool generic_local_storage = SDL_FALSE;
SDL_TLSData *SDL_SYS_GetTLSData(void)
void SDL_SYS_InitTLSData(void)
{
if (thread_local_storage == INVALID_PTHREAD_KEY && !generic_local_storage) {
static SDL_SpinLock lock;
SDL_AtomicLock(&lock);
if (thread_local_storage == INVALID_PTHREAD_KEY && !generic_local_storage) {
pthread_key_t storage;
if (pthread_key_create(&storage, NULL) == 0) {
SDL_MemoryBarrierRelease();
thread_local_storage = storage;
} else {
generic_local_storage = SDL_TRUE;
}
if (pthread_key_create(&thread_local_storage, NULL) != 0) {
thread_local_storage = INVALID_PTHREAD_KEY;
SDL_Generic_InitTLSData();
generic_local_storage = SDL_TRUE;
}
SDL_AtomicUnlock(&lock);
}
}
SDL_TLSData *SDL_SYS_GetTLSData(void)
{
if (generic_local_storage) {
return SDL_Generic_GetTLSData();
}
SDL_MemoryBarrierAcquire();
return (SDL_TLSData *)pthread_getspecific(thread_local_storage);
if (thread_local_storage != INVALID_PTHREAD_KEY) {
return (SDL_TLSData *)pthread_getspecific(thread_local_storage);
}
return NULL;
}
int SDL_SYS_SetTLSData(SDL_TLSData *data)
@ -58,10 +58,24 @@ int SDL_SYS_SetTLSData(SDL_TLSData *data)
if (generic_local_storage) {
return SDL_Generic_SetTLSData(data);
}
if (pthread_setspecific(thread_local_storage, data) != 0) {
return SDL_SetError("pthread_setspecific() failed");
}
return 0;
}
void SDL_SYS_QuitTLSData(void)
{
if (generic_local_storage) {
SDL_Generic_QuitTLSData();
generic_local_storage = SDL_FALSE;
} else {
if (thread_local_storage != INVALID_PTHREAD_KEY) {
pthread_key_delete(thread_local_storage);
thread_local_storage = INVALID_PTHREAD_KEY;
}
}
}
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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,7 +57,7 @@ SDL_CreateCond(void)
extern "C" void
SDL_DestroyCond(SDL_cond *cond)
{
if (cond != NULL) {
if (cond) {
delete cond;
}
}
@ -66,7 +66,7 @@ SDL_DestroyCond(SDL_cond *cond)
extern "C" int
SDL_CondSignal(SDL_cond *cond)
{
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -78,7 +78,7 @@ SDL_CondSignal(SDL_cond *cond)
extern "C" int
SDL_CondBroadcast(SDL_cond *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-2025 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
@ -51,7 +51,7 @@ SDL_CreateMutex(void)
extern "C" void
SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex != NULL) {
if (mutex) {
delete mutex;
}
}
@ -77,7 +77,7 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
{
int retval = 0;
if (mutex == NULL) {
if (!mutex) {
return 0;
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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
@ -120,8 +120,12 @@ SDL_SYS_WaitThread(SDL_Thread *thread)
try {
std::thread *cpp_thread = (std::thread *)thread->handle;
if (cpp_thread->joinable()) {
cpp_thread->join();
if (cpp_thread) {
if (cpp_thread->joinable()) {
cpp_thread->join();
}
delete cpp_thread;
thread->handle = nullptr;
}
} catch (std::system_error &) {
// An error occurred when joining the thread. SDL_WaitThread does not,
@ -139,8 +143,12 @@ SDL_SYS_DetachThread(SDL_Thread *thread)
try {
std::thread *cpp_thread = (std::thread *)thread->handle;
if (cpp_thread->joinable()) {
cpp_thread->detach();
if (cpp_thread) {
if (cpp_thread->joinable()) {
cpp_thread->detach();
}
delete cpp_thread;
thread->handle = nullptr;
}
} catch (std::system_error &) {
// An error occurred when detaching the thread. SDL_DetachThread does not,
@ -149,16 +157,29 @@ SDL_SYS_DetachThread(SDL_Thread *thread)
}
}
extern "C" SDL_TLSData *
SDL_SYS_GetTLSData(void)
static thread_local SDL_TLSData *thread_local_storage;
extern "C"
void SDL_SYS_InitTLSData(void)
{
return SDL_Generic_GetTLSData();
}
extern "C" int
SDL_SYS_SetTLSData(SDL_TLSData *data)
extern "C"
SDL_TLSData * SDL_SYS_GetTLSData(void)
{
return thread_local_storage;
}
extern "C"
int SDL_SYS_SetTLSData(SDL_TLSData *data)
{
thread_local_storage = data;
return 0;
}
extern "C"
void SDL_SYS_QuitTLSData(void)
{
return SDL_Generic_SetTLSData(data);
}
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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,218 +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"
#if 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!
*/
#include "SDL_thread.h"
struct SDL_cond
{
SDL_mutex *lock;
int waiting;
int signals;
SDL_sem *wait_sem;
SDL_sem *wait_done;
};
/* Create a condition variable */
SDL_cond *SDL_CreateCond(void)
{
SDL_cond *cond;
cond = (SDL_cond *)SDL_malloc(sizeof(SDL_cond));
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_DestroyCond(cond);
cond = NULL;
}
} else {
SDL_OutOfMemory();
}
return cond;
}
/* Destroy a condition variable */
void SDL_DestroyCond(SDL_cond *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_CondSignal(SDL_cond *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_SemPost(cond->wait_sem);
SDL_UnlockMutex(cond->lock);
SDL_SemWait(cond->wait_done);
} else {
SDL_UnlockMutex(cond->lock);
}
return 0;
}
/* Restart all threads that are waiting on the condition variable */
int SDL_CondBroadcast(SDL_cond *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_SemPost(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_SemWait(cond->wait_done);
}
} else {
SDL_UnlockMutex(cond->lock);
}
return 0;
}
/* Wait on the condition variable for at most 'ms' milliseconds.
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_CondWait(cond, lock);
}
SDL_UnlockMutex(lock);
Thread B:
SDL_LockMutex(lock);
...
condition = true;
...
SDL_CondSignal(cond);
SDL_UnlockMutex(lock);
*/
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
{
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 */
if (ms == SDL_MUTEX_MAXWAIT) {
retval = SDL_SemWait(cond->wait_sem);
} else {
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
}
/* 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_SemWait(cond->wait_sem);
}
/* We always notify the signal thread that we are done */
SDL_SemPost(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;
}
/* Wait on the condition variable forever */
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}
#endif /* SDL_THREAD_VITA */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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"
#if SDL_THREAD_VITA
#ifdef SDL_THREAD_VITA
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
@ -41,7 +41,7 @@ SDL_mutex *SDL_CreateMutex(void)
/* Allocate mutex memory */
mutex = (SDL_mutex *)SDL_malloc(sizeof(*mutex));
if (mutex != NULL) {
if (mutex) {
res = sceKernelCreateLwMutex(
&mutex->lock,
@ -62,7 +62,7 @@ SDL_mutex *SDL_CreateMutex(void)
/* Free the mutex */
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex != NULL) {
if (mutex) {
sceKernelDeleteLwMutex(&mutex->lock);
SDL_free(mutex);
}
@ -71,12 +71,12 @@ 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 */
{
#if SDL_THREADS_DISABLED
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
if (!mutex) {
return 0;
}
@ -92,12 +92,12 @@ int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn
/* Try to lock the mutex */
int SDL_TryLockMutex(SDL_mutex *mutex)
{
#if SDL_THREADS_DISABLED
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
if (!mutex) {
return 0;
}
@ -121,7 +121,7 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
/* Unlock the mutex */
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
#if SDL_THREADS_DISABLED
#ifdef SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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"
#if SDL_THREAD_VITA
#ifdef SDL_THREAD_VITA
/* Semaphore functions for the VITA. */
@ -45,7 +45,7 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
SDL_sem *sem;
sem = (SDL_sem *)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) {
@ -63,7 +63,7 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
/* Free the semaphore */
void SDL_DestroySemaphore(SDL_sem *sem)
{
if (sem != NULL) {
if (sem) {
if (sem->semid > 0) {
sceKernelDeleteSema(sem->semid);
sem->semid = 0;
@ -82,7 +82,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
Uint32 *pTimeout;
int res;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -128,7 +128,7 @@ Uint32 SDL_SemValue(SDL_sem *sem)
SceKernelSemaInfo info;
info.size = sizeof(info);
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -144,7 +144,7 @@ int SDL_SemPost(SDL_sem *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-2025 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"
#if SDL_THREAD_VITA
#ifdef SDL_THREAD_VITA
/* VITA thread management routines for SDL */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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
@ -61,7 +61,7 @@ typedef struct CONDITION_VARIABLE
} CONDITION_VARIABLE, *PCONDITION_VARIABLE;
#endif
#if __WINRT__
#ifdef __WINRT__
#define pWakeConditionVariable WakeConditionVariable
#define pWakeAllConditionVariable WakeAllConditionVariable
#define pSleepConditionVariableSRW SleepConditionVariableSRW
@ -89,7 +89,7 @@ static SDL_cond *SDL_CreateCond_cv(void)
/* Relies on CONDITION_VARIABLE_INIT == 0. */
cond = (SDL_cond_cv *)SDL_calloc(1, sizeof(*cond));
if (cond == NULL) {
if (!cond) {
SDL_OutOfMemory();
}
@ -98,7 +98,7 @@ static SDL_cond *SDL_CreateCond_cv(void)
static void SDL_DestroyCond_cv(SDL_cond *cond)
{
if (cond != NULL) {
if (cond) {
/* There are no kernel allocated resources */
SDL_free(cond);
}
@ -107,7 +107,7 @@ static void SDL_DestroyCond_cv(SDL_cond *cond)
static int SDL_CondSignal_cv(SDL_cond *_cond)
{
SDL_cond_cv *cond = (SDL_cond_cv *)_cond;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -119,7 +119,7 @@ static int SDL_CondSignal_cv(SDL_cond *_cond)
static int SDL_CondBroadcast_cv(SDL_cond *_cond)
{
SDL_cond_cv *cond = (SDL_cond_cv *)_cond;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
@ -134,10 +134,10 @@ static int SDL_CondWaitTimeout_cv(SDL_cond *_cond, SDL_mutex *_mutex, Uint32 ms)
DWORD timeout;
int ret;
if (cond == NULL) {
if (!cond) {
return SDL_InvalidParamError("cond");
}
if (_mutex == NULL) {
if (!_mutex) {
return SDL_InvalidParamError("mutex");
}
@ -220,14 +220,14 @@ static const SDL_cond_impl_t SDL_cond_impl_generic = {
SDL_cond *SDL_CreateCond(void)
{
if (SDL_cond_impl_active.Create == NULL) {
if (!SDL_cond_impl_active.Create) {
/* Default to generic implementation, works with all mutex implementations */
const SDL_cond_impl_t *impl = &SDL_cond_impl_generic;
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);
@ -235,7 +235,7 @@ SDL_cond *SDL_CreateCond(void)
SDL_assert(SDL_mutex_impl_active.Type != SDL_MUTEX_INVALID);
}
#if __WINRT__
#ifdef __WINRT__
/* Link statically on this platform */
impl = &SDL_cond_impl_cv;
#else

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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"
#if SDL_THREAD_WINDOWS
#ifdef SDL_THREAD_WINDOWS
/**
* Mutex functions using the Win32 API
@ -42,7 +42,7 @@ SDL_mutex_impl_t SDL_mutex_impl_active = { 0 };
* Implementation based on Slim Reader/Writer (SRW) Locks for Win 7 and newer.
*/
#if __WINRT__
#ifdef __WINRT__
/* Functions are guaranteed to be available */
#define pReleaseSRWLockExclusive ReleaseSRWLockExclusive
#define pAcquireSRWLockExclusive AcquireSRWLockExclusive
@ -62,7 +62,7 @@ static SDL_mutex *SDL_CreateMutex_srw(void)
/* Relies on SRWLOCK_INIT == 0. */
mutex = (SDL_mutex_srw *)SDL_calloc(1, sizeof(*mutex));
if (mutex == NULL) {
if (!mutex) {
SDL_OutOfMemory();
}
@ -153,10 +153,10 @@ static SDL_mutex *SDL_CreateMutex_cs(void)
/* Allocate mutex memory */
mutex = (SDL_mutex_cs *)SDL_malloc(sizeof(*mutex));
if (mutex != NULL) {
if (mutex) {
/* Initialize */
/* On SMP systems, a non-zero spin count generally helps performance */
#if __WINRT__
#ifdef __WINRT__
InitializeCriticalSectionEx(&mutex->cs, 2000, 0);
#else
InitializeCriticalSectionAndSpinCount(&mutex->cs, 2000);
@ -221,12 +221,12 @@ static const SDL_mutex_impl_t SDL_mutex_impl_cs = {
SDL_mutex *SDL_CreateMutex(void)
{
if (SDL_mutex_impl_active.Create == NULL) {
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)) {
#if __WINRT__
#ifdef __WINRT__
/* Link statically on this platform */
impl = &SDL_mutex_impl_srw;
#else
@ -260,7 +260,7 @@ void SDL_DestroyMutex(SDL_mutex *mutex)
int SDL_LockMutex(SDL_mutex *mutex)
{
if (mutex == NULL) {
if (!mutex) {
return 0;
}
@ -269,7 +269,7 @@ int SDL_LockMutex(SDL_mutex *mutex)
int SDL_TryLockMutex(SDL_mutex *mutex)
{
if (mutex == NULL) {
if (!mutex) {
return 0;
}
@ -278,7 +278,7 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
int SDL_UnlockMutex(SDL_mutex *mutex)
{
if (mutex == NULL) {
if (!mutex) {
return 0;
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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"
#if SDL_THREAD_WINDOWS
#ifdef SDL_THREAD_WINDOWS
/**
* Semaphore functions using the Win32 API
@ -68,14 +68,8 @@ static SDL_sem_impl_t SDL_sem_impl_active = { 0 };
/* APIs not available on WinPhone 8.1 */
/* https://www.microsoft.com/en-us/download/details.aspx?id=47328 */
#if (HAVE_WINAPIFAMILY_H) && defined(WINAPI_FAMILY_PHONE_APP)
#define SDL_WINAPI_FAMILY_PHONE (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
#else
#define SDL_WINAPI_FAMILY_PHONE 0
#endif
#if !SDL_WINAPI_FAMILY_PHONE
#if __WINRT__
#ifdef __WINRT__
/* Functions are guaranteed to be available */
#define pWaitOnAddress WaitOnAddress
#define pWakeByAddressSingle WakeByAddressSingle
@ -97,7 +91,7 @@ static SDL_sem *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();
@ -107,7 +101,7 @@ static SDL_sem *SDL_CreateSemaphore_atom(Uint32 initial_value)
static void SDL_DestroySemaphore_atom(SDL_sem *sem)
{
if (sem != NULL) {
if (sem) {
SDL_free(sem);
}
}
@ -117,7 +111,7 @@ static int SDL_SemTryWait_atom(SDL_sem *_sem)
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
LONG count;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -138,7 +132,7 @@ static int SDL_SemWait_atom(SDL_sem *_sem)
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
LONG count;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -169,7 +163,7 @@ static int SDL_SemWaitTimeout_atom(SDL_sem *_sem, Uint32 timeout)
return SDL_SemWait_atom(_sem);
}
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -211,7 +205,7 @@ static Uint32 SDL_SemValue_atom(SDL_sem *_sem)
{
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -223,7 +217,7 @@ static int SDL_SemPost_atom(SDL_sem *_sem)
{
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -261,9 +255,9 @@ static SDL_sem *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 */
#if __WINRT__
#ifdef __WINRT__
sem->id = CreateSemaphoreEx(NULL, initial_value, 32 * 1024, NULL, 0, SEMAPHORE_ALL_ACCESS);
#else
sem->id = CreateSemaphore(NULL, initial_value, 32 * 1024, NULL);
@ -284,7 +278,7 @@ static SDL_sem *SDL_CreateSemaphore_kern(Uint32 initial_value)
static void SDL_DestroySemaphore_kern(SDL_sem *_sem)
{
SDL_sem_kern *sem = (SDL_sem_kern *)_sem;
if (sem != NULL) {
if (sem) {
if (sem->id) {
CloseHandle(sem->id);
sem->id = 0;
@ -299,7 +293,7 @@ static int SDL_SemWaitTimeout_kern(SDL_sem *_sem, Uint32 timeout)
int retval;
DWORD dwMilliseconds;
if (sem == NULL) {
if (!sem) {
return SDL_InvalidParamError("sem");
}
@ -337,7 +331,7 @@ static int SDL_SemWait_kern(SDL_sem *sem)
static Uint32 SDL_SemValue_kern(SDL_sem *_sem)
{
SDL_sem_kern *sem = (SDL_sem_kern *)_sem;
if (sem == NULL) {
if (!sem) {
SDL_InvalidParamError("sem");
return 0;
}
@ -347,7 +341,7 @@ static Uint32 SDL_SemValue_kern(SDL_sem *_sem)
static int SDL_SemPost_kern(SDL_sem *_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
@ -379,13 +373,13 @@ static const SDL_sem_impl_t SDL_sem_impl_kern = {
SDL_sem *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;
#if !SDL_WINAPI_FAMILY_PHONE
if (!SDL_GetHintBoolean(SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL, SDL_FALSE)) {
#if __WINRT__
#ifdef __WINRT__
/* Link statically on this platform */
impl = &SDL_sem_impl_atom;
#else

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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"
#if SDL_THREAD_WINDOWS
#ifdef SDL_THREAD_WINDOWS
/* Win32 thread management routines for SDL */
@ -49,7 +49,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;
@ -98,7 +98,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;
@ -118,7 +118,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;
@ -130,7 +130,7 @@ void SDL_SYS_SetupThread(const char *name)
}
}
if (pSetThreadDescription != NULL) {
if (pSetThreadDescription) {
WCHAR *strw = WIN_UTF8ToStringW(name);
if (strw) {
pSetThreadDescription(GetCurrentThread(), strw);
@ -159,7 +159,7 @@ void SDL_SYS_SetupThread(const char *name)
inf.dwFlags = 0;
/* The debugger catches this, renames the thread, continues on. */
RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR *)&inf);
RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG_PTR), (const ULONG_PTR *)&inf);
}
}
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 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-2025 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
@ -21,7 +21,7 @@
#include "../../SDL_internal.h"
#if SDL_THREAD_WINDOWS
#ifdef SDL_THREAD_WINDOWS
#include "../../core/windows/SDL_windows.h"
@ -43,27 +43,27 @@
static DWORD thread_local_storage = TLS_OUT_OF_INDEXES;
static SDL_bool generic_local_storage = SDL_FALSE;
SDL_TLSData *SDL_SYS_GetTLSData(void)
void SDL_SYS_InitTLSData(void)
{
if (thread_local_storage == TLS_OUT_OF_INDEXES && !generic_local_storage) {
static SDL_SpinLock lock;
SDL_AtomicLock(&lock);
if (thread_local_storage == TLS_OUT_OF_INDEXES && !generic_local_storage) {
DWORD storage = TlsAlloc();
if (storage != TLS_OUT_OF_INDEXES) {
SDL_MemoryBarrierRelease();
thread_local_storage = storage;
} else {
generic_local_storage = SDL_TRUE;
}
thread_local_storage = TlsAlloc();
if (thread_local_storage == TLS_OUT_OF_INDEXES) {
SDL_Generic_InitTLSData();
generic_local_storage = SDL_TRUE;
}
SDL_AtomicUnlock(&lock);
}
}
SDL_TLSData *SDL_SYS_GetTLSData(void)
{
if (generic_local_storage) {
return SDL_Generic_GetTLSData();
}
SDL_MemoryBarrierAcquire();
return (SDL_TLSData *)TlsGetValue(thread_local_storage);
if (thread_local_storage != TLS_OUT_OF_INDEXES) {
return (SDL_TLSData *)TlsGetValue(thread_local_storage);
}
return NULL;
}
int SDL_SYS_SetTLSData(SDL_TLSData *data)
@ -71,12 +71,26 @@ int SDL_SYS_SetTLSData(SDL_TLSData *data)
if (generic_local_storage) {
return SDL_Generic_SetTLSData(data);
}
if (!TlsSetValue(thread_local_storage, data)) {
return SDL_SetError("TlsSetValue() failed");
return WIN_SetError("TlsSetValue()");
}
return 0;
}
void SDL_SYS_QuitTLSData(void)
{
if (generic_local_storage) {
SDL_Generic_QuitTLSData();
generic_local_storage = SDL_FALSE;
} else {
if (thread_local_storage != TLS_OUT_OF_INDEXES) {
TlsFree(thread_local_storage);
thread_local_storage = TLS_OUT_OF_INDEXES;
}
}
}
#endif /* SDL_THREAD_WINDOWS */
/* vi: set ts=4 sw=4 expandtab: */