diff --git a/CMakeLists.txt b/CMakeLists.txt index 04e4800..fafd0c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ if (UNIX AND NOT APPLE) endif () include(CheckIncludeFile) +CHECK_INCLUDE_FILE("stdatomic.h" HAVE_C11_ATOMIC) CHECK_INCLUDE_FILE("threads.h" HAVE_C11_THREADS) CHECK_INCLUDE_FILE("pthread.h" HAVE_PTHREADS) @@ -25,6 +26,14 @@ else () message(WARNING "No thread library found") endif () +if (HAVE_C11_ATOMIC) + add_definitions(-DBINJNES_ATOMIC_C11) +elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + add_definitions(-DBINJNES_ATOMIC_MSVC) +else () + message(WARNING "No atomic library found") +endif () + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_definitions(-DBINJNES_CLANG) diff --git a/src/atomic.h b/src/atomic.h index c065b0c..e642676 100644 --- a/src/atomic.h +++ b/src/atomic.h @@ -1,17 +1,27 @@ -#if defined(BINJNES_GCC) || defined(BINJNES_CLANG) +#if defined(BINJNES_ATOMIC_C11) #include typedef atomic_size_t AtomicSize; +typedef atomic_bool AtomicBool; + static inline size_t atomic_load_size(AtomicSize* addr) { - return atomic_load(addr); + return atomic_load(addr); } static inline void atomic_store_size(AtomicSize* addr, size_t value) { - atomic_store(addr, value); + atomic_store(addr, value); +} + +static inline bool atomic_load_bool(AtomicBool* addr) { + return atomic_load(addr); } -#elif defined(BINJNES_MSVC) +static inline void atomic_store_bool(AtomicBool* addr, bool value) { + atomic_store(addr, value); +} + +#elif defined(BINJNES_ATOMIC_MSVC) #define WIN32_LEAN_AND_MEAN #define NOMINMAX @@ -19,13 +29,26 @@ static inline void atomic_store_size(AtomicSize* addr, size_t value) { #undef ERROR typedef volatile PVOID AtomicSize; +typedef AtomicSize AtomicBool; -size_t atomic_load_size(AtomicSize* addr) { - return (size_t)*addr; +static inline size_t atomic_load_size(AtomicSize* addr) { + return (size_t)*addr; } -void atomic_store_size(AtomicSize* addr, size_t value) { - _InterlockedExchangePointer(addr, (PVOID)value); +static inline void atomic_store_size(AtomicSize* addr, size_t value) { + _InterlockedExchangePointer(addr, (PVOID)value); } -#endif \ No newline at end of file +static inline bool atomic_load_bool(AtomicBool* addr) { + return (bool)atomic_load_size(addr); +} + +static inline void atomic_store_bool(AtomicBool* addr, bool value) { + atomic_store_size(addr, (size_t)value); +} + +#else + +#error "No atomics" + +#endif diff --git a/src/binjnes.c b/src/binjnes.c index b6252aa..0411d7e 100644 --- a/src/binjnes.c +++ b/src/binjnes.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "sokol/sokol_app.h" #include "sokol/sokol_audio.h" @@ -73,7 +72,7 @@ static bool s_emulator_done; static mutex s_event_mtx; static sapp_event s_events[MAX_EVENT_COUNT]; static size_t s_event_count; -static atomic_bool s_running = true; +static AtomicBool s_running = true; static f64 s_frame_duration; static const char *s_rom_filename; @@ -908,7 +907,7 @@ static void handle_events(void) { static int emulator_thread(void *arg) { init_emulator(); set_status_text("Loaded %s", s_rom_filename); - while (atomic_load(&s_running)) { + while (atomic_load_bool(&s_running)) { if (!s_paused && s_fast_forward) { handle_events(); f64 delta_sec = 1.f / 60.f; @@ -1003,7 +1002,7 @@ static void frame(void) { } static void cleanup(void) { - atomic_store(&s_running, false); + atomic_store_bool(&s_running, false); // Make sure the emulator thread isn't waiting for the next frame. mutex_lock(&s_frame_begin_mtx);