SDL: Add thread primitive compatibility

Wrap mutexes, condition variables, and atomic integers with common SDL2
and SDL3 types and semantics.  Normalize timed condition waits to report
whether the condition was signaled.
This commit is contained in:
kichikuou
2026-09-22 14:47:34 +09:00
parent 5eea90c9a8
commit e488123345
4 changed files with 128 additions and 21 deletions
+6 -5
View File
@@ -24,6 +24,7 @@
#include "config.h"
#include <stdlib.h>
#include <portmidi.h>
#include "sdl_compat.h"
@@ -61,7 +62,7 @@ static PmDeviceID device_id;
static SDL_Thread *thread;
static struct msgq *queue;
static int start_time;
static SDL_atomic_t atomic_seq;
static sdl_atomic_int_t atomic_seq;
static void enqueue(struct midi_message msg) {
struct midi_message *buf = malloc(sizeof(struct midi_message));
@@ -225,7 +226,7 @@ static int midi_thread(void* unused) {
midi_playloop(stream, msg.music);
send_reset(stream);
}
SDL_AtomicCAS(&atomic_seq, msg.seq, 0);
sdl_compare_and_swap_atomic_int(&atomic_seq, msg.seq, 0);
mf_remove_midifile(msg.music);
break;
@@ -298,7 +299,7 @@ static bool midi_start(int no, int loop, const uint8_t *data, int datalen) {
WARNING("error reading midi file");
return false;
}
SDL_AtomicSet(&atomic_seq, ++seq);
sdl_set_atomic_int(&atomic_seq, ++seq);
ENQUEUE(CMD_PLAY, seq, midi);
start_time = SDL_GetTicks();
@@ -308,7 +309,7 @@ static bool midi_start(int no, int loop, const uint8_t *data, int datalen) {
static void midi_stop(void) {
if (queue) {
SDL_AtomicSet(&atomic_seq, 0);
sdl_set_atomic_int(&atomic_seq, 0);
ENQUEUE(CMD_STOP);
}
}
@@ -324,7 +325,7 @@ static void midi_unpause(void) {
}
static bool midi_get_playing_info(midiplaystate *st) {
if (SDL_AtomicGet(&atomic_seq) == 0) {
if (sdl_get_atomic_int(&atomic_seq) == 0) {
st->in_play = false;
st->loc_ms = 0;
return true;
+15 -14
View File
@@ -27,14 +27,14 @@ struct msgq_elem {
struct msgq *msgq_new(void) {
struct msgq *q = calloc(1, sizeof(struct msgq));
q->mutex = SDL_CreateMutex();
q->cond_nonempty = SDL_CreateCond();
q->mutex = sdl_create_mutex();
q->cond_nonempty = sdl_create_condition();
return q;
}
void msgq_free(struct msgq *q) {
SDL_DestroyMutex(q->mutex);
SDL_DestroyCond(q->cond_nonempty);
sdl_destroy_mutex(q->mutex);
sdl_destroy_condition(q->cond_nonempty);
free(q);
}
@@ -43,28 +43,28 @@ void msgq_enqueue(struct msgq *q, void *msg) {
e->msg = msg;
e->next = NULL;
SDL_LockMutex(q->mutex);
sdl_lock_mutex(q->mutex);
if (!q->head) {
q->head = q->last = e;
} else {
q->last->next = e;
q->last = e;
}
SDL_UnlockMutex(q->mutex);
SDL_CondSignal(q->cond_nonempty);
sdl_unlock_mutex(q->mutex);
sdl_signal_condition(q->cond_nonempty);
}
void *msgq_dequeue(struct msgq *q) {
SDL_LockMutex(q->mutex);
sdl_lock_mutex(q->mutex);
while (!q->head)
SDL_CondWait(q->cond_nonempty, q->mutex);
sdl_wait_condition(q->cond_nonempty, q->mutex);
struct msgq_elem *e = q->head;
q->head = e->next;
if (!e->next)
q->last = NULL;
SDL_UnlockMutex(q->mutex);
sdl_unlock_mutex(q->mutex);
void *msg = e->msg;
free(e);
@@ -72,13 +72,14 @@ void *msgq_dequeue(struct msgq *q) {
}
void *msgq_dequeue_timeout(struct msgq *q, uint32_t timeout_ms) {
SDL_LockMutex(q->mutex);
sdl_lock_mutex(q->mutex);
while (!q->head && SDL_CondWaitTimeout(q->cond_nonempty, q->mutex, timeout_ms) == 0)
while (!q->head &&
sdl_wait_condition_timeout(q->cond_nonempty, q->mutex, timeout_ms))
;
if (!q->head) { // timed out
SDL_UnlockMutex(q->mutex);
sdl_unlock_mutex(q->mutex);
return NULL;
}
@@ -87,7 +88,7 @@ void *msgq_dequeue_timeout(struct msgq *q, uint32_t timeout_ms) {
if (!e->next)
q->last = NULL;
SDL_UnlockMutex(q->mutex);
sdl_unlock_mutex(q->mutex);
void *msg = e->msg;
free(e);
+2 -2
View File
@@ -26,8 +26,8 @@
struct msgq_elem;
struct msgq {
SDL_mutex *mutex;
SDL_cond *cond_nonempty;
sdl_mutex_t *mutex;
sdl_condition_t *cond_nonempty;
struct msgq_elem *head;
struct msgq_elem *last;
};
+105
View File
@@ -326,4 +326,109 @@ static inline void sdl_get_rect_union(
#define SDL_IntersectRect sdl_get_rect_intersection
#define SDL_UnionRect sdl_get_rect_union
#if XSYSTEM35_SDL_VERSION == 2
typedef SDL_mutex sdl_mutex_t;
typedef SDL_cond sdl_condition_t;
typedef SDL_atomic_t sdl_atomic_int_t;
#else
typedef SDL_Mutex sdl_mutex_t;
typedef SDL_Condition sdl_condition_t;
typedef SDL_AtomicInt sdl_atomic_int_t;
#endif
static inline sdl_mutex_t *sdl_create_mutex(void)
{
return SDL_CreateMutex();
}
static inline void sdl_destroy_mutex(sdl_mutex_t *mutex)
{
SDL_DestroyMutex(mutex);
}
static inline void sdl_lock_mutex(sdl_mutex_t *mutex)
{
SDL_LockMutex(mutex);
}
static inline void sdl_unlock_mutex(sdl_mutex_t *mutex)
{
SDL_UnlockMutex(mutex);
}
static inline sdl_condition_t *sdl_create_condition(void)
{
#if XSYSTEM35_SDL_VERSION == 2
return SDL_CreateCond();
#else
return SDL_CreateCondition();
#endif
}
static inline void sdl_destroy_condition(sdl_condition_t *condition)
{
#if XSYSTEM35_SDL_VERSION == 2
SDL_DestroyCond(condition);
#else
SDL_DestroyCondition(condition);
#endif
}
static inline void sdl_signal_condition(sdl_condition_t *condition)
{
#if XSYSTEM35_SDL_VERSION == 2
SDL_CondSignal(condition);
#else
SDL_SignalCondition(condition);
#endif
}
static inline void sdl_wait_condition(
sdl_condition_t *condition, sdl_mutex_t *mutex)
{
#if XSYSTEM35_SDL_VERSION == 2
SDL_CondWait(condition, mutex);
#else
SDL_WaitCondition(condition, mutex);
#endif
}
static inline bool sdl_wait_condition_timeout(sdl_condition_t *condition,
sdl_mutex_t *mutex, uint32_t timeout_ms)
{
#if XSYSTEM35_SDL_VERSION == 2
return SDL_CondWaitTimeout(condition, mutex, timeout_ms) == 0;
#else
return SDL_WaitConditionTimeout(condition, mutex, timeout_ms);
#endif
}
static inline bool sdl_compare_and_swap_atomic_int(
sdl_atomic_int_t *value, int expected, int desired)
{
#if XSYSTEM35_SDL_VERSION == 2
return SDL_AtomicCAS(value, expected, desired) == SDL_TRUE;
#else
return SDL_CompareAndSwapAtomicInt(value, expected, desired);
#endif
}
static inline int sdl_set_atomic_int(sdl_atomic_int_t *value, int desired)
{
#if XSYSTEM35_SDL_VERSION == 2
return SDL_AtomicSet(value, desired);
#else
return SDL_SetAtomicInt(value, desired);
#endif
}
static inline int sdl_get_atomic_int(sdl_atomic_int_t *value)
{
#if XSYSTEM35_SDL_VERSION == 2
return SDL_AtomicGet(value);
#else
return SDL_GetAtomicInt(value);
#endif
}
#endif /* XSYSTEM35_SDL_COMPAT_H */