mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-09-01 03:33:08 +02:00
Don't use atomics in libretro builds without multithreading support
This commit is contained in:
parent
8056cb3774
commit
0d035702a1
1 changed files with 63 additions and 11 deletions
74
src/core.cpp
74
src/core.cpp
|
@ -68,8 +68,60 @@ struct lock_guard {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T> struct atomic {
|
||||||
|
#ifdef MKXPZ_HAVE_THREADED_AUDIO
|
||||||
|
std::atomic<T> atom;
|
||||||
|
#else
|
||||||
|
T atom;
|
||||||
|
#endif // MKXPZ_HAVE_THREADED_AUDIO
|
||||||
|
|
||||||
|
atomic() {}
|
||||||
|
|
||||||
|
atomic(T value) : atom(value) {}
|
||||||
|
|
||||||
|
atomic(const struct atomic &guard) = delete;
|
||||||
|
|
||||||
|
atomic(struct atomic &&guard) noexcept = delete;
|
||||||
|
|
||||||
|
struct atomic &operator=(const struct atomic &guard) = delete;
|
||||||
|
|
||||||
|
struct atomic &operator=(struct atomic &&guard) noexcept = delete;
|
||||||
|
|
||||||
|
T load_relaxed() const noexcept {
|
||||||
|
#ifdef MKXPZ_HAVE_THREADED_AUDIO
|
||||||
|
return atom.load(std::memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
return atom;
|
||||||
|
#endif // MKXPZ_HAVE_THREADED_AUDIO
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T() const noexcept {
|
||||||
|
#ifdef MKXPZ_HAVE_THREADED_AUDIO
|
||||||
|
return atom.load(std::memory_order_seq_cst);
|
||||||
|
#else
|
||||||
|
return atom;
|
||||||
|
#endif // MKXPZ_HAVE_THREADED_AUDIO
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator=(T value) noexcept {
|
||||||
|
#ifdef MKXPZ_HAVE_THREADED_AUDIO
|
||||||
|
atom.store(value, std::memory_order_seq_cst);
|
||||||
|
#else
|
||||||
|
atom = value;
|
||||||
|
#endif // MKXPZ_HAVE_THREADED_AUDIO
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator+=(T value) noexcept {
|
||||||
|
#ifdef MKXPZ_HAVE_THREADED_AUDIO
|
||||||
|
atom.fetch_add(value, std::memory_order_seq_cst);
|
||||||
|
#else
|
||||||
|
atom += value;
|
||||||
|
#endif // MKXPZ_HAVE_THREADED_AUDIO
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static uint64_t frame_count;
|
static uint64_t frame_count;
|
||||||
static std::atomic<uint64_t> frame_time;
|
static struct atomic<uint64_t> frame_time;
|
||||||
static uint64_t frame_time_remainder;
|
static uint64_t frame_time_remainder;
|
||||||
static uint64_t retro_run_count;
|
static uint64_t retro_run_count;
|
||||||
|
|
||||||
|
@ -89,14 +141,14 @@ static retro_system_av_info av_info;
|
||||||
static struct retro_audio_callback audio_callback;
|
static struct retro_audio_callback audio_callback;
|
||||||
static struct retro_frame_time_callback frame_time_callback = {
|
static struct retro_frame_time_callback frame_time_callback = {
|
||||||
.callback = [](retro_usec_t delta) {
|
.callback = [](retro_usec_t delta) {
|
||||||
frame_time.fetch_add(delta, std::memory_order_seq_cst);
|
frame_time += delta;
|
||||||
frame_time_remainder += delta;
|
frame_time_remainder += delta;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
static std::mutex threaded_audio_mutex;
|
static std::mutex threaded_audio_mutex;
|
||||||
static bool threaded_audio_enabled = false;
|
static bool threaded_audio_enabled = false;
|
||||||
static bool frame_time_callback_enabled = false;
|
static bool frame_time_callback_enabled = false;
|
||||||
static std::atomic<bool> shared_state_initialized(false);
|
static struct atomic<bool> shared_state_initialized(false);
|
||||||
|
|
||||||
namespace mkxp_retro {
|
namespace mkxp_retro {
|
||||||
retro_log_printf_t log_printf;
|
retro_log_printf_t log_printf;
|
||||||
|
@ -110,7 +162,7 @@ namespace mkxp_retro {
|
||||||
bool input_polled;
|
bool input_polled;
|
||||||
|
|
||||||
uint64_t get_ticks() noexcept {
|
uint64_t get_ticks() noexcept {
|
||||||
return frame_time.load(std::memory_order_seq_cst) / 1000;
|
return frame_time / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
double get_refresh_rate() noexcept {
|
double get_refresh_rate() noexcept {
|
||||||
|
@ -204,7 +256,7 @@ SANDBOX_COROUTINE(main,
|
||||||
)
|
)
|
||||||
|
|
||||||
static void deinit_sandbox() {
|
static void deinit_sandbox() {
|
||||||
shared_state_initialized.store(false, std::memory_order_seq_cst);
|
shared_state_initialized = false;
|
||||||
struct lock_guard guard(threaded_audio_mutex);
|
struct lock_guard guard(threaded_audio_mutex);
|
||||||
|
|
||||||
if (sound_buf != NULL) {
|
if (sound_buf != NULL) {
|
||||||
|
@ -348,7 +400,7 @@ static bool init_sandbox() {
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_count = 0;
|
frame_count = 0;
|
||||||
frame_time.store(0, std::memory_order_seq_cst);
|
frame_time = 0;
|
||||||
frame_time_remainder = 0;
|
frame_time_remainder = 0;
|
||||||
retro_run_count = 0;
|
retro_run_count = 0;
|
||||||
|
|
||||||
|
@ -448,16 +500,16 @@ extern "C" RETRO_API void retro_run() {
|
||||||
|
|
||||||
if (!frame_time_callback_enabled) {
|
if (!frame_time_callback_enabled) {
|
||||||
uint64_t reference = 1000000 / av_info.timing.fps;
|
uint64_t reference = 1000000 / av_info.timing.fps;
|
||||||
frame_time.fetch_add(reference, std::memory_order_seq_cst);
|
frame_time += reference;
|
||||||
frame_time_remainder += reference;
|
frame_time_remainder += reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
input_polled = false;
|
input_polled = false;
|
||||||
|
|
||||||
// We deferred initializing the shared state since the OpenGL symbols aren't available until the first call to `retro_run()`
|
// We deferred initializing the shared state since the OpenGL symbols aren't available until the first call to `retro_run()`
|
||||||
if (!shared_state_initialized.load(std::memory_order_relaxed)) {
|
if (!shared_state_initialized.load_relaxed()) {
|
||||||
SharedState::initInstance(&thread_data.get());
|
SharedState::initInstance(&thread_data.get());
|
||||||
shared_state_initialized.store(true, std::memory_order_seq_cst);
|
shared_state_initialized = true;
|
||||||
} else if (hw_render.context_type != RETRO_HW_CONTEXT_NONE && (should_render || (!dupe_supported && mkxp_retro::sandbox.has_value()))) {
|
} else if (hw_render.context_type != RETRO_HW_CONTEXT_NONE && (should_render || (!dupe_supported && mkxp_retro::sandbox.has_value()))) {
|
||||||
glState.reset();
|
glState.reset();
|
||||||
}
|
}
|
||||||
|
@ -602,13 +654,13 @@ extern "C" RETRO_API bool retro_load_game(const struct retro_game_info *info) {
|
||||||
|
|
||||||
#ifdef MKXPZ_HAVE_THREADED_AUDIO
|
#ifdef MKXPZ_HAVE_THREADED_AUDIO
|
||||||
audio_callback.callback = []() {
|
audio_callback.callback = []() {
|
||||||
if (!shared_state_initialized.load(std::memory_order_seq_cst)) {
|
if (!shared_state_initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lock_guard guard(threaded_audio_mutex);
|
struct lock_guard guard(threaded_audio_mutex);
|
||||||
|
|
||||||
if (!shared_state_initialized.load(std::memory_order_seq_cst)) {
|
if (!shared_state_initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue