Updates the SDL library to the latest standard bugfix release

This commit is contained in:
JeffR 2023-07-13 15:20:29 -05:00
parent cb766f2878
commit 083d2175ea
1280 changed files with 343926 additions and 179615 deletions

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -28,16 +28,21 @@
#include "SDL_thread.h"
#include "SDL_thread_c.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/* This function creates a thread, passing args to SDL_RunThread(),
saves a system-dependent thread id in thread->id, and returns 0
on success.
*/
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
extern int SDL_SYS_CreateThread(SDL_Thread * thread,
extern int SDL_SYS_CreateThread(SDL_Thread *thread,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread);
#else
extern int SDL_SYS_CreateThread(SDL_Thread * thread);
extern int SDL_SYS_CreateThread(SDL_Thread *thread);
#endif
/* This function does any necessary setup in the child thread */
@ -49,10 +54,10 @@ extern int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority);
/* This function waits for the thread to finish and frees any data
allocated by SDL_SYS_CreateThread()
*/
extern void SDL_SYS_WaitThread(SDL_Thread * thread);
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);
extern void SDL_SYS_DetachThread(SDL_Thread *thread);
/* Get the thread local storage for this thread */
extern SDL_TLSData *SDL_SYS_GetTLSData(void);
@ -62,9 +67,14 @@ extern int SDL_SYS_SetTLSData(SDL_TLSData *data);
/* 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,
SDL_CreateThreadInternal(int(SDLCALL *fn)(void *), const char *name,
const size_t stacksize, void *data);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_systhread_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -28,28 +28,24 @@
#include "SDL_hints.h"
#include "../SDL_error_c.h"
SDL_TLSID
SDL_TLSCreate()
SDL_TLSID SDL_TLSCreate()
{
static SDL_atomic_t SDL_tls_id;
return SDL_AtomicIncRef(&SDL_tls_id)+1;
return SDL_AtomicIncRef(&SDL_tls_id) + 1;
}
void *
SDL_TLSGet(SDL_TLSID id)
void *SDL_TLSGet(SDL_TLSID id)
{
SDL_TLSData *storage;
storage = SDL_SYS_GetTLSData();
if (!storage || id == 0 || id > storage->limit) {
if (storage == NULL || id == 0 || id > storage->limit) {
return NULL;
}
return storage->array[id-1].data;
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, void(SDLCALL *destructor)(void *))
{
SDL_TLSData *storage;
@ -58,13 +54,13 @@ SDL_TLSSet(SDL_TLSID id, const void *value, void (SDLCALL *destructor)(void *))
}
storage = SDL_SYS_GetTLSData();
if (!storage || (id > storage->limit)) {
if (storage == NULL || (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) {
storage = (SDL_TLSData *)SDL_realloc(storage, sizeof(*storage) + (newlimit - 1) * sizeof(storage->array[0]));
if (storage == NULL) {
return SDL_OutOfMemory();
}
storage->limit = newlimit;
@ -77,13 +73,12 @@ SDL_TLSSet(SDL_TLSID id, const void *value, void (SDLCALL *destructor)(void *))
}
}
storage->array[id-1].data = SDL_const_cast(void*, value);
storage->array[id-1].destructor = destructor;
storage->array[id - 1].data = SDL_const_cast(void *, value);
storage->array[id - 1].destructor = destructor;
return 0;
}
void
SDL_TLSCleanup()
void SDL_TLSCleanup()
{
SDL_TLSData *storage;
@ -100,7 +95,6 @@ SDL_TLSCleanup()
}
}
/* This is a generic implementation of thread-local storage which doesn't
require additional OS support.
@ -109,7 +103,8 @@ SDL_TLSCleanup()
storage this implementation should be improved to be production quality.
*/
typedef struct SDL_TLSEntry {
typedef struct SDL_TLSEntry
{
SDL_threadID thread;
SDL_TLSData *storage;
struct SDL_TLSEntry *next;
@ -118,23 +113,21 @@ typedef struct SDL_TLSEntry {
static SDL_mutex *SDL_generic_TLS_mutex;
static SDL_TLSEntry *SDL_generic_TLS;
SDL_TLSData *
SDL_Generic_GetTLSData(void)
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) {
if (SDL_generic_TLS_mutex == NULL) {
static SDL_SpinLock tls_lock;
SDL_AtomicLock(&tls_lock);
if (!SDL_generic_TLS_mutex) {
if (SDL_generic_TLS_mutex == NULL) {
SDL_mutex *mutex = SDL_CreateMutex();
SDL_MemoryBarrierRelease();
SDL_generic_TLS_mutex = mutex;
if (!SDL_generic_TLS_mutex) {
if (SDL_generic_TLS_mutex == NULL) {
SDL_AtomicUnlock(&tls_lock);
return NULL;
}
@ -158,8 +151,7 @@ SDL_Generic_GetTLSData(void)
return storage;
}
int
SDL_Generic_SetTLSData(SDL_TLSData *storage)
int SDL_Generic_SetTLSData(SDL_TLSData *data)
{
SDL_threadID thread = SDL_ThreadID();
SDL_TLSEntry *prev, *entry;
@ -169,10 +161,10 @@ SDL_Generic_SetTLSData(SDL_TLSData *storage)
prev = NULL;
for (entry = SDL_generic_TLS; entry; entry = entry->next) {
if (entry->thread == thread) {
if (storage) {
entry->storage = storage;
if (data != NULL) {
entry->storage = data;
} else {
if (prev) {
if (prev != NULL) {
prev->next = entry->next;
} else {
SDL_generic_TLS = entry->next;
@ -183,36 +175,54 @@ SDL_Generic_SetTLSData(SDL_TLSData *storage)
}
prev = entry;
}
if (!entry) {
if (entry == NULL) {
entry = (SDL_TLSEntry *)SDL_malloc(sizeof(*entry));
if (entry) {
entry->thread = thread;
entry->storage = storage;
entry->storage = data;
entry->next = SDL_generic_TLS;
SDL_generic_TLS = entry;
}
}
SDL_UnlockMutex(SDL_generic_TLS_mutex);
if (!entry) {
if (entry == NULL) {
return SDL_OutOfMemory();
}
return 0;
}
/* Non-thread-safe global error variable */
static SDL_error *SDL_GetStaticErrBuf()
{
static SDL_error SDL_global_error;
static char SDL_global_error_str[128];
SDL_global_error.str = SDL_global_error_str;
SDL_global_error.len = sizeof(SDL_global_error_str);
return &SDL_global_error;
}
#if !SDL_THREADS_DISABLED
static void SDLCALL SDL_FreeErrBuf(void *data)
{
SDL_error *errbuf = (SDL_error *)data;
if (errbuf->str) {
errbuf->free_func(errbuf->str);
}
errbuf->free_func(errbuf);
}
#endif
/* Routine to get the thread-specific error variable */
SDL_error *
SDL_GetErrBuf(void)
SDL_error *SDL_GetErrBuf(void)
{
#if SDL_THREADS_DISABLED
/* Non-thread-safe global error variable */
static SDL_error SDL_global_error;
return &SDL_global_error;
return SDL_GetStaticErrBuf();
#else
static SDL_SpinLock tls_lock;
static SDL_bool tls_being_created;
static SDL_TLSID tls_errbuf;
static SDL_error SDL_global_errbuf;
const SDL_error *ALLOCATION_IN_PROGRESS = (SDL_error *)-1;
SDL_error *errbuf;
@ -233,35 +243,42 @@ SDL_GetErrBuf(void)
SDL_AtomicUnlock(&tls_lock);
}
if (!tls_errbuf) {
return &SDL_global_errbuf;
return SDL_GetStaticErrBuf();
}
SDL_MemoryBarrierAcquire();
errbuf = (SDL_error *)SDL_TLSGet(tls_errbuf);
if (errbuf == ALLOCATION_IN_PROGRESS) {
return &SDL_global_errbuf;
return SDL_GetStaticErrBuf();
}
if (!errbuf) {
if (errbuf == NULL) {
/* Get the original memory functions for this allocation because the lifetime
* of the error buffer may span calls to SDL_SetMemoryFunctions() by the app
*/
SDL_realloc_func realloc_func;
SDL_free_func free_func;
SDL_GetOriginalMemoryFunctions(NULL, NULL, &realloc_func, &free_func);
/* Mark that we're in the middle of allocating our buffer */
SDL_TLSSet(tls_errbuf, ALLOCATION_IN_PROGRESS, NULL);
errbuf = (SDL_error *)SDL_malloc(sizeof(*errbuf));
if (!errbuf) {
errbuf = (SDL_error *)realloc_func(NULL, sizeof(*errbuf));
if (errbuf == NULL) {
SDL_TLSSet(tls_errbuf, NULL, NULL);
return &SDL_global_errbuf;
return SDL_GetStaticErrBuf();
}
SDL_zerop(errbuf);
SDL_TLSSet(tls_errbuf, errbuf, SDL_free);
errbuf->realloc_func = realloc_func;
errbuf->free_func = free_func;
SDL_TLSSet(tls_errbuf, errbuf, SDL_FreeErrBuf);
}
return errbuf;
#endif /* SDL_THREADS_DISABLED */
}
void
SDL_RunThread(SDL_Thread *thread)
void SDL_RunThread(SDL_Thread *thread)
{
void *userdata = thread->userdata;
int (SDLCALL * userfunc) (void *) = thread->userfunc;
int(SDLCALL * userfunc)(void *) = thread->userfunc;
int *statusloc = &thread->status;
@ -294,27 +311,25 @@ SDL_RunThread(SDL_Thread *thread)
#undef SDL_CreateThreadWithStackSize
#endif
#if SDL_DYNAMIC_API
#define SDL_CreateThread SDL_CreateThread_REAL
#define SDL_CreateThread SDL_CreateThread_REAL
#define SDL_CreateThreadWithStackSize SDL_CreateThreadWithStackSize_REAL
#endif
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
SDL_Thread *
SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
const char *name, const size_t stacksize, void *data,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread)
SDL_Thread *SDL_CreateThreadWithStackSize(int(SDLCALL *fn)(void *),
const char *name, const size_t stacksize, void *data,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread)
#else
SDL_Thread *
SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
const char *name, const size_t stacksize, void *data)
SDL_Thread *SDL_CreateThreadWithStackSize(int(SDLCALL *fn)(void *),
const char *name, const size_t stacksize, void *data)
#endif
{
SDL_Thread *thread;
int ret;
/* Allocate memory for the thread info structure */
thread = (SDL_Thread *) SDL_calloc(1, sizeof(*thread));
thread = (SDL_Thread *)SDL_calloc(1, sizeof(*thread));
if (thread == NULL) {
SDL_OutOfMemory();
return NULL;
@ -354,14 +369,12 @@ SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
}
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
DECLSPEC SDL_Thread *SDLCALL
SDL_CreateThread(int (SDLCALL * fn) (void *),
DECLSPEC SDL_Thread *SDLCALL SDL_CreateThread(int(SDLCALL *fn)(void *),
const char *name, void *data,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread)
#else
DECLSPEC SDL_Thread *SDLCALL
SDL_CreateThread(int (SDLCALL * fn) (void *),
DECLSPEC SDL_Thread *SDLCALL SDL_CreateThread(int(SDLCALL *fn)(void *),
const char *name, void *data)
#endif
{
@ -373,9 +386,9 @@ SDL_CreateThread(int (SDLCALL * fn) (void *),
if (stackhint != NULL) {
char *endp = NULL;
const Sint64 hintval = SDL_strtoll(stackhint, &endp, 10);
if ((*stackhint != '\0') && (*endp == '\0')) { /* a valid number? */
if (hintval > 0) { /* reject bogus values. */
stacksize = (size_t) hintval;
if ((*stackhint != '\0') && (*endp == '\0')) { /* a valid number? */
if (hintval > 0) { /* reject bogus values. */
stacksize = (size_t)hintval;
}
}
}
@ -387,9 +400,9 @@ SDL_CreateThread(int (SDLCALL * fn) (void *),
#endif
}
SDL_Thread *
SDL_CreateThreadInternal(int (SDLCALL * fn) (void *), const char *name,
const size_t stacksize, void *data) {
SDL_Thread *SDL_CreateThreadInternal(int(SDLCALL *fn)(void *), const char *name,
const size_t stacksize, void *data)
{
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
return SDL_CreateThreadWithStackSize(fn, name, stacksize, data, NULL, NULL);
#else
@ -397,8 +410,7 @@ SDL_CreateThreadInternal(int (SDLCALL * fn) (void *), const char *name,
#endif
}
SDL_threadID
SDL_GetThreadID(SDL_Thread * thread)
SDL_threadID SDL_GetThreadID(SDL_Thread *thread)
{
SDL_threadID id;
@ -410,8 +422,7 @@ SDL_GetThreadID(SDL_Thread * thread)
return id;
}
const char *
SDL_GetThreadName(SDL_Thread * thread)
const char *SDL_GetThreadName(SDL_Thread *thread)
{
if (thread) {
return thread->name;
@ -420,14 +431,12 @@ SDL_GetThreadName(SDL_Thread * thread)
}
}
int
SDL_SetThreadPriority(SDL_ThreadPriority priority)
int SDL_SetThreadPriority(SDL_ThreadPriority priority)
{
return SDL_SYS_SetThreadPriority(priority);
}
void
SDL_WaitThread(SDL_Thread * thread, int *status)
void SDL_WaitThread(SDL_Thread *thread, int *status)
{
if (thread) {
SDL_SYS_WaitThread(thread);
@ -441,10 +450,9 @@ SDL_WaitThread(SDL_Thread * thread, int *status)
}
}
void
SDL_DetachThread(SDL_Thread * thread)
void SDL_DetachThread(SDL_Thread *thread)
{
if (!thread) {
if (thread == NULL) {
return;
}
@ -455,9 +463,9 @@ SDL_DetachThread(SDL_Thread * thread)
/* all other states are pretty final, see where we landed. */
const int thread_state = SDL_AtomicGet(&thread->state);
if ((thread_state == SDL_THREAD_STATE_DETACHED) || (thread_state == SDL_THREAD_STATE_CLEANED)) {
return; /* already detached (you shouldn't call this twice!) */
return; /* already detached (you shouldn't call this twice!) */
} else if (thread_state == SDL_THREAD_STATE_ZOMBIE) {
SDL_WaitThread(thread, NULL); /* already done, clean it up. */
SDL_WaitThread(thread, NULL); /* already done, clean it up. */
} else {
SDL_assert(0 && "Unexpected thread state");
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -32,10 +32,14 @@
#include "pthread/SDL_systhread_c.h"
#elif SDL_THREAD_WINDOWS
#include "windows/SDL_systhread_c.h"
#elif SDL_THREAD_PS2
#include "ps2/SDL_systhread_c.h"
#elif SDL_THREAD_PSP
#include "psp/SDL_systhread_c.h"
#elif SDL_THREAD_VITA
#include "vita/SDL_systhread_c.h"
#elif SDL_THREAD_N3DS
#include "n3ds/SDL_systhread_c.h"
#elif SDL_THREAD_STDCPP
#include "stdcpp/SDL_systhread_c.h"
#elif SDL_THREAD_OS2
@ -62,25 +66,27 @@ struct SDL_Thread
SDL_threadID threadid;
SYS_ThreadHandle handle;
int status;
SDL_atomic_t state; /* SDL_THREAD_STATE_* */
SDL_atomic_t state; /* SDL_THREAD_STATE_* */
SDL_error errbuf;
char *name;
size_t stacksize; /* 0 for default, >0 for user-specified stack size. */
int (SDLCALL * userfunc) (void *);
size_t stacksize; /* 0 for default, >0 for user-specified stack size. */
int(SDLCALL *userfunc)(void *);
void *userdata;
void *data;
void *endfunc; /* only used on some platforms. */
void *endfunc; /* only used on some platforms. */
};
/* This is the function called to run a thread */
extern void SDL_RunThread(SDL_Thread *thread);
/* This is the system-independent thread local storage structure */
typedef struct {
typedef struct
{
unsigned int limit;
struct {
struct
{
void *data;
void (SDLCALL *destructor)(void*);
void(SDLCALL *destructor)(void *);
} array[1];
} SDL_TLSData;

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -53,12 +53,11 @@ typedef struct SDL_cond_generic
} SDL_cond_generic;
/* Create a condition variable */
SDL_cond *
SDL_CreateCond_generic(void)
SDL_cond *SDL_CreateCond_generic(void)
{
SDL_cond_generic *cond;
cond = (SDL_cond_generic *) SDL_malloc(sizeof(SDL_cond_generic));
cond = (SDL_cond_generic *)SDL_malloc(sizeof(SDL_cond_generic));
if (cond) {
cond->lock = SDL_CreateMutex();
cond->wait_sem = SDL_CreateSemaphore(0);
@ -75,8 +74,7 @@ SDL_CreateCond_generic(void)
}
/* Destroy a condition variable */
void
SDL_DestroyCond_generic(SDL_cond * _cond)
void SDL_DestroyCond_generic(SDL_cond *_cond)
{
SDL_cond_generic *cond = (SDL_cond_generic *)_cond;
if (cond) {
@ -94,11 +92,10 @@ SDL_DestroyCond_generic(SDL_cond * _cond)
}
/* Restart one of the threads that are waiting on the condition variable */
int
SDL_CondSignal_generic(SDL_cond * _cond)
int SDL_CondSignal_generic(SDL_cond *_cond)
{
SDL_cond_generic *cond = (SDL_cond_generic *)_cond;
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -119,11 +116,10 @@ SDL_CondSignal_generic(SDL_cond * _cond)
}
/* Restart all threads that are waiting on the condition variable */
int
SDL_CondBroadcast_generic(SDL_cond * _cond)
int SDL_CondBroadcast_generic(SDL_cond *_cond)
{
SDL_cond_generic *cond = (SDL_cond_generic *)_cond;
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -174,13 +170,12 @@ Thread B:
SDL_CondSignal(cond);
SDL_UnlockMutex(lock);
*/
int
SDL_CondWaitTimeout_generic(SDL_cond * _cond, SDL_mutex * mutex, Uint32 ms)
int SDL_CondWaitTimeout_generic(SDL_cond *_cond, SDL_mutex *mutex, Uint32 ms)
{
SDL_cond_generic *cond = (SDL_cond_generic *)_cond;
int retval;
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -230,8 +225,7 @@ SDL_CondWaitTimeout_generic(SDL_cond * _cond, SDL_mutex * mutex, Uint32 ms)
}
/* Wait on the condition variable forever */
int
SDL_CondWait_generic(SDL_cond * cond, SDL_mutex * mutex)
int SDL_CondWait_generic(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout_generic(cond, mutex, SDL_MUTEX_MAXWAIT);
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -27,13 +27,13 @@
#if SDL_THREAD_GENERIC_COND_SUFFIX
SDL_cond * SDL_CreateCond_generic(void);
void SDL_DestroyCond_generic(SDL_cond * cond);
int SDL_CondSignal_generic(SDL_cond * cond);
int SDL_CondBroadcast_generic(SDL_cond * cond);
int SDL_CondWait_generic(SDL_cond * cond, SDL_mutex * mutex);
int SDL_CondWaitTimeout_generic(SDL_cond * cond,
SDL_mutex * mutex, Uint32 ms);
SDL_cond *SDL_CreateCond_generic(void);
void SDL_DestroyCond_generic(SDL_cond *cond);
int SDL_CondSignal_generic(SDL_cond *cond);
int SDL_CondBroadcast_generic(SDL_cond *cond);
int SDL_CondWait_generic(SDL_cond *cond, SDL_mutex *mutex);
int SDL_CondWaitTimeout_generic(SDL_cond *cond,
SDL_mutex *mutex, Uint32 ms);
#endif /* SDL_THREAD_GENERIC_COND_SUFFIX */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -25,7 +25,6 @@
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
struct SDL_mutex
{
int recursive;
@ -34,13 +33,14 @@ struct SDL_mutex
};
/* Create a mutex */
SDL_mutex *
SDL_CreateMutex(void)
SDL_mutex *SDL_CreateMutex(void)
{
SDL_mutex *mutex;
/* Allocate mutex memory */
mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex));
#if !SDL_THREADS_DISABLED
if (mutex) {
/* Create the mutex semaphore, with initial value 1 */
mutex->sem = SDL_CreateSemaphore(1);
@ -53,12 +53,13 @@ SDL_CreateMutex(void)
} else {
SDL_OutOfMemory();
}
#endif /* !SDL_THREADS_DISABLED */
return mutex;
}
/* Free the mutex */
void
SDL_DestroyMutex(SDL_mutex * mutex)
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex) {
if (mutex->sem) {
@ -69,8 +70,7 @@ SDL_DestroyMutex(SDL_mutex * mutex)
}
/* Lock the mutex */
int
SDL_LockMutex(SDL_mutex * mutex)
int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
#if SDL_THREADS_DISABLED
return 0;
@ -78,7 +78,7 @@ SDL_LockMutex(SDL_mutex * mutex)
SDL_threadID this_thread;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
this_thread = SDL_ThreadID();
@ -99,8 +99,7 @@ SDL_LockMutex(SDL_mutex * mutex)
}
/* try Lock the mutex */
int
SDL_TryLockMutex(SDL_mutex * mutex)
int SDL_TryLockMutex(SDL_mutex *mutex)
{
#if SDL_THREADS_DISABLED
return 0;
@ -109,7 +108,7 @@ SDL_TryLockMutex(SDL_mutex * mutex)
SDL_threadID this_thread;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
this_thread = SDL_ThreadID();
@ -132,14 +131,13 @@ SDL_TryLockMutex(SDL_mutex * mutex)
}
/* Unlock the mutex */
int
SDL_mutexV(SDL_mutex * mutex)
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
#if SDL_THREADS_DISABLED
return 0;
#else
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
/* If we don't own the mutex, we can't unlock it */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -26,47 +26,39 @@
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
#if SDL_THREADS_DISABLED
SDL_sem *
SDL_CreateSemaphore(Uint32 initial_value)
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_SetError("SDL not built with thread support");
return (SDL_sem *) 0;
return (SDL_sem *)0;
}
void
SDL_DestroySemaphore(SDL_sem * sem)
void SDL_DestroySemaphore(SDL_sem *sem)
{
}
int
SDL_SemTryWait(SDL_sem * sem)
int SDL_SemTryWait(SDL_sem *sem)
{
return SDL_SetError("SDL not built with thread support");
}
int
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
return SDL_SetError("SDL not built with thread support");
}
int
SDL_SemWait(SDL_sem * sem)
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SetError("SDL not built with thread support");
}
Uint32
SDL_SemValue(SDL_sem * sem)
Uint32 SDL_SemValue(SDL_sem *sem)
{
return 0;
}
int
SDL_SemPost(SDL_sem * sem)
int SDL_SemPost(SDL_sem *sem)
{
return SDL_SetError("SDL not built with thread support");
}
@ -81,13 +73,12 @@ struct SDL_semaphore
SDL_cond *count_nonzero;
};
SDL_sem *
SDL_CreateSemaphore(Uint32 initial_value)
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem;
sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
if (!sem) {
sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
if (sem == NULL) {
SDL_OutOfMemory();
return NULL;
}
@ -107,8 +98,7 @@ SDL_CreateSemaphore(Uint32 initial_value)
/* WARNING:
You cannot call this function when another thread is using the semaphore.
*/
void
SDL_DestroySemaphore(SDL_sem * sem)
void SDL_DestroySemaphore(SDL_sem *sem)
{
if (sem) {
sem->count = 0xFFFFFFFF;
@ -126,12 +116,11 @@ SDL_DestroySemaphore(SDL_sem * sem)
}
}
int
SDL_SemTryWait(SDL_sem * sem)
int SDL_SemTryWait(SDL_sem *sem)
{
int retval;
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
@ -146,12 +135,11 @@ SDL_SemTryWait(SDL_sem * sem)
return retval;
}
int
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
int retval;
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
@ -176,14 +164,12 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
return retval;
}
int
SDL_SemWait(SDL_sem * sem)
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
Uint32
SDL_SemValue(SDL_sem * sem)
Uint32 SDL_SemValue(SDL_sem *sem)
{
Uint32 value;
@ -196,10 +182,9 @@ SDL_SemValue(SDL_sem * sem)
return value;
}
int
SDL_SemPost(SDL_sem * sem)
int SDL_SemPost(SDL_sem *sem)
{
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -26,44 +26,37 @@
#include "../SDL_systhread.h"
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
int
SDL_SYS_CreateThread(SDL_Thread * thread,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread)
int SDL_SYS_CreateThread(SDL_Thread *thread,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread)
#else
int
SDL_SYS_CreateThread(SDL_Thread * thread)
int SDL_SYS_CreateThread(SDL_Thread *thread)
#endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */
{
return SDL_SetError("Threads are not supported on this platform");
}
void
SDL_SYS_SetupThread(const char *name)
void SDL_SYS_SetupThread(const char *name)
{
return;
}
SDL_threadID
SDL_ThreadID(void)
SDL_threadID SDL_ThreadID(void)
{
return (0);
return 0;
}
int
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
return (0);
return 0;
}
void
SDL_SYS_WaitThread(SDL_Thread * thread)
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
return;
}
void
SDL_SYS_DetachThread(SDL_Thread * thread)
void SDL_SYS_DetachThread(SDL_Thread *thread)
{
return;
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -22,15 +22,12 @@
#include "../../SDL_internal.h"
#include "../SDL_thread_c.h"
SDL_TLSData *
SDL_SYS_GetTLSData(void)
SDL_TLSData *SDL_SYS_GetTLSData(void)
{
return SDL_Generic_GetTLSData();
}
int
SDL_SYS_SetTLSData(SDL_TLSData *data)
int SDL_SYS_SetTLSData(SDL_TLSData *data)
{
return SDL_Generic_SetTLSData(data);
}

View file

@ -0,0 +1,127 @@
/*
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

@ -0,0 +1,88 @@
/*
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 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));
if (mutex) {
RecursiveLock_Init(&mutex->lock);
} else {
SDL_OutOfMemory();
}
return mutex;
}
/* Free the mutex */
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex) {
SDL_free(mutex);
}
}
/* Lock the mutex */
int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
if (mutex == NULL) {
return 0;
}
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);
}
/* Unlock the mutex */
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
if (mutex == NULL) {
return 0;
}
RecursiveLock_Unlock(&mutex->lock);
return 0;
}
#endif /* SDL_THREAD_N3DS */
/* vi: set sts=4 ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,37 @@
/*
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"
#ifndef SDL_sysmutex_c_h_
#define SDL_sysmutex_c_h_
#include <3ds.h>
#include "SDL_mutex.h"
struct SDL_mutex
{
RecursiveLock lock;
};
#endif /* SDL_sysmutex_c_h */
/* vi: set sts=4 ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,143 @@
/*
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 semaphores using libctru's LightSemaphore */
#include <3ds.h>
#include "SDL_thread.h"
#include "SDL_timer.h"
int WaitOnSemaphoreFor(SDL_sem *sem, Uint32 timeout);
struct SDL_semaphore
{
LightSemaphore semaphore;
};
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem;
if (initial_value > SDL_MAX_SINT16) {
SDL_SetError("Initial semaphore value too high for this platform");
return NULL;
}
sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
if (sem == NULL) {
SDL_OutOfMemory();
return NULL;
}
LightSemaphore_Init(&sem->semaphore, initial_value, SDL_MAX_SINT16);
return sem;
}
/* WARNING:
You cannot call this function when another thread is using the semaphore.
*/
void SDL_DestroySemaphore(SDL_sem *sem)
{
SDL_free(sem);
}
int SDL_SemTryWait(SDL_sem *sem)
{
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
if (LightSemaphore_TryAcquire(&sem->semaphore, 1) != 0) {
/* If we failed, yield to avoid starvation on busy waits */
svcSleepThread(1);
return SDL_MUTEX_TIMEDOUT;
}
return 0;
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
if (timeout == SDL_MUTEX_MAXWAIT) {
LightSemaphore_Acquire(&sem->semaphore, 1);
return 0;
}
if (LightSemaphore_TryAcquire(&sem->semaphore, 1) != 0) {
return WaitOnSemaphoreFor(sem, timeout);
}
return 0;
}
int WaitOnSemaphoreFor(SDL_sem *sem, Uint32 timeout)
{
Uint64 stop_time = SDL_GetTicks64() + timeout;
Uint64 current_time = SDL_GetTicks64();
while (current_time < stop_time) {
if (LightSemaphore_TryAcquire(&sem->semaphore, 1) == 0) {
return 0;
}
/* 100 microseconds seems to be the sweet spot */
svcSleepThread(100000LL);
current_time = SDL_GetTicks64();
}
/* If we failed, yield to avoid starvation on busy waits */
svcSleepThread(1);
return SDL_MUTEX_TIMEDOUT;
}
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
Uint32 SDL_SemValue(SDL_sem *sem)
{
if (sem == NULL) {
SDL_InvalidParamError("sem");
return 0;
}
return sem->semaphore.current_count;
}
int SDL_SemPost(SDL_sem *sem)
{
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
LightSemaphore_Release(&sem->semaphore, 1);
return 0;
}
#endif /* SDL_THREAD_N3DS */
/* vi: set sts=4 ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,141 @@
/*
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
/* Thread management routines for SDL */
#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)
#define N3DS_THREAD_PRIORITY_LOW 0x3F /**< Minimum priority */
#define N3DS_THREAD_PRIORITY_MEDIUM 0x2F /**< Slightly higher than main thread (0x30) */
#define N3DS_THREAD_PRIORITY_HIGH 0x19 /**< High priority for non-video work */
#define N3DS_THREAD_PRIORITY_TIME_CRITICAL 0x18 /**< Highest priority */
static size_t GetStackSize(size_t requested_size);
static void ThreadEntry(void *arg)
{
SDL_RunThread((SDL_Thread *)arg);
threadExit(0);
}
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
#error "SDL_PASSED_BEGINTHREAD_ENDTHREAD is not supported on N3DS"
#endif
int SDL_SYS_CreateThread(SDL_Thread *thread)
{
s32 priority;
size_t stack_size = GetStackSize(thread->stacksize);
svcGetThreadPriority(&priority, CUR_THREAD_HANDLE);
thread->handle = threadCreate(ThreadEntry,
thread,
stack_size,
priority,
-1,
false);
if (thread->handle == NULL) {
return SDL_SetError("Couldn't create thread");
}
return 0;
}
static size_t GetStackSize(size_t requested_size)
{
if (requested_size == 0) {
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;
}
void SDL_SYS_SetupThread(const char *name)
{
return;
}
SDL_threadID SDL_ThreadID(void)
{
u32 thread_ID = 0;
svcGetThreadId(&thread_ID, CUR_THREAD_HANDLE);
return (SDL_threadID)thread_ID;
}
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority sdl_priority)
{
s32 svc_priority;
switch (sdl_priority) {
case SDL_THREAD_PRIORITY_LOW:
svc_priority = N3DS_THREAD_PRIORITY_LOW;
break;
case SDL_THREAD_PRIORITY_NORMAL:
svc_priority = N3DS_THREAD_PRIORITY_MEDIUM;
break;
case SDL_THREAD_PRIORITY_HIGH:
svc_priority = N3DS_THREAD_PRIORITY_HIGH;
break;
case SDL_THREAD_PRIORITY_TIME_CRITICAL:
svc_priority = N3DS_THREAD_PRIORITY_TIME_CRITICAL;
break;
default:
svc_priority = N3DS_THREAD_PRIORITY_MEDIUM;
}
return (int)svcSetThreadPriority(CUR_THREAD_HANDLE, svc_priority);
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
Result res = threadJoin(thread->handle, U64_MAX);
/*
Detached threads can be waited on, but should NOT be cleaned manually
as it would result in a fatal error.
*/
if (R_SUCCEEDED(res) && SDL_AtomicGet(&thread->state) != SDL_THREAD_STATE_DETACHED) {
threadFree(thread->handle);
}
}
void SDL_SYS_DetachThread(SDL_Thread *thread)
{
threadDetach(thread->handle);
}
#endif /* SDL_THREAD_N3DS */
/* vi: set sts=4 ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,32 @@
/*
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"
#ifndef SDL_systhread_c_h_
#define SDL_systhread_c_h_
#include <3ds.h>
typedef Thread SYS_ThreadHandle;
#endif /* SDL_systhread_c_h_ */
/* vi: set sts=4 ts=4 sw=4 expandtab: */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -32,53 +32,62 @@ struct SDL_mutex
TInt handle;
};
extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
extern TInt CreateUnique(TInt (*aFunc)(const TDesC &aName, TAny *, TAny *), TAny *, TAny *);
static TInt NewMutex(const TDesC& aName, TAny* aPtr1, TAny*)
static TInt NewMutex(const TDesC &aName, TAny *aPtr1, TAny *)
{
return ((RMutex*)aPtr1)->CreateGlobal(aName);
return ((RMutex *)aPtr1)->CreateGlobal(aName);
}
/* Create a mutex */
SDL_mutex *
SDL_CreateMutex(void)
SDL_mutex *SDL_CreateMutex(void)
{
RMutex rmutex;
TInt status = CreateUnique(NewMutex, &rmutex, NULL);
if(status != KErrNone)
{
if (status != KErrNone) {
SDL_SetError("Couldn't create mutex.");
return NULL;
}
SDL_mutex* mutex = new /*(ELeave)*/ SDL_mutex;
SDL_mutex *mutex = new /*(ELeave)*/ SDL_mutex;
mutex->handle = rmutex.Handle();
return(mutex);
return mutex;
}
/* Free the mutex */
void
SDL_DestroyMutex(SDL_mutex * mutex)
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex)
{
if (mutex) {
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Signal();
rmutex.Close();
delete(mutex);
delete (mutex);
mutex = NULL;
}
}
/* Lock the mutex */
int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
if (mutex == NULL) {
return 0;
}
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Wait();
return 0;
}
/* Try to lock the mutex */
#if 0
int
SDL_TryLockMutex(SDL_mutex * mutex)
int SDL_TryLockMutex(SDL_mutex *mutex)
{
if (mutex == NULL)
{
SDL_SetError("Passed a NULL mutex.");
return -1;
return 0;
}
// Not yet implemented.
@ -86,38 +95,18 @@ SDL_TryLockMutex(SDL_mutex * mutex)
}
#endif
/* Lock the mutex */
int
SDL_LockMutex(SDL_mutex * mutex)
{
if (mutex == NULL)
{
SDL_SetError("Passed a NULL mutex.");
return -1;
}
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Wait();
return(0);
}
/* Unlock the mutex */
int
SDL_UnlockMutex(SDL_mutex * mutex)
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
if ( mutex == NULL )
{
SDL_SetError("Passed a NULL mutex.");
return -1;
if (mutex == NULL) {
return 0;
}
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Signal();
return(0);
return 0;
}
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -37,18 +37,17 @@ struct SDL_semaphore
struct TInfo
{
TInfo(TInt aTime, TInt aHandle) :
iTime(aTime), iHandle(aHandle), iVal(0) {}
TInfo(TInt aTime, TInt aHandle) : iTime(aTime), iHandle(aHandle), iVal(0) {}
TInt iTime;
TInt iHandle;
TInt iVal;
};
extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
extern TInt CreateUnique(TInt (*aFunc)(const TDesC &aName, TAny *, TAny *), TAny *, TAny *);
static TBool RunThread(TAny* aInfo)
static TBool RunThread(TAny *aInfo)
{
TInfo* info = STATIC_CAST(TInfo*, aInfo);
TInfo *info = STATIC_CAST(TInfo *, aInfo);
User::After(info->iTime);
RSemaphore sema;
sema.SetHandle(info->iHandle);
@ -57,21 +56,15 @@ static TBool RunThread(TAny* aInfo)
return 0;
}
static TInt
NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2)
static TInt NewThread(const TDesC &aName, TAny *aPtr1, TAny *aPtr2)
{
return ((RThread*)(aPtr1))->Create
(aName,
RunThread,
KDefaultStackSize,
NULL,
aPtr2);
return ((RThread *)(aPtr1))->Create(aName, RunThread, KDefaultStackSize, NULL, aPtr2);
}
static TInt NewSema(const TDesC& aName, TAny* aPtr1, TAny* aPtr2)
static TInt NewSema(const TDesC &aName, TAny *aPtr1, TAny *aPtr2)
{
TInt value = *((TInt*) aPtr2);
return ((RSemaphore*)aPtr1)->CreateGlobal(aName, value);
TInt value = *((TInt *)aPtr2);
return ((RSemaphore *)aPtr1)->CreateGlobal(aName, value);
}
static void WaitAll(SDL_sem *sem)
@ -79,32 +72,27 @@ static void WaitAll(SDL_sem *sem)
RSemaphore sema;
sema.SetHandle(sem->handle);
sema.Wait();
while(sem->count < 0)
{
while (sem->count < 0) {
sema.Wait();
}
}
SDL_sem *
SDL_CreateSemaphore(Uint32 initial_value)
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
RSemaphore s;
TInt status = CreateUnique(NewSema, &s, &initial_value);
if(status != KErrNone)
{
if (status != KErrNone) {
SDL_SetError("Couldn't create semaphore");
}
SDL_semaphore* sem = new /*(ELeave)*/ SDL_semaphore;
SDL_semaphore *sem = new /*(ELeave)*/ SDL_semaphore;
sem->handle = s.Handle();
sem->count = initial_value;
return(sem);
return sem;
}
void
SDL_DestroySemaphore(SDL_sem * sem)
void SDL_DestroySemaphore(SDL_sem *sem)
{
if (sem)
{
if (sem != NULL) {
RSemaphore sema;
sema.SetHandle(sem->handle);
sema.Signal(sema.Count());
@ -114,35 +102,29 @@ SDL_DestroySemaphore(SDL_sem * sem)
}
}
int
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
if (! sem)
{
SDL_SetError("Passed a NULL sem");
return -1;
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
if (timeout == SDL_MUTEX_MAXWAIT)
{
if (timeout == SDL_MUTEX_MAXWAIT) {
WaitAll(sem);
return SDL_MUTEX_MAXWAIT;
}
RThread thread;
TInfo* info = new (ELeave)TInfo(timeout, sem->handle);
TInt status = CreateUnique(NewThread, &thread, info);
TInfo *info = new (ELeave) TInfo(timeout, sem->handle);
TInt status = CreateUnique(NewThread, &thread, info);
if(status != KErrNone)
{
if (status != KErrNone) {
return status;
}
thread.Resume();
WaitAll(sem);
if(thread.ExitType() == EExitPending)
{
if (thread.ExitType() == EExitPending) {
thread.Kill(SDL_MUTEX_TIMEOUT);
}
@ -150,40 +132,36 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
return info->iVal;
}
int
SDL_SemTryWait(SDL_sem *sem)
int SDL_SemTryWait(SDL_sem *sem)
{
if(sem->count > 0)
{
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
if (sem->count > 0) {
sem->count--;
}
return SDL_MUTEX_TIMEOUT;
}
int
SDL_SemWait(SDL_sem * sem)
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
Uint32
SDL_SemValue(SDL_sem * sem)
Uint32 SDL_SemValue(SDL_sem *sem)
{
if (! sem)
{
SDL_SetError("Passed a NULL sem.");
if (sem == NULL) {
SDL_InvalidParamError("sem");
return 0;
}
return sem->count;
}
int
SDL_SemPost(SDL_sem * sem)
int SDL_SemPost(SDL_sem *sem)
{
if (! sem)
{
SDL_SetError("Passed a NULL sem.");
return -1;
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
sem->count++;
RSemaphore sema;

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -36,85 +36,67 @@ extern "C" {
static int object_count;
static int
RunThread(TAny* data)
static int RunThread(TAny *data)
{
SDL_RunThread((SDL_Thread*)data);
return(0);
SDL_RunThread((SDL_Thread *)data);
return 0;
}
static TInt
NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2)
static TInt NewThread(const TDesC &aName, TAny *aPtr1, TAny *aPtr2)
{
return ((RThread*)(aPtr1))->Create
(aName,
RunThread,
KDefaultStackSize,
NULL,
aPtr2);
return ((RThread *)(aPtr1))->Create(aName, RunThread, KDefaultStackSize, NULL, aPtr2);
}
int
CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny* aPtr1, TAny* aPtr2)
int CreateUnique(TInt (*aFunc)(const TDesC &aName, TAny *, TAny *), TAny *aPtr1, TAny *aPtr2)
{
TBuf<16> name;
TInt status = KErrNone;
do
{
TInt status = KErrNone;
do {
object_count++;
name.Format(_L("SDL_%x"), object_count);
status = aFunc(name, aPtr1, aPtr2);
}
while(status == KErrAlreadyExists);
} while (status == KErrAlreadyExists);
return status;
}
int
SDL_SYS_CreateThread(SDL_Thread *thread)
int SDL_SYS_CreateThread(SDL_Thread *thread)
{
RThread rthread;
TInt status = CreateUnique(NewThread, &rthread, thread);
if (status != KErrNone)
{
delete(((RThread*)(thread->handle)));
if (status != KErrNone) {
delete (RThread *)thread->handle;
thread->handle = NULL;
SDL_SetError("Not enough resources to create thread");
return(-1);
return SDL_SetError("Not enough resources to create thread");
}
rthread.Resume();
thread->handle = rthread.Handle();
return(0);
return 0;
}
void
SDL_SYS_SetupThread(const char *name)
void SDL_SYS_SetupThread(const char *name)
{
return;
}
SDL_threadID
SDL_ThreadID(void)
SDL_threadID SDL_ThreadID(void)
{
RThread current;
RThread current;
TThreadId id = current.Id();
return id;
}
int
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
return (0);
return 0;
}
void
SDL_SYS_WaitThread(SDL_Thread * thread)
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
RThread t;
t.Open(thread->threadid);
if(t.ExitReason() == EExitPending)
{
if (t.ExitReason() == EExitPending) {
TRequestStatus status;
t.Logon(status);
User::WaitForRequest(status);
@ -122,8 +104,7 @@ SDL_SYS_WaitThread(SDL_Thread * thread)
t.Close();
}
void
SDL_SYS_DetachThread(SDL_Thread * thread)
void SDL_SYS_DetachThread(SDL_Thread *thread)
{
return;
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -37,8 +37,7 @@ struct SDL_mutex {
};
/* Create a mutex */
SDL_mutex *
SDL_CreateMutex(void)
SDL_mutex *SDL_CreateMutex(void)
{
ULONG ulRC;
HMTX hMtx;
@ -53,8 +52,7 @@ SDL_CreateMutex(void)
}
/* Free the mutex */
void
SDL_DestroyMutex(SDL_mutex * mutex)
void SDL_DestroyMutex(SDL_mutex * mutex)
{
HMTX hMtx = (HMTX)mutex;
if (hMtx != NULLHANDLE) {
@ -66,14 +64,13 @@ SDL_DestroyMutex(SDL_mutex * mutex)
}
/* Lock the mutex */
int
SDL_LockMutex(SDL_mutex * mutex)
int SDL_LockMutex(SDL_mutex * mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
ULONG ulRC;
HMTX hMtx = (HMTX)mutex;
if (hMtx == NULLHANDLE)
return SDL_InvalidParamError("mutex");
return 0;
ulRC = DosRequestMutexSem(hMtx, SEM_INDEFINITE_WAIT);
if (ulRC != NO_ERROR) {
@ -85,14 +82,13 @@ SDL_LockMutex(SDL_mutex * mutex)
}
/* try Lock the mutex */
int
SDL_TryLockMutex(SDL_mutex * mutex)
int SDL_TryLockMutex(SDL_mutex * mutex)
{
ULONG ulRC;
HMTX hMtx = (HMTX)mutex;
if (hMtx == NULLHANDLE)
return SDL_InvalidParamError("mutex");
return 0;
ulRC = DosRequestMutexSem(hMtx, SEM_IMMEDIATE_RETURN);
@ -108,14 +104,13 @@ SDL_TryLockMutex(SDL_mutex * mutex)
}
/* Unlock the mutex */
int
SDL_UnlockMutex(SDL_mutex * mutex)
int SDL_UnlockMutex(SDL_mutex * mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
ULONG ulRC;
HMTX hMtx = (HMTX)mutex;
if (hMtx == NULLHANDLE)
return SDL_InvalidParamError("mutex");
return 0;
ulRC = DosReleaseMutexSem(hMtx);
if (ulRC != NO_ERROR)

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -39,8 +39,7 @@ struct SDL_semaphore {
};
SDL_sem *
SDL_CreateSemaphore(Uint32 initial_value)
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
ULONG ulRC;
SDL_sem *pSDLSem = SDL_malloc(sizeof(SDL_sem));
@ -70,8 +69,7 @@ SDL_CreateSemaphore(Uint32 initial_value)
return pSDLSem;
}
void
SDL_DestroySemaphore(SDL_sem * sem)
void SDL_DestroySemaphore(SDL_sem * sem)
{
if (!sem) return;
@ -80,8 +78,7 @@ SDL_DestroySemaphore(SDL_sem * sem)
SDL_free(sem);
}
int
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
int SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
{
ULONG ulRC;
ULONG ulStartTime, ulCurTime;
@ -129,20 +126,17 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
return 0;
}
int
SDL_SemTryWait(SDL_sem * sem)
int SDL_SemTryWait(SDL_sem * sem)
{
return SDL_SemWaitTimeout(sem, 0);
}
int
SDL_SemWait(SDL_sem * sem)
int SDL_SemWait(SDL_sem * sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
Uint32
SDL_SemValue(SDL_sem * sem)
Uint32 SDL_SemValue(SDL_sem * sem)
{
ULONG ulRC;
@ -161,8 +155,7 @@ SDL_SemValue(SDL_sem * sem)
return ulRC;
}
int
SDL_SemPost(SDL_sem * sem)
int SDL_SemPost(SDL_sem * sem)
{
ULONG ulRC;

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -54,8 +54,7 @@ static void RunThread(void *data)
pfnEndThread();
}
int
SDL_SYS_CreateThread(SDL_Thread * thread,
int SDL_SYS_CreateThread(SDL_Thread * thread,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread)
{
@ -80,14 +79,12 @@ SDL_SYS_CreateThread(SDL_Thread * thread,
return 0;
}
void
SDL_SYS_SetupThread(const char *name)
void SDL_SYS_SetupThread(const char *name)
{
/* nothing. */
}
SDL_threadID
SDL_ThreadID(void)
SDL_threadID SDL_ThreadID(void)
{
PTIB tib;
PPIB pib;
@ -96,8 +93,7 @@ SDL_ThreadID(void)
return tib->tib_ptib2->tib2_ultid;
}
int
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
ULONG ulRC;
@ -112,8 +108,7 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
return 0;
}
void
SDL_SYS_WaitThread(SDL_Thread * thread)
void SDL_SYS_WaitThread(SDL_Thread * thread)
{
ULONG ulRC = DosWaitThread((PTID)&thread->handle, DCWW_WAIT);
@ -122,8 +117,7 @@ SDL_SYS_WaitThread(SDL_Thread * thread)
}
}
void
SDL_SYS_DetachThread(SDL_Thread * thread)
void SDL_SYS_DetachThread(SDL_Thread * thread)
{
/* nothing. */
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -0,0 +1,161 @@
/*
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_PS2
/* Semaphore functions for the PS2. */
#include <stdio.h>
#include <stdlib.h>
#include <timer_alarm.h>
#include "SDL_error.h"
#include "SDL_thread.h"
#include <kernel.h>
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)
{
SDL_sem *sem;
ee_sema_t sema;
sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
if (sem != NULL) {
/* TODO: Figure out the limit on the maximum value. */
sema.init_count = initial_value;
sema.max_count = 255;
sema.option = 0;
sem->semid = CreateSema(&sema);
if (sem->semid < 0) {
SDL_SetError("Couldn't create semaphore");
SDL_free(sem);
sem = NULL;
}
} else {
SDL_OutOfMemory();
}
return sem;
}
/* Free the semaphore */
void SDL_DestroySemaphore(SDL_sem *sem)
{
if (sem != NULL) {
if (sem->semid > 0) {
DeleteSema(sem->semid);
sem->semid = 0;
}
SDL_free(sem);
}
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
int ret;
struct timer_alarm_t alarm;
InitializeTimerAlarm(&alarm);
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
if (timeout == 0) {
if (PollSema(sem->semid) < 0) {
return SDL_MUTEX_TIMEDOUT;
}
return 0;
}
if (timeout != SDL_MUTEX_MAXWAIT) {
SetTimerAlarm(&alarm, MSec2TimerBusClock(timeout), &usercb, (void *)GetThreadId());
}
ret = WaitSema(sem->semid);
StopTimerAlarm(&alarm);
if (ret < 0) {
return SDL_MUTEX_TIMEDOUT;
}
return 0; // Wait condition satisfied.
}
int SDL_SemTryWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, 0);
}
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
/* Returns the current count of the semaphore */
Uint32 SDL_SemValue(SDL_sem *sem)
{
ee_sema_t info;
if (sem == NULL) {
SDL_InvalidParamError("sem");
return 0;
}
if (ReferSemaStatus(sem->semid, &info) >= 0) {
return info.count;
}
return 0;
}
int SDL_SemPost(SDL_sem *sem)
{
int res;
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
res = SignalSema(sem->semid);
if (res < 0) {
return SDL_SetError("sceKernelSignalSema() failed");
}
return 0;
}
#endif /* SDL_THREAD_PS2 */
/* vim: ts=4 sw=4
*/

View file

@ -0,0 +1,140 @@
/*
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_PS2
/* PS2 thread management routines for SDL */
#include <stdio.h>
#include <stdlib.h>
#include "SDL_error.h"
#include "SDL_thread.h"
#include "../SDL_systhread.h"
#include "../SDL_thread_c.h"
#include <kernel.h>
static void FinishThread(SDL_Thread *thread)
{
ee_thread_status_t info;
int res;
res = ReferThreadStatus(thread->handle, &info);
TerminateThread(thread->handle);
DeleteThread(thread->handle);
DeleteSema((int)thread->endfunc);
if (res > 0) {
SDL_free(info.stack);
}
}
static int childThread(void *arg)
{
SDL_Thread *thread = (SDL_Thread *)arg;
int res = thread->userfunc(thread->userdata);
SignalSema((int)thread->endfunc);
return res;
}
int SDL_SYS_CreateThread(SDL_Thread *thread)
{
ee_thread_status_t status;
ee_thread_t eethread;
ee_sema_t sema;
size_t stack_size;
int priority = 32;
/* Set priority of new thread to the same as the current thread */
// status.size = sizeof(ee_thread_t);
if (ReferThreadStatus(GetThreadId(), &status) == 0) {
priority = status.current_priority;
}
stack_size = thread->stacksize ? ((int)thread->stacksize) : 0x1800;
/* Create EE Thread */
eethread.attr = 0;
eethread.option = 0;
eethread.func = &childThread;
eethread.stack = SDL_malloc(stack_size);
eethread.stack_size = stack_size;
eethread.gp_reg = &_gp;
eethread.initial_priority = priority;
thread->handle = CreateThread(&eethread);
if (thread->handle < 0) {
return SDL_SetError("CreateThread() failed");
}
// Prepare el semaphore for the ending function
sema.init_count = 0;
sema.max_count = 1;
sema.option = 0;
thread->endfunc = (void *)CreateSema(&sema);
return StartThread(thread->handle, thread);
}
void SDL_SYS_SetupThread(const char *name)
{
/* Do nothing. */
}
SDL_threadID SDL_ThreadID(void)
{
return (SDL_threadID)GetThreadId();
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
WaitSema((int)thread->endfunc);
ReleaseWaitThread(thread->handle);
FinishThread(thread);
}
void SDL_SYS_DetachThread(SDL_Thread *thread)
{
/* Do nothing. */
}
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
int value;
if (priority == SDL_THREAD_PRIORITY_LOW) {
value = 111;
} else if (priority == SDL_THREAD_PRIORITY_HIGH) {
value = 32;
} else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
value = 16;
} else {
value = 50;
}
return ChangeThreadPriority(GetThreadId(), value);
}
#endif /* SDL_THREAD_PS2 */
/* vim: ts=4 sw=4
*/

View file

@ -0,0 +1,24 @@
/*
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 <stdint.h>
typedef int32_t SYS_ThreadHandle;

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -40,12 +40,11 @@ struct SDL_cond
};
/* Create a condition variable */
SDL_cond *
SDL_CreateCond(void)
SDL_cond *SDL_CreateCond(void)
{
SDL_cond *cond;
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
cond = (SDL_cond *)SDL_malloc(sizeof(SDL_cond));
if (cond) {
cond->lock = SDL_CreateMutex();
cond->wait_sem = SDL_CreateSemaphore(0);
@ -58,12 +57,11 @@ SDL_CreateCond(void)
} else {
SDL_OutOfMemory();
}
return (cond);
return cond;
}
/* Destroy a condition variable */
void
SDL_DestroyCond(SDL_cond * cond)
void SDL_DestroyCond(SDL_cond *cond)
{
if (cond) {
if (cond->wait_sem) {
@ -80,10 +78,9 @@ SDL_DestroyCond(SDL_cond * cond)
}
/* Restart one of the threads that are waiting on the condition variable */
int
SDL_CondSignal(SDL_cond * cond)
int SDL_CondSignal(SDL_cond *cond)
{
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -104,10 +101,9 @@ SDL_CondSignal(SDL_cond * cond)
}
/* Restart all threads that are waiting on the condition variable */
int
SDL_CondBroadcast(SDL_cond * cond)
int SDL_CondBroadcast(SDL_cond *cond)
{
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -158,12 +154,11 @@ Thread B:
SDL_CondSignal(cond);
SDL_UnlockMutex(lock);
*/
int
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
{
int retval;
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -213,8 +208,7 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
}
/* Wait on the condition variable forever */
int
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -38,14 +38,13 @@ struct SDL_mutex
};
/* Create a mutex */
SDL_mutex *
SDL_CreateMutex(void)
SDL_mutex *SDL_CreateMutex(void)
{
SDL_mutex *mutex = NULL;
SceInt32 res = 0;
/* Allocate mutex memory */
mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
mutex = (SDL_mutex *)SDL_malloc(sizeof(*mutex));
if (mutex) {
res = sceKernelCreateLwMutex(
@ -53,11 +52,10 @@ SDL_CreateMutex(void)
"SDL mutex",
SCE_KERNEL_MUTEX_ATTR_RECURSIVE,
0,
NULL
);
NULL);
if (res < 0) {
SDL_SetError("Error trying to create mutex: %x", res);
SDL_SetError("Error trying to create mutex: %lx", res);
}
} else {
SDL_OutOfMemory();
@ -66,8 +64,7 @@ SDL_CreateMutex(void)
}
/* Free the mutex */
void
SDL_DestroyMutex(SDL_mutex * mutex)
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex) {
sceKernelDeleteLwMutex(&mutex->lock);
@ -75,60 +72,58 @@ SDL_DestroyMutex(SDL_mutex * mutex)
}
}
/* Try to lock the mutex */
int
SDL_TryLockMutex(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
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
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 */
}
/* Try to lock the mutex */
int SDL_TryLockMutex(SDL_mutex *mutex)
{
#if SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
return 0;
}
res = sceKernelTryLockLwMutex(&mutex->lock, 1);
switch (res) {
case SCE_KERNEL_ERROR_OK:
return 0;
break;
case SCE_KERNEL_ERROR_WAIT_TIMEOUT:
return SDL_MUTEX_TIMEDOUT;
break;
default:
return SDL_SetError("Error trying to lock mutex: %x", res);
break;
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 */
}
/* Lock the mutex */
int
SDL_mutexP(SDL_mutex * mutex)
{
#if SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
}
res = sceKernelLockLwMutex(&mutex->lock, 1, NULL);
if (res != SCE_KERNEL_ERROR_OK) {
return SDL_SetError("Error trying to lock mutex: %x", res);
}
return 0;
#endif /* SDL_THREADS_DISABLED */
}
/* Unlock the mutex */
int
SDL_mutexV(SDL_mutex * mutex)
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
#if SDL_THREADS_DISABLED
return 0;
@ -136,17 +131,18 @@ SDL_mutexV(SDL_mutex * mutex)
SceInt32 res = 0;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
res = sceKernelUnlockLwMutex(&mutex->lock, 1);
if (res != 0) {
return SDL_SetError("Error trying to unlock mutex: %x", res);
return SDL_SetError("Error trying to unlock mutex: %lx", res);
}
return 0;
#endif /* SDL_THREADS_DISABLED */
}
#endif /* SDL_THREAD_PSP */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -33,17 +33,17 @@
#include <pspthreadman.h>
#include <pspkerror.h>
struct SDL_semaphore {
SceUID semid;
struct SDL_semaphore
{
SceUID semid;
};
/* Create a semaphore */
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem;
sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
if (sem != NULL) {
/* TODO: Figure out the limit on the maximum value. */
sem->semid = sceKernelCreateSema("SDL sema", 0, initial_value, 255, NULL);
@ -82,8 +82,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
int res;
if (sem == NULL) {
SDL_InvalidParamError("sem");
return 0;
return SDL_InvalidParamError("sem");
}
if (timeout == 0) {
@ -97,18 +96,18 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
if (timeout == SDL_MUTEX_MAXWAIT) {
pTimeout = NULL;
} else {
timeout *= 1000; /* Convert to microseconds. */
timeout *= 1000; /* Convert to microseconds. */
pTimeout = &timeout;
}
res = sceKernelWaitSema(sem->semid, 1, pTimeout);
switch (res) {
case SCE_KERNEL_ERROR_OK:
return 0;
case SCE_KERNEL_ERROR_WAIT_TIMEOUT:
return SDL_MUTEX_TIMEDOUT;
default:
return SDL_SetError("sceKernelWaitSema() failed");
res = sceKernelWaitSema(sem->semid, 1, (SceUInt *)pTimeout);
switch (res) {
case SCE_KERNEL_ERROR_OK:
return 0;
case SCE_KERNEL_ERROR_WAIT_TIMEOUT:
return SDL_MUTEX_TIMEDOUT;
default:
return SDL_SetError("sceKernelWaitSema() failed");
}
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -34,10 +34,9 @@
#include <pspkerneltypes.h>
#include <pspthreadman.h>
static int ThreadEntry(SceSize args, void *argp)
{
SDL_RunThread(*(SDL_Thread **) argp);
SDL_RunThread(*(SDL_Thread **)argp);
return 0;
}
@ -53,8 +52,8 @@ int SDL_SYS_CreateThread(SDL_Thread *thread)
}
thread->handle = sceKernelCreateThread(thread->name, ThreadEntry,
priority, thread->stacksize ? ((int) thread->stacksize) : 0x8000,
PSP_THREAD_ATTR_VFPU, NULL);
priority, thread->stacksize ? ((int)thread->stacksize) : 0x8000,
PSP_THREAD_ATTR_VFPU, NULL);
if (thread->handle < 0) {
return SDL_SetError("sceKernelCreateThread() failed");
}
@ -70,7 +69,7 @@ void SDL_SYS_SetupThread(const char *name)
SDL_threadID SDL_ThreadID(void)
{
return (SDL_threadID) sceKernelGetThreadId();
return (SDL_threadID)sceKernelGetThreadId();
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
@ -104,8 +103,7 @@ int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
value = 50;
}
return sceKernelChangeThreadPriority(sceKernelGetThreadId(),value);
return sceKernelChangeThreadPriority(sceKernelGetThreadId(), value);
}
#endif /* SDL_THREAD_PSP */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -35,12 +35,11 @@ struct SDL_cond
};
/* Create a condition variable */
SDL_cond *
SDL_CreateCond(void)
SDL_cond *SDL_CreateCond(void)
{
SDL_cond *cond;
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
cond = (SDL_cond *)SDL_malloc(sizeof(SDL_cond));
if (cond) {
if (pthread_cond_init(&cond->cond, NULL) != 0) {
SDL_SetError("pthread_cond_init() failed");
@ -48,12 +47,11 @@ SDL_CreateCond(void)
cond = NULL;
}
}
return (cond);
return cond;
}
/* Destroy a condition variable */
void
SDL_DestroyCond(SDL_cond * cond)
void SDL_DestroyCond(SDL_cond *cond)
{
if (cond) {
pthread_cond_destroy(&cond->cond);
@ -62,12 +60,11 @@ SDL_DestroyCond(SDL_cond * cond)
}
/* Restart one of the threads that are waiting on the condition variable */
int
SDL_CondSignal(SDL_cond * cond)
int SDL_CondSignal(SDL_cond *cond)
{
int retval;
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -79,12 +76,11 @@ SDL_CondSignal(SDL_cond * cond)
}
/* Restart all threads that are waiting on the condition variable */
int
SDL_CondBroadcast(SDL_cond * cond)
int SDL_CondBroadcast(SDL_cond *cond)
{
int retval;
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -95,8 +91,7 @@ SDL_CondBroadcast(SDL_cond * cond)
return retval;
}
int
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
{
int retval;
#ifndef HAVE_CLOCK_GETTIME
@ -104,7 +99,7 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
#endif
struct timespec abstime;
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -117,14 +112,14 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
gettimeofday(&delta, NULL);
abstime.tv_sec = delta.tv_sec + (ms / 1000);
abstime.tv_nsec = (delta.tv_usec + (ms % 1000) * 1000) * 1000;
abstime.tv_nsec = (long)(delta.tv_usec + (ms % 1000) * 1000) * 1000;
#endif
if (abstime.tv_nsec > 1000000000) {
abstime.tv_sec += 1;
abstime.tv_nsec -= 1000000000;
}
tryagain:
tryagain:
retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
switch (retval) {
case EINTR:
@ -144,10 +139,9 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
/* Wait on the condition variable, unlocking the provided mutex.
The mutex must be locked before entering this function!
*/
int
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
if (!cond) {
if (cond == NULL) {
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-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -39,14 +39,13 @@ struct SDL_mutex
#endif
};
SDL_mutex *
SDL_CreateMutex(void)
SDL_mutex *SDL_CreateMutex(void)
{
SDL_mutex *mutex;
pthread_mutexattr_t attr;
/* Allocate the structure */
mutex = (SDL_mutex *) SDL_calloc(1, sizeof(*mutex));
mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex));
if (mutex) {
pthread_mutexattr_init(&attr);
#if SDL_THREAD_PTHREAD_RECURSIVE_MUTEX
@ -64,11 +63,10 @@ SDL_CreateMutex(void)
} else {
SDL_OutOfMemory();
}
return (mutex);
return mutex;
}
void
SDL_DestroyMutex(SDL_mutex * mutex)
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex) {
pthread_mutex_destroy(&mutex->id);
@ -77,15 +75,14 @@ SDL_DestroyMutex(SDL_mutex * mutex)
}
/* Lock the mutex */
int
SDL_LockMutex(SDL_mutex * mutex)
int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
#if FAKE_RECURSIVE_MUTEX
pthread_t this_thread;
#endif
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
#if FAKE_RECURSIVE_MUTEX
@ -112,8 +109,7 @@ SDL_LockMutex(SDL_mutex * mutex)
return 0;
}
int
SDL_TryLockMutex(SDL_mutex * mutex)
int SDL_TryLockMutex(SDL_mutex *mutex)
{
int retval;
int result;
@ -122,7 +118,7 @@ SDL_TryLockMutex(SDL_mutex * mutex)
#endif
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
retval = 0;
@ -158,11 +154,10 @@ SDL_TryLockMutex(SDL_mutex * mutex)
return retval;
}
int
SDL_UnlockMutex(SDL_mutex * mutex)
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
#if FAKE_RECURSIVE_MUTEX

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -42,11 +42,10 @@ struct SDL_semaphore
};
/* Create a semaphore, initialized with value */
SDL_sem *
SDL_CreateSemaphore(Uint32 initial_value)
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem));
if (sem) {
SDL_sem *sem = (SDL_sem *)SDL_malloc(sizeof(SDL_sem));
if (sem != NULL) {
if (sem_init(&sem->sem, 0, initial_value) < 0) {
SDL_SetError("sem_init() failed");
SDL_free(sem);
@ -58,21 +57,19 @@ SDL_CreateSemaphore(Uint32 initial_value)
return sem;
}
void
SDL_DestroySemaphore(SDL_sem * sem)
void SDL_DestroySemaphore(SDL_sem *sem)
{
if (sem) {
if (sem != NULL) {
sem_destroy(&sem->sem);
SDL_free(sem);
}
}
int
SDL_SemTryWait(SDL_sem * sem)
int SDL_SemTryWait(SDL_sem *sem)
{
int retval;
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
retval = SDL_MUTEX_TIMEDOUT;
@ -82,12 +79,11 @@ SDL_SemTryWait(SDL_sem * sem)
return retval;
}
int
SDL_SemWait(SDL_sem * sem)
int SDL_SemWait(SDL_sem *sem)
{
int retval;
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
@ -101,10 +97,9 @@ SDL_SemWait(SDL_sem * sem)
return retval;
}
int
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
int retval;
int retval = 0;
#ifdef HAVE_SEM_TIMEDWAIT
#ifndef HAVE_CLOCK_GETTIME
struct timeval now;
@ -114,7 +109,7 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
Uint32 end;
#endif
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
@ -128,9 +123,9 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
#ifdef HAVE_SEM_TIMEDWAIT
/* Setup the timeout. sem_timedwait doesn't wait for
* a lapse of time, but until we reach a certain time.
* This time is now plus the timeout.
*/
* a lapse of time, but until we reach a certain time.
* This time is now plus the timeout.
*/
#ifdef HAVE_CLOCK_GETTIME
clock_gettime(CLOCK_REALTIME, &ts_timeout);
@ -176,25 +171,27 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
return retval;
}
Uint32
SDL_SemValue(SDL_sem * sem)
Uint32 SDL_SemValue(SDL_sem *sem)
{
int ret = 0;
if (sem) {
sem_getvalue(&sem->sem, &ret);
if (ret < 0) {
ret = 0;
}
if (sem == NULL) {
SDL_InvalidParamError("sem");
return 0;
}
return (Uint32) ret;
sem_getvalue(&sem->sem, &ret);
if (ret < 0) {
ret = 0;
}
return (Uint32)ret;
}
int
SDL_SemPost(SDL_sem * sem)
int SDL_SemPost(SDL_sem *sem)
{
int retval;
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -68,25 +68,23 @@ static const int sig_list[] = {
};
#endif
static void *
RunThread(void *data)
static void *RunThread(void *data)
{
#ifdef __ANDROID__
Android_JNI_SetupThread();
#endif
SDL_RunThread((SDL_Thread *) data);
SDL_RunThread((SDL_Thread *)data);
return NULL;
}
#if (defined(__MACOSX__) || defined(__IPHONEOS__)) && defined(HAVE_DLOPEN)
static SDL_bool checked_setname = SDL_FALSE;
static int (*ppthread_setname_np)(const char*) = NULL;
static int (*ppthread_setname_np)(const char *) = NULL;
#elif defined(__LINUX__) && defined(HAVE_DLOPEN)
static SDL_bool checked_setname = SDL_FALSE;
static int (*ppthread_setname_np)(pthread_t, const char*) = NULL;
static int (*ppthread_setname_np)(pthread_t, const char *) = NULL;
#endif
int
SDL_SYS_CreateThread(SDL_Thread * thread)
int SDL_SYS_CreateThread(SDL_Thread *thread)
{
pthread_attr_t type;
@ -101,14 +99,14 @@ SDL_SYS_CreateThread(SDL_Thread * thread)
#endif
checked_setname = SDL_TRUE;
}
#endif
#endif
/* Set the thread attributes */
if (pthread_attr_init(&type) != 0) {
return SDL_SetError("Couldn't initialize pthread attributes");
}
pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
/* Set caller-requested stack size. Otherwise: use the system default. */
if (thread->stacksize) {
pthread_attr_setstacksize(&type, thread->stacksize);
@ -122,8 +120,7 @@ SDL_SYS_CreateThread(SDL_Thread * thread)
return 0;
}
void
SDL_SYS_SetupThread(const char *name)
void SDL_SYS_SetupThread(const char *name)
{
#if !defined(__NACL__)
int i;
@ -136,32 +133,32 @@ SDL_SYS_SetupThread(const char *name)
if (ppthread_setname_np != NULL) {
#if defined(__MACOSX__) || defined(__IPHONEOS__)
ppthread_setname_np(name);
#elif defined(__LINUX__)
#elif defined(__LINUX__)
if (ppthread_setname_np(pthread_self(), name) == ERANGE) {
char namebuf[16]; /* Limited to 16 char */
SDL_strlcpy(namebuf, name, sizeof (namebuf));
SDL_strlcpy(namebuf, name, sizeof(namebuf));
ppthread_setname_np(pthread_self(), namebuf);
}
#endif
#endif
}
#elif HAVE_PTHREAD_SETNAME_NP
#if defined(__NETBSD__)
pthread_setname_np(pthread_self(), "%s", name);
#else
if (pthread_setname_np(pthread_self(), name) == ERANGE) {
char namebuf[16]; /* Limited to 16 char */
SDL_strlcpy(namebuf, name, sizeof (namebuf));
pthread_setname_np(pthread_self(), namebuf);
}
#endif
#elif 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. */
char namebuf[B_OS_NAME_LENGTH];
SDL_strlcpy(namebuf, name, sizeof (namebuf));
rename_thread(find_thread(NULL), namebuf);
#endif
#elif HAVE_PTHREAD_SETNAME_NP
#if defined(__NETBSD__)
pthread_setname_np(pthread_self(), "%s", name);
#else
if (pthread_setname_np(pthread_self(), name) == ERANGE) {
char namebuf[16]; /* Limited to 16 char */
SDL_strlcpy(namebuf, name, sizeof(namebuf));
pthread_setname_np(pthread_self(), namebuf);
}
#endif
#elif 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. */
char namebuf[B_OS_NAME_LENGTH];
SDL_strlcpy(namebuf, name, sizeof(namebuf));
rename_thread(find_thread(NULL), namebuf);
#endif
}
/* NativeClient does not yet support signals.*/
@ -184,14 +181,12 @@ SDL_SYS_SetupThread(const char *name)
#endif
}
SDL_threadID
SDL_ThreadID(void)
SDL_threadID SDL_ThreadID(void)
{
return ((SDL_threadID) pthread_self());
return (SDL_threadID)pthread_self();
}
int
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
#if __NACL__ || __RISCOS__ || __OS2__
/* FIXME: Setting thread priority does not seem to be supported in NACL */
@ -290,14 +285,12 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
#endif /* #if __NACL__ || __RISCOS__ */
}
void
SDL_SYS_WaitThread(SDL_Thread * thread)
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
pthread_join(thread->handle, 0);
}
void
SDL_SYS_DetachThread(SDL_Thread * thread)
void SDL_SYS_DetachThread(SDL_Thread *thread)
{
pthread_detach(thread->handle);
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -25,14 +25,12 @@
#include <pthread.h>
#define INVALID_PTHREAD_KEY ((pthread_key_t)-1)
static pthread_key_t thread_local_storage = INVALID_PTHREAD_KEY;
static SDL_bool generic_local_storage = SDL_FALSE;
SDL_TLSData *
SDL_SYS_GetTLSData(void)
SDL_TLSData *SDL_SYS_GetTLSData(void)
{
if (thread_local_storage == INVALID_PTHREAD_KEY && !generic_local_storage) {
static SDL_SpinLock lock;
@ -55,8 +53,7 @@ SDL_SYS_GetTLSData(void)
return (SDL_TLSData *)pthread_getspecific(thread_local_storage);
}
int
SDL_SYS_SetTLSData(SDL_TLSData *data)
int SDL_SYS_SetTLSData(SDL_TLSData *data)
{
if (generic_local_storage) {
return SDL_Generic_SetTLSData(data);

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -37,15 +37,14 @@ struct SDL_cond
};
/* Create a condition variable */
extern "C"
SDL_cond *
extern "C" SDL_cond *
SDL_CreateCond(void)
{
/* Allocate and initialize the condition variable */
try {
SDL_cond * cond = new SDL_cond;
SDL_cond *cond = new SDL_cond;
return cond;
} catch (std::system_error & ex) {
} catch (std::system_error &ex) {
SDL_SetError("unable to create a C++ condition variable: code=%d; %s", ex.code(), ex.what());
return NULL;
} catch (std::bad_alloc &) {
@ -55,21 +54,19 @@ SDL_CreateCond(void)
}
/* Destroy a condition variable */
extern "C"
void
SDL_DestroyCond(SDL_cond * cond)
extern "C" void
SDL_DestroyCond(SDL_cond *cond)
{
if (cond) {
if (cond != NULL) {
delete cond;
}
}
/* Restart one of the threads that are waiting on the condition variable */
extern "C"
int
SDL_CondSignal(SDL_cond * cond)
extern "C" int
SDL_CondSignal(SDL_cond *cond)
{
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -78,11 +75,10 @@ SDL_CondSignal(SDL_cond * cond)
}
/* Restart all threads that are waiting on the condition variable */
extern "C"
int
SDL_CondBroadcast(SDL_cond * cond)
extern "C" int
SDL_CondBroadcast(SDL_cond *cond)
{
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -111,15 +107,14 @@ Thread B:
SDL_CondSignal(cond);
SDL_UnlockMutex(lock);
*/
extern "C"
int
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
extern "C" int
SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
{
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
if (!mutex) {
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
}
@ -127,15 +122,13 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
std::unique_lock<std::recursive_mutex> cpp_lock(mutex->cpp_mutex, std::adopt_lock_t());
if (ms == SDL_MUTEX_MAXWAIT) {
cond->cpp_cond.wait(
cpp_lock
);
cpp_lock);
cpp_lock.release();
return 0;
} else {
auto wait_result = cond->cpp_cond.wait_for(
cpp_lock,
std::chrono::duration<Uint32, std::milli>(ms)
);
std::chrono::duration<Uint32, std::milli>(ms));
cpp_lock.release();
if (wait_result == std::cv_status::timeout) {
return SDL_MUTEX_TIMEDOUT;
@ -143,15 +136,14 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
return 0;
}
}
} catch (std::system_error & ex) {
} catch (std::system_error &ex) {
return SDL_SetError("unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what());
}
}
/* Wait on the condition variable forever */
extern "C"
int
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
extern "C" int
SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -30,17 +30,15 @@ extern "C" {
#include "SDL_sysmutex_c.h"
#include <Windows.h>
/* Create a mutex */
extern "C"
SDL_mutex *
extern "C" SDL_mutex *
SDL_CreateMutex(void)
{
/* Allocate and initialize the mutex */
try {
SDL_mutex * mutex = new SDL_mutex;
SDL_mutex *mutex = new SDL_mutex;
return mutex;
} catch (std::system_error & ex) {
} 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 &) {
@ -50,39 +48,37 @@ SDL_CreateMutex(void)
}
/* Free the mutex */
extern "C"
void
SDL_DestroyMutex(SDL_mutex * mutex)
extern "C" void
SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex) {
if (mutex != NULL) {
delete mutex;
}
}
/* Lock the semaphore */
extern "C"
int
SDL_mutexP(SDL_mutex * mutex)
/* Lock the mutex */
extern "C" int
SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
try {
mutex->cpp_mutex.lock();
return 0;
} catch (std::system_error & ex) {
} catch (std::system_error &ex) {
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)
int SDL_TryLockMutex(SDL_mutex *mutex)
{
int retval = 0;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
if (mutex->cpp_mutex.try_lock() == false) {
@ -92,12 +88,11 @@ SDL_TryLockMutex(SDL_mutex * mutex)
}
/* Unlock the mutex */
extern "C"
int
SDL_mutexV(SDL_mutex * mutex)
extern "C" int
SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
mutex->cpp_mutex.unlock();

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -36,30 +36,27 @@ extern "C" {
#include <Windows.h>
#endif
static void
RunThread(void *args)
static void RunThread(void *args)
{
SDL_RunThread((SDL_Thread *) args);
SDL_RunThread((SDL_Thread *)args);
}
extern "C"
int
SDL_SYS_CreateThread(SDL_Thread * thread)
extern "C" int
SDL_SYS_CreateThread(SDL_Thread *thread)
{
try {
// !!! FIXME: no way to set a thread stack size here.
std::thread cpp_thread(RunThread, thread);
thread->handle = (void *) new std::thread(std::move(cpp_thread));
thread->handle = (void *)new std::thread(std::move(cpp_thread));
return 0;
} catch (std::system_error & ex) {
} catch (std::system_error &ex) {
return SDL_SetError("unable to start a C++ thread: code=%d; %s", ex.code(), ex.what());
} catch (std::bad_alloc &) {
return SDL_OutOfMemory();
}
}
extern "C"
void
extern "C" void
SDL_SYS_SetupThread(const char *name)
{
// Make sure a thread ID gets assigned ASAP, for debugging purposes:
@ -67,8 +64,7 @@ SDL_SYS_SetupThread(const char *name)
return;
}
extern "C"
SDL_threadID
extern "C" SDL_threadID
SDL_ThreadID(void)
{
#ifdef __WINRT__
@ -89,8 +85,7 @@ SDL_ThreadID(void)
#endif
}
extern "C"
int
extern "C" int
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
#ifdef __WINRT__
@ -98,16 +93,13 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
if (priority == SDL_THREAD_PRIORITY_LOW) {
value = THREAD_PRIORITY_LOWEST;
}
else if (priority == SDL_THREAD_PRIORITY_HIGH) {
} else if (priority == SDL_THREAD_PRIORITY_HIGH) {
value = THREAD_PRIORITY_HIGHEST;
}
else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
} else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
// FIXME: WinRT does not support TIME_CRITICAL! -flibit
SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "TIME_CRITICAL unsupported, falling back to HIGHEST");
value = THREAD_PRIORITY_HIGHEST;
}
else {
} else {
value = THREAD_PRIORITY_NORMAL;
}
if (!SetThreadPriority(GetCurrentThread(), value)) {
@ -119,16 +111,15 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
#endif
}
extern "C"
void
SDL_SYS_WaitThread(SDL_Thread * thread)
extern "C" void
SDL_SYS_WaitThread(SDL_Thread *thread)
{
if ( ! thread) {
if (!thread) {
return;
}
try {
std::thread * cpp_thread = (std::thread *) thread->handle;
std::thread *cpp_thread = (std::thread *)thread->handle;
if (cpp_thread->joinable()) {
cpp_thread->join();
}
@ -139,16 +130,15 @@ SDL_SYS_WaitThread(SDL_Thread * thread)
}
}
extern "C"
void
SDL_SYS_DetachThread(SDL_Thread * thread)
extern "C" void
SDL_SYS_DetachThread(SDL_Thread *thread)
{
if ( ! thread) {
if (!thread) {
return;
}
try {
std::thread * cpp_thread = (std::thread *) thread->handle;
std::thread *cpp_thread = (std::thread *)thread->handle;
if (cpp_thread->joinable()) {
cpp_thread->detach();
}
@ -159,15 +149,13 @@ SDL_SYS_DetachThread(SDL_Thread * thread)
}
}
extern "C"
SDL_TLSData *
extern "C" SDL_TLSData *
SDL_SYS_GetTLSData(void)
{
return SDL_Generic_GetTLSData();
}
extern "C"
int
extern "C" int
SDL_SYS_SetTLSData(SDL_TLSData *data)
{
return SDL_Generic_SetTLSData(data);

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -21,6 +21,6 @@
#include "SDL_config.h"
/* For a thread handle, use a void pointer to a std::thread */
typedef void * SYS_ThreadHandle;
typedef void *SYS_ThreadHandle;
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -40,13 +40,12 @@ struct SDL_cond
};
/* Create a condition variable */
SDL_cond *
SDL_CreateCond(void)
SDL_cond *SDL_CreateCond(void)
{
SDL_cond *cond;
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
if (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);
@ -58,14 +57,13 @@ SDL_CreateCond(void)
} else {
SDL_OutOfMemory();
}
return (cond);
return cond;
}
/* Destroy a condition variable */
void
SDL_DestroyCond(SDL_cond * cond)
void SDL_DestroyCond(SDL_cond *cond)
{
if (cond) {
if (cond != NULL) {
if (cond->wait_sem) {
SDL_DestroySemaphore(cond->wait_sem);
}
@ -80,10 +78,9 @@ SDL_DestroyCond(SDL_cond * cond)
}
/* Restart one of the threads that are waiting on the condition variable */
int
SDL_CondSignal(SDL_cond * cond)
int SDL_CondSignal(SDL_cond *cond)
{
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -104,10 +101,9 @@ SDL_CondSignal(SDL_cond * cond)
}
/* Restart all threads that are waiting on the condition variable */
int
SDL_CondBroadcast(SDL_cond * cond)
int SDL_CondBroadcast(SDL_cond *cond)
{
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -158,12 +154,11 @@ Thread B:
SDL_CondSignal(cond);
SDL_UnlockMutex(lock);
*/
int
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
{
int retval;
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -213,8 +208,7 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
}
/* Wait on the condition variable forever */
int
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -34,23 +34,21 @@ struct SDL_mutex
};
/* Create a mutex */
SDL_mutex *
SDL_CreateMutex(void)
SDL_mutex *SDL_CreateMutex(void)
{
SDL_mutex *mutex = NULL;
SceInt32 res = 0;
/* Allocate mutex memory */
mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
if (mutex) {
mutex = (SDL_mutex *)SDL_malloc(sizeof(*mutex));
if (mutex != NULL) {
res = sceKernelCreateLwMutex(
&mutex->lock,
"SDL mutex",
SCE_KERNEL_MUTEX_ATTR_RECURSIVE,
0,
NULL
);
NULL);
if (res < 0) {
SDL_SetError("Error trying to create mutex: %x", res);
@ -62,55 +60,24 @@ SDL_CreateMutex(void)
}
/* Free the mutex */
void
SDL_DestroyMutex(SDL_mutex * mutex)
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex) {
if (mutex != NULL) {
sceKernelDeleteLwMutex(&mutex->lock);
SDL_free(mutex);
}
}
/* Try to lock the mutex */
int
SDL_TryLockMutex(SDL_mutex * mutex)
{
#if SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
}
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;
}
return -1;
#endif /* SDL_THREADS_DISABLED */
}
/* Lock the mutex */
int
SDL_mutexP(SDL_mutex * mutex)
int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
#if SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
res = sceKernelLockLwMutex(&mutex->lock, 1, NULL);
@ -122,9 +89,8 @@ SDL_mutexP(SDL_mutex * mutex)
#endif /* SDL_THREADS_DISABLED */
}
/* Unlock the mutex */
int
SDL_mutexV(SDL_mutex * mutex)
/* Try to lock the mutex */
int SDL_TryLockMutex(SDL_mutex *mutex)
{
#if SDL_THREADS_DISABLED
return 0;
@ -132,7 +98,36 @@ SDL_mutexV(SDL_mutex * mutex)
SceInt32 res = 0;
if (mutex == NULL) {
return SDL_InvalidParamError("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;
}
return -1;
#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 */
{
#if SDL_THREADS_DISABLED
return 0;
#else
SceInt32 res = 0;
if (mutex == NULL) {
return 0;
}
res = sceKernelUnlockLwMutex(&mutex->lock, 1);

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -34,17 +34,17 @@
#include <psp2/kernel/error.h>
#include <psp2/kernel/threadmgr.h>
struct SDL_semaphore {
SceUID semid;
struct SDL_semaphore
{
SceUID semid;
};
/* Create a semaphore */
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem;
sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
if (sem != NULL) {
/* TODO: Figure out the limit on the maximum value. */
sem->semid = sceKernelCreateSema("SDL sema", 0, initial_value, 255, NULL);
@ -80,11 +80,10 @@ void SDL_DestroySemaphore(SDL_sem *sem)
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
Uint32 *pTimeout;
unsigned int res;
int res;
if (sem == NULL) {
SDL_InvalidParamError("sem");
return 0;
return SDL_InvalidParamError("sem");
}
if (timeout == 0) {
@ -98,18 +97,18 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
if (timeout == SDL_MUTEX_MAXWAIT) {
pTimeout = NULL;
} else {
timeout *= 1000; /* Convert to microseconds. */
timeout *= 1000; /* Convert to microseconds. */
pTimeout = &timeout;
}
res = sceKernelWaitSema(sem->semid, 1, pTimeout);
switch (res) {
case SCE_KERNEL_OK:
return 0;
case SCE_KERNEL_ERROR_WAIT_TIMEOUT:
return SDL_MUTEX_TIMEDOUT;
default:
return SDL_SetError("WaitForSingleObject() failed");
switch (res) {
case SCE_KERNEL_OK:
return 0;
case SCE_KERNEL_ERROR_WAIT_TIMEOUT:
return SDL_MUTEX_TIMEDOUT;
default:
return SDL_SetError("WaitForSingleObject() failed");
}
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -34,19 +34,19 @@
#include <psp2/types.h>
#include <psp2/kernel/threadmgr.h>
#define VITA_THREAD_STACK_SIZE_MIN 0x1000 // 4KiB
#define VITA_THREAD_STACK_SIZE_MAX 0x2000000 // 32MiB
#define VITA_THREAD_STACK_SIZE_DEFAULT 0x10000 // 64KiB
#define VITA_THREAD_NAME_MAX 32
#define VITA_THREAD_STACK_SIZE_MIN 0x1000 // 4KiB
#define VITA_THREAD_STACK_SIZE_MAX 0x2000000 // 32MiB
#define VITA_THREAD_STACK_SIZE_DEFAULT 0x10000 // 64KiB
#define VITA_THREAD_NAME_MAX 32
#define VITA_THREAD_PRIORITY_LOW 191
#define VITA_THREAD_PRIORITY_NORMAL 160
#define VITA_THREAD_PRIORITY_HIGH 112
#define VITA_THREAD_PRIORITY_LOW 191
#define VITA_THREAD_PRIORITY_NORMAL 160
#define VITA_THREAD_PRIORITY_HIGH 112
#define VITA_THREAD_PRIORITY_TIME_CRITICAL 64
static int ThreadEntry(SceSize args, void *argp)
{
SDL_RunThread(*(SDL_Thread **) argp);
SDL_RunThread(*(SDL_Thread **)argp);
return 0;
}
@ -74,11 +74,11 @@ int SDL_SYS_CreateThread(SDL_Thread *thread)
thread->handle = sceKernelCreateThread(
thread_name, // name
ThreadEntry, // function to run
0, // priority. 0 means priority of calling thread
stack_size, // stack size
0, // attibutes. always 0
0, // cpu affinity mask. 0 = all CPUs
NULL // opt. always NULL
0, // priority. 0 means priority of calling thread
stack_size, // stack size
0, // attibutes. always 0
0, // cpu affinity mask. 0 = all CPUs
NULL // opt. always NULL
);
if (thread->handle < 0) {
@ -96,7 +96,7 @@ void SDL_SYS_SetupThread(const char *name)
SDL_threadID SDL_ThreadID(void)
{
return (SDL_threadID) sceKernelGetThreadId();
return (SDL_threadID)sceKernelGetThreadId();
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
@ -114,23 +114,22 @@ int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
int value = VITA_THREAD_PRIORITY_NORMAL;
switch(priority) {
case SDL_THREAD_PRIORITY_LOW:
value = VITA_THREAD_PRIORITY_LOW;
break;
case SDL_THREAD_PRIORITY_NORMAL:
value = VITA_THREAD_PRIORITY_NORMAL;
break;
case SDL_THREAD_PRIORITY_HIGH:
value = VITA_THREAD_PRIORITY_HIGH;
break;
case SDL_THREAD_PRIORITY_TIME_CRITICAL:
value = VITA_THREAD_PRIORITY_TIME_CRITICAL;
break;
switch (priority) {
case SDL_THREAD_PRIORITY_LOW:
value = VITA_THREAD_PRIORITY_LOW;
break;
case SDL_THREAD_PRIORITY_NORMAL:
value = VITA_THREAD_PRIORITY_NORMAL;
break;
case SDL_THREAD_PRIORITY_HIGH:
value = VITA_THREAD_PRIORITY_HIGH;
break;
case SDL_THREAD_PRIORITY_TIME_CRITICAL:
value = VITA_THREAD_PRIORITY_TIME_CRITICAL;
break;
}
return sceKernelChangeThreadPriority(0, value);
}
#endif /* SDL_THREAD_VITA */

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -26,7 +26,7 @@
#include "../generic/SDL_syscond_c.h"
#include "SDL_sysmutex_c.h"
typedef SDL_cond * (*pfnSDL_CreateCond)(void);
typedef SDL_cond *(*pfnSDL_CreateCond)(void);
typedef void (*pfnSDL_DestroyCond)(SDL_cond *);
typedef int (*pfnSDL_CondSignal)(SDL_cond *);
typedef int (*pfnSDL_CondBroadcast)(SDL_cond *);
@ -35,39 +35,42 @@ typedef int (*pfnSDL_CondWaitTimeout)(SDL_cond *, SDL_mutex *, Uint32);
typedef struct SDL_cond_impl_t
{
pfnSDL_CreateCond Create;
pfnSDL_DestroyCond Destroy;
pfnSDL_CondSignal Signal;
pfnSDL_CondBroadcast Broadcast;
pfnSDL_CondWait Wait;
pfnSDL_CondWaitTimeout WaitTimeout;
pfnSDL_CreateCond Create;
pfnSDL_DestroyCond Destroy;
pfnSDL_CondSignal Signal;
pfnSDL_CondBroadcast Broadcast;
pfnSDL_CondWait Wait;
pfnSDL_CondWaitTimeout WaitTimeout;
} SDL_cond_impl_t;
/* Implementation will be chosen at runtime based on available Kernel features */
static SDL_cond_impl_t SDL_cond_impl_active = {0};
static SDL_cond_impl_t SDL_cond_impl_active = { 0 };
/**
* Native Windows Condition Variable (SRW Locks)
*/
#ifndef CONDITION_VARIABLE_INIT
#define CONDITION_VARIABLE_INIT {0}
typedef struct CONDITION_VARIABLE {
#define CONDITION_VARIABLE_INIT \
{ \
0 \
}
typedef struct CONDITION_VARIABLE
{
PVOID Ptr;
} CONDITION_VARIABLE, *PCONDITION_VARIABLE;
#endif
#if __WINRT__
#define pWakeConditionVariable WakeConditionVariable
#define pWakeAllConditionVariable WakeAllConditionVariable
#define pWakeConditionVariable WakeConditionVariable
#define pWakeAllConditionVariable WakeAllConditionVariable
#define pSleepConditionVariableSRW SleepConditionVariableSRW
#define pSleepConditionVariableCS SleepConditionVariableCS
#define pSleepConditionVariableCS SleepConditionVariableCS
#else
typedef VOID(WINAPI *pfnWakeConditionVariable)(PCONDITION_VARIABLE);
typedef VOID(WINAPI *pfnWakeAllConditionVariable)(PCONDITION_VARIABLE);
typedef BOOL(WINAPI *pfnSleepConditionVariableSRW)(PCONDITION_VARIABLE, PSRWLOCK, DWORD, ULONG);
typedef BOOL(WINAPI* pfnSleepConditionVariableCS)(PCONDITION_VARIABLE, PCRITICAL_SECTION, DWORD);
typedef BOOL(WINAPI *pfnSleepConditionVariableCS)(PCONDITION_VARIABLE, PCRITICAL_SECTION, DWORD);
static pfnWakeConditionVariable pWakeConditionVariable = NULL;
static pfnWakeAllConditionVariable pWakeAllConditionVariable = NULL;
@ -80,35 +83,31 @@ typedef struct SDL_cond_cv
CONDITION_VARIABLE cond;
} SDL_cond_cv;
static SDL_cond *
SDL_CreateCond_cv(void)
static SDL_cond *SDL_CreateCond_cv(void)
{
SDL_cond_cv *cond;
/* Relies on CONDITION_VARIABLE_INIT == 0. */
cond = (SDL_cond_cv *) SDL_calloc(1, sizeof(*cond));
if (!cond) {
cond = (SDL_cond_cv *)SDL_calloc(1, sizeof(*cond));
if (cond == NULL) {
SDL_OutOfMemory();
}
return (SDL_cond *)cond;
}
static void
SDL_DestroyCond_cv(SDL_cond * cond)
static void SDL_DestroyCond_cv(SDL_cond *cond)
{
if (cond) {
if (cond != NULL) {
/* There are no kernel allocated resources */
SDL_free(cond);
}
}
static int
SDL_CondSignal_cv(SDL_cond * _cond)
static int SDL_CondSignal_cv(SDL_cond *_cond)
{
SDL_cond_cv *cond = (SDL_cond_cv *)_cond;
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -117,11 +116,10 @@ SDL_CondSignal_cv(SDL_cond * _cond)
return 0;
}
static int
SDL_CondBroadcast_cv(SDL_cond * _cond)
static int SDL_CondBroadcast_cv(SDL_cond *_cond)
{
SDL_cond_cv *cond = (SDL_cond_cv *)_cond;
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
@ -130,24 +128,23 @@ SDL_CondBroadcast_cv(SDL_cond * _cond)
return 0;
}
static int
SDL_CondWaitTimeout_cv(SDL_cond * _cond, SDL_mutex * _mutex, Uint32 ms)
static int SDL_CondWaitTimeout_cv(SDL_cond *_cond, SDL_mutex *_mutex, Uint32 ms)
{
SDL_cond_cv *cond = (SDL_cond_cv *)_cond;
DWORD timeout;
int ret;
if (!cond) {
if (cond == NULL) {
return SDL_InvalidParamError("cond");
}
if (!_mutex) {
if (_mutex == NULL) {
return SDL_InvalidParamError("mutex");
}
if (ms == SDL_MUTEX_MAXWAIT) {
timeout = INFINITE;
} else {
timeout = (DWORD) ms;
timeout = (DWORD)ms;
}
if (SDL_mutex_impl_active.Type == SDL_MUTEX_SRW) {
@ -194,13 +191,12 @@ SDL_CondWaitTimeout_cv(SDL_cond * _cond, SDL_mutex * _mutex, Uint32 ms)
return ret;
}
static int
SDL_CondWait_cv(SDL_cond * cond, SDL_mutex * mutex) {
static int SDL_CondWait_cv(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout_cv(cond, mutex, SDL_MUTEX_MAXWAIT);
}
static const SDL_cond_impl_t SDL_cond_impl_cv =
{
static const SDL_cond_impl_t SDL_cond_impl_cv = {
&SDL_CreateCond_cv,
&SDL_DestroyCond_cv,
&SDL_CondSignal_cv,
@ -213,8 +209,7 @@ static const SDL_cond_impl_t SDL_cond_impl_cv =
* Generic Condition Variable implementation using SDL_mutex and SDL_sem
*/
static const SDL_cond_impl_t SDL_cond_impl_generic =
{
static const SDL_cond_impl_t SDL_cond_impl_generic = {
&SDL_CreateCond_generic,
&SDL_DestroyCond_generic,
&SDL_CondSignal_generic,
@ -223,18 +218,16 @@ static const SDL_cond_impl_t SDL_cond_impl_generic =
&SDL_CondWaitTimeout_generic,
};
SDL_cond *
SDL_CreateCond(void)
SDL_cond *SDL_CreateCond(void)
{
if (SDL_cond_impl_active.Create == NULL) {
/* Default to generic implementation, works with all mutex implementations */
const SDL_cond_impl_t * impl = &SDL_cond_impl_generic;
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) {
if (mutex == NULL) {
return NULL;
}
SDL_DestroyMutex(mutex);
@ -249,10 +242,10 @@ SDL_CreateCond(void)
{
HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll"));
if (kernel32) {
pWakeConditionVariable = (pfnWakeConditionVariable) GetProcAddress(kernel32, "WakeConditionVariable");
pWakeAllConditionVariable = (pfnWakeAllConditionVariable) GetProcAddress(kernel32, "WakeAllConditionVariable");
pSleepConditionVariableSRW = (pfnSleepConditionVariableSRW) GetProcAddress(kernel32, "SleepConditionVariableSRW");
pSleepConditionVariableCS = (pfnSleepConditionVariableCS) GetProcAddress(kernel32, "SleepConditionVariableCS");
pWakeConditionVariable = (pfnWakeConditionVariable)GetProcAddress(kernel32, "WakeConditionVariable");
pWakeAllConditionVariable = (pfnWakeAllConditionVariable)GetProcAddress(kernel32, "WakeAllConditionVariable");
pSleepConditionVariableSRW = (pfnSleepConditionVariableSRW)GetProcAddress(kernel32, "SleepConditionVariableSRW");
pSleepConditionVariableCS = (pfnSleepConditionVariableCS)GetProcAddress(kernel32, "SleepConditionVariableCS");
if (pWakeConditionVariable && pWakeAllConditionVariable && pSleepConditionVariableSRW && pSleepConditionVariableCS) {
/* Use the Windows provided API */
impl = &SDL_cond_impl_cv;
@ -261,37 +254,32 @@ SDL_CreateCond(void)
}
#endif
SDL_memcpy(&SDL_cond_impl_active, impl, sizeof(SDL_cond_impl_active));
SDL_copyp(&SDL_cond_impl_active, impl);
}
return SDL_cond_impl_active.Create();
}
void
SDL_DestroyCond(SDL_cond * cond)
void SDL_DestroyCond(SDL_cond *cond)
{
SDL_cond_impl_active.Destroy(cond);
}
int
SDL_CondSignal(SDL_cond * cond)
int SDL_CondSignal(SDL_cond *cond)
{
return SDL_cond_impl_active.Signal(cond);
}
int
SDL_CondBroadcast(SDL_cond * cond)
int SDL_CondBroadcast(SDL_cond *cond)
{
return SDL_cond_impl_active.Broadcast(cond);
}
int
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
{
return SDL_cond_impl_active.WaitTimeout(cond, mutex, ms);
}
int
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_cond_impl_active.Wait(cond, mutex);
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -35,10 +35,8 @@
#include "SDL_sysmutex_c.h"
/* Implementation will be chosen at runtime based on available Kernel features */
SDL_mutex_impl_t SDL_mutex_impl_active = {0};
SDL_mutex_impl_t SDL_mutex_impl_active = { 0 };
/**
* Implementation based on Slim Reader/Writer (SRW) Locks for Win 7 and newer.
@ -46,8 +44,8 @@ SDL_mutex_impl_t SDL_mutex_impl_active = {0};
#if __WINRT__
/* Functions are guaranteed to be available */
#define pReleaseSRWLockExclusive ReleaseSRWLockExclusive
#define pAcquireSRWLockExclusive AcquireSRWLockExclusive
#define pReleaseSRWLockExclusive ReleaseSRWLockExclusive
#define pAcquireSRWLockExclusive AcquireSRWLockExclusive
#define pTryAcquireSRWLockExclusive TryAcquireSRWLockExclusive
#else
typedef VOID(WINAPI *pfnReleaseSRWLockExclusive)(PSRWLOCK);
@ -58,37 +56,34 @@ static pfnAcquireSRWLockExclusive pAcquireSRWLockExclusive = NULL;
static pfnTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive = NULL;
#endif
static SDL_mutex *
SDL_CreateMutex_srw(void)
static SDL_mutex *SDL_CreateMutex_srw(void)
{
SDL_mutex_srw *mutex;
/* Relies on SRWLOCK_INIT == 0. */
mutex = (SDL_mutex_srw *) SDL_calloc(1, sizeof(*mutex));
if (!mutex) {
mutex = (SDL_mutex_srw *)SDL_calloc(1, sizeof(*mutex));
if (mutex == NULL) {
SDL_OutOfMemory();
}
return (SDL_mutex *)mutex;
}
static void
SDL_DestroyMutex_srw(SDL_mutex * mutex)
static void SDL_DestroyMutex_srw(SDL_mutex *mutex)
{
if (mutex) {
if (mutex != NULL) {
/* There are no kernel allocated resources */
SDL_free(mutex);
}
}
static int
SDL_LockMutex_srw(SDL_mutex * _mutex)
static int 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;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
this_thread = GetCurrentThreadId();
@ -107,15 +102,14 @@ SDL_LockMutex_srw(SDL_mutex * _mutex)
return 0;
}
static int
SDL_TryLockMutex_srw(SDL_mutex * _mutex)
static int SDL_TryLockMutex_srw(SDL_mutex *_mutex)
{
SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex;
DWORD this_thread;
int retval = 0;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
this_thread = GetCurrentThreadId();
@ -133,13 +127,12 @@ SDL_TryLockMutex_srw(SDL_mutex * _mutex)
return retval;
}
static int
SDL_UnlockMutex_srw(SDL_mutex * _mutex)
static int 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;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
if (mutex->owner == GetCurrentThreadId()) {
@ -154,8 +147,7 @@ SDL_UnlockMutex_srw(SDL_mutex * _mutex)
return 0;
}
static const SDL_mutex_impl_t SDL_mutex_impl_srw =
{
static const SDL_mutex_impl_t SDL_mutex_impl_srw = {
&SDL_CreateMutex_srw,
&SDL_DestroyMutex_srw,
&SDL_LockMutex_srw,
@ -164,20 +156,18 @@ static const SDL_mutex_impl_t SDL_mutex_impl_srw =
SDL_MUTEX_SRW,
};
/**
* Fallback Mutex implementation using Critical Sections (before Win 7)
*/
/* Create a mutex */
static SDL_mutex *
SDL_CreateMutex_cs(void)
static SDL_mutex *SDL_CreateMutex_cs(void)
{
SDL_mutex_cs *mutex;
/* Allocate mutex memory */
mutex = (SDL_mutex_cs *) SDL_malloc(sizeof(*mutex));
if (mutex) {
mutex = (SDL_mutex_cs *)SDL_malloc(sizeof(*mutex));
if (mutex != NULL) {
/* Initialize */
/* On SMP systems, a non-zero spin count generally helps performance */
#if __WINRT__
@ -192,23 +182,21 @@ SDL_CreateMutex_cs(void)
}
/* Free the mutex */
static void
SDL_DestroyMutex_cs(SDL_mutex * mutex_)
static void SDL_DestroyMutex_cs(SDL_mutex *mutex_)
{
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
if (mutex) {
if (mutex != NULL) {
DeleteCriticalSection(&mutex->cs);
SDL_free(mutex);
}
}
/* Lock the mutex */
static int
SDL_LockMutex_cs(SDL_mutex * mutex_)
static int 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_;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
EnterCriticalSection(&mutex->cs);
@ -216,13 +204,12 @@ SDL_LockMutex_cs(SDL_mutex * mutex_)
}
/* TryLock the mutex */
static int
SDL_TryLockMutex_cs(SDL_mutex * mutex_)
static int SDL_TryLockMutex_cs(SDL_mutex *mutex_)
{
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
int retval = 0;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
if (TryEnterCriticalSection(&mutex->cs) == 0) {
@ -232,20 +219,18 @@ SDL_TryLockMutex_cs(SDL_mutex * mutex_)
}
/* Unlock the mutex */
static int
SDL_UnlockMutex_cs(SDL_mutex * mutex_)
static int 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_;
if (mutex == NULL) {
return SDL_InvalidParamError("mutex");
return 0;
}
LeaveCriticalSection(&mutex->cs);
return 0;
}
static const SDL_mutex_impl_t SDL_mutex_impl_cs =
{
static const SDL_mutex_impl_t SDL_mutex_impl_cs = {
&SDL_CreateMutex_cs,
&SDL_DestroyMutex_cs,
&SDL_LockMutex_cs,
@ -254,17 +239,15 @@ static const SDL_mutex_impl_t SDL_mutex_impl_cs =
SDL_MUTEX_CS,
};
/**
* Runtime selection and redirection
*/
SDL_mutex *
SDL_CreateMutex(void)
SDL_mutex *SDL_CreateMutex(void)
{
if (SDL_mutex_impl_active.Create == NULL) {
/* Default to fallback implementation */
const SDL_mutex_impl_t * impl = &SDL_mutex_impl_cs;
const SDL_mutex_impl_t *impl = &SDL_mutex_impl_cs;
if (!SDL_GetHintBoolean(SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS, SDL_FALSE)) {
#if __WINRT__
@ -275,10 +258,10 @@ SDL_CreateMutex(void)
HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll"));
if (kernel32) {
/* Requires Vista: */
pReleaseSRWLockExclusive = (pfnReleaseSRWLockExclusive) GetProcAddress(kernel32, "ReleaseSRWLockExclusive");
pAcquireSRWLockExclusive = (pfnAcquireSRWLockExclusive) GetProcAddress(kernel32, "AcquireSRWLockExclusive");
pReleaseSRWLockExclusive = (pfnReleaseSRWLockExclusive)GetProcAddress(kernel32, "ReleaseSRWLockExclusive");
pAcquireSRWLockExclusive = (pfnAcquireSRWLockExclusive)GetProcAddress(kernel32, "AcquireSRWLockExclusive");
/* Requires 7: */
pTryAcquireSRWLockExclusive = (pfnTryAcquireSRWLockExclusive) GetProcAddress(kernel32, "TryAcquireSRWLockExclusive");
pTryAcquireSRWLockExclusive = (pfnTryAcquireSRWLockExclusive)GetProcAddress(kernel32, "TryAcquireSRWLockExclusive");
if (pReleaseSRWLockExclusive && pAcquireSRWLockExclusive && pTryAcquireSRWLockExclusive) {
impl = &SDL_mutex_impl_srw;
}
@ -287,28 +270,28 @@ SDL_CreateMutex(void)
}
/* Copy instead of using pointer to save one level of indirection */
SDL_memcpy(&SDL_mutex_impl_active, impl, sizeof(SDL_mutex_impl_active));
SDL_copyp(&SDL_mutex_impl_active, impl);
}
return SDL_mutex_impl_active.Create();
}
void
SDL_DestroyMutex(SDL_mutex * mutex) {
void SDL_DestroyMutex(SDL_mutex *mutex)
{
SDL_mutex_impl_active.Destroy(mutex);
}
int
SDL_LockMutex(SDL_mutex * mutex) {
int SDL_LockMutex(SDL_mutex *mutex)
{
return SDL_mutex_impl_active.Lock(mutex);
}
int
SDL_TryLockMutex(SDL_mutex * mutex) {
int SDL_TryLockMutex(SDL_mutex *mutex)
{
return SDL_mutex_impl_active.TryLock(mutex);
}
int
SDL_UnlockMutex(SDL_mutex * mutex) {
int SDL_UnlockMutex(SDL_mutex *mutex)
{
return SDL_mutex_impl_active.Unlock(mutex);
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -39,21 +39,24 @@ typedef enum
typedef struct SDL_mutex_impl_t
{
pfnSDL_CreateMutex Create;
pfnSDL_CreateMutex Create;
pfnSDL_DestroyMutex Destroy;
pfnSDL_LockMutex Lock;
pfnSDL_LockMutex Lock;
pfnSDL_TryLockMutex TryLock;
pfnSDL_UnlockMutex Unlock;
pfnSDL_UnlockMutex Unlock;
/* Needed by SDL_cond: */
SDL_MutexType Type;
SDL_MutexType Type;
} SDL_mutex_impl_t;
extern SDL_mutex_impl_t SDL_mutex_impl_active;
#ifndef SRWLOCK_INIT
#define SRWLOCK_INIT {0}
typedef struct _SRWLOCK {
#define SRWLOCK_INIT \
{ \
0 \
}
typedef struct _SRWLOCK
{
PVOID Ptr;
} SRWLOCK, *PSRWLOCK;
#endif

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -31,7 +31,7 @@
* Faster due to significantly less context switches.
* Requires Windows 8 or newer.
* which are chosen at runtime.
*/
*/
#include "../../core/windows/SDL_windows.h"
@ -49,18 +49,17 @@ typedef int (*pfnSDL_SemPost)(SDL_sem *);
typedef struct SDL_semaphore_impl_t
{
pfnSDL_CreateSemaphore Create;
pfnSDL_CreateSemaphore Create;
pfnSDL_DestroySemaphore Destroy;
pfnSDL_SemWaitTimeout WaitTimeout;
pfnSDL_SemTryWait TryWait;
pfnSDL_SemWait Wait;
pfnSDL_SemValue Value;
pfnSDL_SemPost Post;
pfnSDL_SemWaitTimeout WaitTimeout;
pfnSDL_SemTryWait TryWait;
pfnSDL_SemWait Wait;
pfnSDL_SemValue Value;
pfnSDL_SemPost Post;
} SDL_sem_impl_t;
/* Implementation will be chosen at runtime based on available Kernel features */
static SDL_sem_impl_t SDL_sem_impl_active = {0};
static SDL_sem_impl_t SDL_sem_impl_active = { 0 };
/**
* Atomic + WaitOnAddress implementation
@ -70,7 +69,7 @@ static SDL_sem_impl_t SDL_sem_impl_active = {0};
/* 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)
#define SDL_WINAPI_FAMILY_PHONE (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
#else
#define SDL_WINAPI_FAMILY_PHONE 0
#endif
@ -78,10 +77,10 @@ static SDL_sem_impl_t SDL_sem_impl_active = {0};
#if !SDL_WINAPI_FAMILY_PHONE
#if __WINRT__
/* Functions are guaranteed to be available */
#define pWaitOnAddress WaitOnAddress
#define pWaitOnAddress WaitOnAddress
#define pWakeByAddressSingle WakeByAddressSingle
#else
typedef BOOL(WINAPI *pfnWaitOnAddress)(volatile VOID*, PVOID, SIZE_T, DWORD);
typedef BOOL(WINAPI *pfnWaitOnAddress)(volatile VOID *, PVOID, SIZE_T, DWORD);
typedef VOID(WINAPI *pfnWakeByAddressSingle)(PVOID);
static pfnWaitOnAddress pWaitOnAddress = NULL;
@ -93,13 +92,12 @@ typedef struct SDL_semaphore_atom
LONG count;
} SDL_sem_atom;
static SDL_sem *
SDL_CreateSemaphore_atom(Uint32 initial_value)
static SDL_sem *SDL_CreateSemaphore_atom(Uint32 initial_value)
{
SDL_sem_atom *sem;
sem = (SDL_sem_atom *) SDL_malloc(sizeof(*sem));
if (sem) {
sem = (SDL_sem_atom *)SDL_malloc(sizeof(*sem));
if (sem != NULL) {
sem->count = initial_value;
} else {
SDL_OutOfMemory();
@ -107,21 +105,19 @@ SDL_CreateSemaphore_atom(Uint32 initial_value)
return (SDL_sem *)sem;
}
static void
SDL_DestroySemaphore_atom(SDL_sem * sem)
static void SDL_DestroySemaphore_atom(SDL_sem *sem)
{
if (sem) {
if (sem != NULL) {
SDL_free(sem);
}
}
static int
SDL_SemTryWait_atom(SDL_sem * _sem)
static int SDL_SemTryWait_atom(SDL_sem *_sem)
{
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
LONG count;
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
@ -137,13 +133,12 @@ SDL_SemTryWait_atom(SDL_sem * _sem)
return SDL_MUTEX_TIMEDOUT;
}
static int
SDL_SemWait_atom(SDL_sem * _sem)
static int SDL_SemWait_atom(SDL_sem *_sem)
{
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
LONG count;
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
@ -162,8 +157,7 @@ SDL_SemWait_atom(SDL_sem * _sem)
}
}
static int
SDL_SemWaitTimeout_atom(SDL_sem * _sem, Uint32 timeout)
static int SDL_SemWaitTimeout_atom(SDL_sem *_sem, Uint32 timeout)
{
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
LONG count;
@ -175,7 +169,7 @@ SDL_SemWaitTimeout_atom(SDL_sem * _sem, Uint32 timeout)
return SDL_SemWait_atom(_sem);
}
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
@ -184,7 +178,7 @@ SDL_SemWaitTimeout_atom(SDL_sem * _sem, Uint32 timeout)
* need to recalculate the effective timeout before every wait
*/
now = SDL_GetTicks();
deadline = now + (DWORD) timeout;
deadline = now + (DWORD)timeout;
for (;;) {
count = sem->count;
@ -213,12 +207,11 @@ SDL_SemWaitTimeout_atom(SDL_sem * _sem, Uint32 timeout)
}
}
static Uint32
SDL_SemValue_atom(SDL_sem * _sem)
static Uint32 SDL_SemValue_atom(SDL_sem *_sem)
{
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
if (!sem) {
if (sem == NULL) {
SDL_InvalidParamError("sem");
return 0;
}
@ -226,12 +219,11 @@ SDL_SemValue_atom(SDL_sem * _sem)
return (Uint32)sem->count;
}
static int
SDL_SemPost_atom(SDL_sem * _sem)
static int SDL_SemPost_atom(SDL_sem *_sem)
{
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
@ -241,8 +233,7 @@ SDL_SemPost_atom(SDL_sem * _sem)
return 0;
}
static const SDL_sem_impl_t SDL_sem_impl_atom =
{
static const SDL_sem_impl_t SDL_sem_impl_atom = {
&SDL_CreateSemaphore_atom,
&SDL_DestroySemaphore_atom,
&SDL_SemWaitTimeout_atom,
@ -253,7 +244,6 @@ static const SDL_sem_impl_t SDL_sem_impl_atom =
};
#endif /* !SDL_WINAPI_FAMILY_PHONE */
/**
* Fallback Semaphore implementation using Kernel Semaphores
*/
@ -265,14 +255,13 @@ typedef struct SDL_semaphore_kern
} SDL_sem_kern;
/* Create a semaphore */
static SDL_sem *
SDL_CreateSemaphore_kern(Uint32 initial_value)
static SDL_sem *SDL_CreateSemaphore_kern(Uint32 initial_value)
{
SDL_sem_kern *sem;
/* Allocate sem memory */
sem = (SDL_sem_kern *) SDL_malloc(sizeof(*sem));
if (sem) {
sem = (SDL_sem_kern *)SDL_malloc(sizeof(*sem));
if (sem != NULL) {
/* Create the semaphore, with max value 32K */
#if __WINRT__
sem->id = CreateSemaphoreEx(NULL, initial_value, 32 * 1024, NULL, 0, SEMAPHORE_ALL_ACCESS);
@ -292,11 +281,10 @@ SDL_CreateSemaphore_kern(Uint32 initial_value)
}
/* Free the semaphore */
static void
SDL_DestroySemaphore_kern(SDL_sem * _sem)
static void SDL_DestroySemaphore_kern(SDL_sem *_sem)
{
SDL_sem_kern *sem = (SDL_sem_kern *)_sem;
if (sem) {
if (sem != NULL) {
if (sem->id) {
CloseHandle(sem->id);
sem->id = 0;
@ -305,21 +293,20 @@ SDL_DestroySemaphore_kern(SDL_sem * _sem)
}
}
static int
SDL_SemWaitTimeout_kern(SDL_sem * _sem, Uint32 timeout)
static int SDL_SemWaitTimeout_kern(SDL_sem *_sem, Uint32 timeout)
{
SDL_sem_kern *sem = (SDL_sem_kern *)_sem;
int retval;
DWORD dwMilliseconds;
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
if (timeout == SDL_MUTEX_MAXWAIT) {
dwMilliseconds = INFINITE;
} else {
dwMilliseconds = (DWORD) timeout;
dwMilliseconds = (DWORD)timeout;
}
switch (WaitForSingleObjectEx(sem->id, dwMilliseconds, FALSE)) {
case WAIT_OBJECT_0:
@ -336,35 +323,31 @@ SDL_SemWaitTimeout_kern(SDL_sem * _sem, Uint32 timeout)
return retval;
}
static int
SDL_SemTryWait_kern(SDL_sem * sem)
static int SDL_SemTryWait_kern(SDL_sem *sem)
{
return SDL_SemWaitTimeout_kern(sem, 0);
}
static int
SDL_SemWait_kern(SDL_sem * sem)
static int SDL_SemWait_kern(SDL_sem *sem)
{
return SDL_SemWaitTimeout_kern(sem, SDL_MUTEX_MAXWAIT);
}
/* Returns the current count of the semaphore */
static Uint32
SDL_SemValue_kern(SDL_sem * _sem)
static Uint32 SDL_SemValue_kern(SDL_sem *_sem)
{
SDL_sem_kern *sem = (SDL_sem_kern *)_sem;
if (!sem) {
if (sem == NULL) {
SDL_InvalidParamError("sem");
return 0;
}
return (Uint32)sem->count;
}
static int
SDL_SemPost_kern(SDL_sem * _sem)
static int SDL_SemPost_kern(SDL_sem *_sem)
{
SDL_sem_kern *sem = (SDL_sem_kern *)_sem;
if (!sem) {
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
/* Increase the counter in the first place, because
@ -374,14 +357,13 @@ SDL_SemPost_kern(SDL_sem * _sem)
*/
InterlockedIncrement(&sem->count);
if (ReleaseSemaphore(sem->id, 1, NULL) == FALSE) {
InterlockedDecrement(&sem->count); /* restore */
InterlockedDecrement(&sem->count); /* restore */
return SDL_SetError("ReleaseSemaphore() failed");
}
return 0;
}
static const SDL_sem_impl_t SDL_sem_impl_kern =
{
static const SDL_sem_impl_t SDL_sem_impl_kern = {
&SDL_CreateSemaphore_kern,
&SDL_DestroySemaphore_kern,
&SDL_SemWaitTimeout_kern,
@ -391,17 +373,15 @@ static const SDL_sem_impl_t SDL_sem_impl_kern =
&SDL_SemPost_kern,
};
/**
* Runtime selection and redirection
*/
SDL_sem *
SDL_CreateSemaphore(Uint32 initial_value)
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
if (SDL_sem_impl_active.Create == NULL) {
/* Default to fallback implementation */
const SDL_sem_impl_t * impl = &SDL_sem_impl_kern;
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)) {
@ -418,10 +398,10 @@ SDL_CreateSemaphore(Uint32 initial_value)
HMODULE synch120 = GetModuleHandle(TEXT("api-ms-win-core-synch-l1-2-0.dll"));
if (synch120) {
/* Try to load required functions provided by Win 8 or newer */
pWaitOnAddress = (pfnWaitOnAddress) GetProcAddress(synch120, "WaitOnAddress");
pWakeByAddressSingle = (pfnWakeByAddressSingle) GetProcAddress(synch120, "WakeByAddressSingle");
pWaitOnAddress = (pfnWaitOnAddress)GetProcAddress(synch120, "WaitOnAddress");
pWakeByAddressSingle = (pfnWakeByAddressSingle)GetProcAddress(synch120, "WakeByAddressSingle");
if(pWaitOnAddress && pWakeByAddressSingle) {
if (pWaitOnAddress && pWakeByAddressSingle) {
impl = &SDL_sem_impl_atom;
}
}
@ -430,43 +410,37 @@ SDL_CreateSemaphore(Uint32 initial_value)
#endif
/* Copy instead of using pointer to save one level of indirection */
SDL_memcpy(&SDL_sem_impl_active, impl, sizeof(SDL_sem_impl_active));
SDL_copyp(&SDL_sem_impl_active, impl);
}
return SDL_sem_impl_active.Create(initial_value);
}
void
SDL_DestroySemaphore(SDL_sem * sem)
void SDL_DestroySemaphore(SDL_sem *sem)
{
SDL_sem_impl_active.Destroy(sem);
}
int
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
return SDL_sem_impl_active.WaitTimeout(sem, timeout);
}
int
SDL_SemTryWait(SDL_sem * sem)
int SDL_SemTryWait(SDL_sem *sem)
{
return SDL_sem_impl_active.TryWait(sem);
}
int
SDL_SemWait(SDL_sem * sem)
int SDL_SemWait(SDL_sem *sem)
{
return SDL_sem_impl_active.Wait(sem);
}
Uint32
SDL_SemValue(SDL_sem * sem)
Uint32 SDL_SemValue(SDL_sem *sem)
{
return SDL_sem_impl_active.Value(sem);
}
int
SDL_SemPost(SDL_sem * sem)
int SDL_SemPost(SDL_sem *sem)
{
return SDL_sem_impl_active.Post(sem);
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -30,55 +30,24 @@
#include "../SDL_systhread.h"
#include "SDL_systhread_c.h"
#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD
/* We'll use the C library from this DLL */
#include <process.h>
#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
#endif
/* Cygwin gcc-3 ... MingW64 (even with a i386 host) does this like MSVC. */
#if (defined(__MINGW32__) && (__GNUC__ < 4))
typedef unsigned long (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned,
unsigned (__stdcall *func)(void *), void *arg,
unsigned, unsigned *threadID);
typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code);
#elif defined(__WATCOMC__)
/* This is for Watcom targets except OS2 */
#if __WATCOMC__ < 1240
#define __watcall
#endif
typedef unsigned long (__watcall * pfnSDL_CurrentBeginThread) (void *,
unsigned,
unsigned
(__stdcall *
func) (void
*),
void *arg,
unsigned,
unsigned
*threadID);
typedef void (__watcall * pfnSDL_CurrentEndThread) (unsigned code);
#else
typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned,
unsigned (__stdcall *
func) (void
*),
void *arg, unsigned,
unsigned *threadID);
typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code);
#endif
#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD
/* We'll use the C library from this DLL */
#include <process.h>
typedef uintptr_t(__cdecl *pfnSDL_CurrentBeginThread)(void *, unsigned,
unsigned(__stdcall *func)(void*),
void *arg, unsigned,
unsigned *threadID);
typedef void(__cdecl *pfnSDL_CurrentEndThread)(unsigned code);
#endif /* !SDL_PASSED_BEGINTHREAD_ENDTHREAD */
static DWORD
RunThread(void *data)
static DWORD RunThread(void *data)
{
SDL_Thread *thread = (SDL_Thread *) data;
pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread) thread->endfunc;
SDL_Thread *thread = (SDL_Thread *)data;
pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread)thread->endfunc;
SDL_RunThread(thread);
if (pfnEndThread != NULL) {
pfnEndThread(0);
@ -86,33 +55,28 @@ RunThread(void *data)
return 0;
}
static DWORD WINAPI
RunThreadViaCreateThread(LPVOID data)
static DWORD WINAPI RunThreadViaCreateThread(LPVOID data)
{
return RunThread(data);
return RunThread(data);
}
static unsigned __stdcall
RunThreadViaBeginThreadEx(void *data)
static unsigned __stdcall RunThreadViaBeginThreadEx(void *data)
{
return (unsigned) RunThread(data);
return (unsigned)RunThread(data);
}
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
int
SDL_SYS_CreateThread(SDL_Thread * thread,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread)
int SDL_SYS_CreateThread(SDL_Thread *thread,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread)
{
#elif defined(__CYGWIN__) || defined(__WINRT__)
int
SDL_SYS_CreateThread(SDL_Thread * thread)
int SDL_SYS_CreateThread(SDL_Thread *thread)
{
pfnSDL_CurrentBeginThread pfnBeginThread = NULL;
pfnSDL_CurrentEndThread pfnEndThread = NULL;
#else
int
SDL_SYS_CreateThread(SDL_Thread * thread)
int SDL_SYS_CreateThread(SDL_Thread *thread)
{
pfnSDL_CurrentBeginThread pfnBeginThread = (pfnSDL_CurrentBeginThread)_beginthreadex;
pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread)_endthreadex;
@ -125,10 +89,9 @@ SDL_SYS_CreateThread(SDL_Thread * thread)
/* thread->stacksize == 0 means "system default", same as win32 expects */
if (pfnBeginThread) {
unsigned threadid = 0;
thread->handle = (SYS_ThreadHandle)
((size_t) pfnBeginThread(NULL, (unsigned int) thread->stacksize,
RunThreadViaBeginThreadEx,
thread, flags, &threadid));
thread->handle = (SYS_ThreadHandle)((size_t)pfnBeginThread(NULL, (unsigned int)thread->stacksize,
RunThreadViaBeginThreadEx,
thread, flags, &threadid));
} else {
DWORD threadid = 0;
thread->handle = CreateThread(NULL, thread->stacksize,
@ -141,31 +104,29 @@ SDL_SYS_CreateThread(SDL_Thread * thread)
return 0;
}
#pragma pack(push,8)
#pragma pack(push, 8)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; /* must be 0x1000 */
LPCSTR szName; /* pointer to name (in user addr space) */
DWORD dwType; /* must be 0x1000 */
LPCSTR szName; /* pointer to name (in user addr space) */
DWORD dwThreadID; /* thread ID (-1=caller thread) */
DWORD dwFlags; /* reserved for future use, must be zero */
DWORD dwFlags; /* reserved for future use, must be zero */
} THREADNAME_INFO;
#pragma pack(pop)
typedef HRESULT(WINAPI *pfnSetThreadDescription)(HANDLE, PCWSTR);
typedef HRESULT (WINAPI *pfnSetThreadDescription)(HANDLE, PCWSTR);
void
SDL_SYS_SetupThread(const char *name)
void SDL_SYS_SetupThread(const char *name)
{
if (name != NULL) {
#ifndef __WINRT__ /* !!! FIXME: There's no LoadLibrary() in WinRT; don't know if SetThreadDescription is available there at all at the moment. */
#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 = 0;
static HMODULE kernel32 = NULL;
if (!kernel32) {
kernel32 = GetModuleHandle(TEXT("kernel32.dll"));
if (kernel32) {
pSetThreadDescription = (pfnSetThreadDescription) GetProcAddress(kernel32, "SetThreadDescription");
pSetThreadDescription = (pfnSetThreadDescription)GetProcAddress(kernel32, "SetThreadDescription");
}
}
@ -176,7 +137,7 @@ SDL_SYS_SetupThread(const char *name)
SDL_free(strw);
}
}
#endif
#endif
/* Presumably some version of Visual Studio will understand SetThreadDescription(),
but we still need to deal with older OSes and debuggers. Set it with the arcane
@ -194,23 +155,21 @@ SDL_SYS_SetupThread(const char *name)
SDL_zero(inf);
inf.dwType = 0x1000;
inf.szName = name;
inf.dwThreadID = (DWORD) -1;
inf.dwThreadID = (DWORD)-1;
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), (const ULONG_PTR *)&inf);
}
}
}
SDL_threadID
SDL_ThreadID(void)
SDL_threadID SDL_ThreadID(void)
{
return ((SDL_threadID) GetCurrentThreadId());
return (SDL_threadID)GetCurrentThreadId();
}
int
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
int value;
@ -229,15 +188,13 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
return 0;
}
void
SDL_SYS_WaitThread(SDL_Thread * thread)
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
WaitForSingleObjectEx(thread->handle, INFINITE, FALSE);
CloseHandle(thread->handle);
}
void
SDL_SYS_DetachThread(SDL_Thread * thread)
void SDL_SYS_DetachThread(SDL_Thread *thread)
{
CloseHandle(thread->handle);
}

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
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
@ -32,7 +32,7 @@
#include <fibersapi.h>
#ifndef TLS_OUT_OF_INDEXES
#define TLS_OUT_OF_INDEXES FLS_OUT_OF_INDEXES
#define TLS_OUT_OF_INDEXES FLS_OUT_OF_INDEXES
#endif
#define TlsAlloc() FlsAlloc(NULL)
@ -43,8 +43,7 @@
static DWORD thread_local_storage = TLS_OUT_OF_INDEXES;
static SDL_bool generic_local_storage = SDL_FALSE;
SDL_TLSData *
SDL_SYS_GetTLSData(void)
SDL_TLSData *SDL_SYS_GetTLSData(void)
{
if (thread_local_storage == TLS_OUT_OF_INDEXES && !generic_local_storage) {
static SDL_SpinLock lock;
@ -67,8 +66,7 @@ SDL_SYS_GetTLSData(void)
return (SDL_TLSData *)TlsGetValue(thread_local_storage);
}
int
SDL_SYS_SetTLSData(SDL_TLSData *data)
int SDL_SYS_SetTLSData(SDL_TLSData *data)
{
if (generic_local_storage) {
return SDL_Generic_SetTLSData(data);