mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-28 09:48:05 +03:00
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:
+6
-5
@@ -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
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user