From dd51566d3b37a3e0b4d522c2b777ee127fe9a420 Mon Sep 17 00:00:00 2001 From: "E. Melucci" Date: Thu, 27 Jan 2022 15:08:07 +0100 Subject: [PATCH] Rebase on top of FluidSynth 2.2.5 Signed-off-by: E. Melucci --- 0001-solidsynth-patchset.patch | 1538 ++++++++++++++++---------------- 1 file changed, 774 insertions(+), 764 deletions(-) diff --git a/0001-solidsynth-patchset.patch b/0001-solidsynth-patchset.patch index 1446998..27d7988 100644 --- a/0001-solidsynth-patchset.patch +++ b/0001-solidsynth-patchset.patch @@ -1,5 +1,5 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index d0293363..24355e41 100644 +index 93000f71..3d2a7665 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,7 @@ option ( BUILD_SHARED_LIBS "Build a shared object or DLL" on ) @@ -20,7 +20,7 @@ index d0293363..24355e41 100644 option ( enable-pulseaudio "compile PulseAudio support (if it is available)" on ) option ( enable-readline "compile readline lib line editing (if it is available)" on ) option ( enable-threads "enable multi-threading support (such as parallel voice synthesis)" on ) -@@ -130,7 +130,7 @@ mark_as_advanced ( LIB_SUFFIX ) +@@ -131,7 +131,7 @@ mark_as_advanced ( LIB_SUFFIX ) set(CMAKE_C_STANDARD 90) # the default C++ standard to use for all targets @@ -29,7 +29,7 @@ index d0293363..24355e41 100644 # whether to use gnu extensions set(CMAKE_CXX_EXTENSIONS OFF) -@@ -183,6 +183,7 @@ check_include_file ( pthread.h HAVE_PTHREAD_H ) +@@ -184,6 +184,7 @@ check_include_file ( pthread.h HAVE_PTHREAD_H ) check_include_file ( signal.h HAVE_SIGNAL_H ) check_include_file ( getopt.h HAVE_GETOPT_H ) check_include_file ( stdint.h HAVE_STDINT_H ) @@ -37,7 +37,7 @@ index d0293363..24355e41 100644 check_type_size ( "long long" LONG_LONG ) if ( NOT HAVE_LONG_LONG AND NOT MSVC) message ( FATAL_ERROR "Your compiler does not support intrinsic type 'long long'. Unable to compile fluidsynth." ) -@@ -487,37 +488,9 @@ if ( ASTYLE ) +@@ -492,38 +493,9 @@ if ( ASTYLE ) ) endif(ASTYLE) @@ -68,6 +68,7 @@ index d0293363..24355e41 100644 - - # Mandatory libraries: glib and gthread - pkg_check_modules ( GLIB REQUIRED glib-2.0>=2.6.5 gthread-2.0>=2.6.5 ) +- list( APPEND PC_REQUIRES_PRIV "glib-2.0" "gthread-2.0") - - if ( GLIB_glib-2.0_VERSION AND GLIB_glib-2.0_VERSION VERSION_LESS "2.26.0" ) - message ( WARNING "Your version of glib is very old. This may cause problems with fluidsynth's sample cache on Windows. Consider updating to glib 2.26 or newer!" ) @@ -76,7 +77,16 @@ index d0293363..24355e41 100644 include ( UnsetPkgConfig ) # Optional features -@@ -781,7 +754,6 @@ configure_file ( ${CMAKE_SOURCE_DIR}/src/config.cmake +@@ -687,7 +659,7 @@ else(NOT enable-pkgconfig) + endif ( READLINE_FOUND ) + endif ( enable-readline ) + +-endif(NOT enable-pkgconfig) ++endif(enable-pkgconfig) + + unset ( AUFILE_SUPPORT CACHE ) + if ( enable-aufile ) +@@ -827,7 +799,6 @@ configure_file ( ${CMAKE_SOURCE_DIR}/src/config.cmake # Setup linker directories NOW, as the command will apply only to targets created after it has been called. link_directories ( @@ -85,7 +95,7 @@ index d0293363..24355e41 100644 ${JACK_LIBRARY_DIRS} ${ALSA_LIBRARY_DIRS} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt -index e913cb21..053ac962 100644 +index 2803ca88..804d18de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,7 +35,6 @@ include_directories ( @@ -138,7 +148,7 @@ index 1d4baaed..9295b77d 100644 /** diff --git a/src/config.cmake b/src/config.cmake -index 946421b6..bdbd3fd5 100644 +index d3aaf701..ba6e6b3d 100644 --- a/src/config.cmake +++ b/src/config.cmake @@ -124,6 +124,9 @@ @@ -152,10 +162,10 @@ index 946421b6..bdbd3fd5 100644 #cmakedefine HAVE_INETNTOP @HAVE_INETNTOP@ diff --git a/src/drivers/fluid_oss.c b/src/drivers/fluid_oss.c -index 0cd359d5..dc6a7317 100644 +index 9f27735d..ed82d8fc 100644 --- a/src/drivers/fluid_oss.c +++ b/src/drivers/fluid_oss.c -@@ -540,7 +540,7 @@ fluid_oss_audio_run(void *d) +@@ -562,7 +562,7 @@ fluid_oss_audio_run(void *d) if(write(dev->dspfd, buffer, dev->buffer_byte_size) < 0) { FLUID_LOG(FLUID_ERR, "Error writing to OSS sound device: %s", @@ -164,7 +174,7 @@ index 0cd359d5..dc6a7317 100644 break; } } -@@ -580,7 +580,7 @@ fluid_oss_audio_run2(void *d) +@@ -602,7 +602,7 @@ fluid_oss_audio_run2(void *d) if(write(dev->dspfd, buffer, dev->buffer_byte_size) < 0) { FLUID_LOG(FLUID_ERR, "Error writing to OSS sound device: %s", @@ -187,10 +197,10 @@ index f7a74dea..d30c2994 100644 FLUID_FREE(media_role); /* -- free media_role string */ diff --git a/src/fluidsynth.c b/src/fluidsynth.c -index 6c1132f4..997626fb 100644 +index 55d1000f..28a1850f 100644 --- a/src/fluidsynth.c +++ b/src/fluidsynth.c -@@ -855,12 +855,6 @@ int main(int argc, char **argv) +@@ -894,12 +894,6 @@ int main(int argc, char **argv) { config_file = fluid_get_sysconf(buf, sizeof(buf)); } @@ -204,10 +214,10 @@ index 6c1132f4..997626fb 100644 /* Handle set commands before creating the synth */ diff --git a/src/midi/fluid_midi.c b/src/midi/fluid_midi.c -index 113c1595..7194c0cf 100644 +index cab651b8..2ef0d709 100644 --- a/src/midi/fluid_midi.c +++ b/src/midi/fluid_midi.c -@@ -2163,7 +2163,8 @@ fluid_player_callback(void *data, unsigned int msec) +@@ -2191,7 +2191,8 @@ fluid_player_callback(void *data, unsigned int msec) while(loadnextfile); /* do not update the status if the player has been stopped already */ @@ -217,7 +227,7 @@ index 113c1595..7194c0cf 100644 return 1; } -@@ -2245,7 +2246,8 @@ int fluid_player_seek(fluid_player_t *player, int ticks) +@@ -2283,7 +2284,8 @@ int fluid_player_seek(fluid_player_t *player, int ticks) if(fluid_player_get_status(player) == FLUID_PLAYER_PLAYING) { @@ -228,7 +238,7 @@ index 113c1595..7194c0cf 100644 // new seek position has been set, as no previous seek was in progress return FLUID_OK; diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c -index fc0d35fc..f754c1bc 100644 +index b6a8c3ee..81273b06 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -631,7 +631,8 @@ new_fluid_synth(fluid_settings_t *settings) @@ -243,532 +253,532 @@ index fc0d35fc..f754c1bc 100644 } diff --git a/src/utils/fluid_atomics.c b/src/utils/fluid_atomics.c new file mode 100644 -index 00000000..6bb28c25 +index 00000000..7532e45e --- /dev/null +++ b/src/utils/fluid_atomics.c @@ -0,0 +1,303 @@ -+/** -+ * MSVC doesn't support C11 atomics (yet) -+ * This whole hack is hopefully provisional -+ */ -+ -+#ifdef _MSC_VER -+ -+#include -+#include "fluid_atomics.h" -+ -+#ifdef _WIN32 -+#pragma warning(disable : 4800) -+ -+#include -+ -+#define WIN32_LEAN_AND_MEAN -+#include -+ -+#ifndef _WIN64 -+/* The following is needed for x86 */ -+#define _InterlockedIncrement64 InterlockedIncrement64 -+#define _InterlockedDecrement64 InterlockedDecrement64 -+#define _InterlockedExchangeAdd64 InterlockedExchangeAdd64 -+#define _InterlockedOr64 InterlockedOr64 -+#define _InterlockedAnd64 InterlockedAnd64 -+#define _InterlockedXor64 InterlockedXor64 -+#define _InterlockedExchange64 InterlockedExchange64 -+#endif -+#endif -+ -+int8_t zenny_atomic_fetch_add8(volatile atomic_schar *object, int8_t operand) -+{ -+ int8_t expected = *object; -+ int8_t desired; -+ bool success; -+ -+ do -+ { -+ desired = expected + operand; -+ } while ((success = zenny_atomic_compare_exchange8(object, &expected, desired)), -+ (success ? (void)0 : YieldProcessor()), -+ !success); -+ -+ return expected; -+} -+ -+int16_t zenny_atomic_fetch_add16(volatile atomic_short *object, int16_t operand) -+{ -+ int16_t expected = *object; -+ int16_t desired; -+ bool success; -+ -+ do -+ { -+ desired = expected + operand; -+ } while ((success = zenny_atomic_compare_exchange16(object, &expected, desired)), -+ (success ? (void)0 : YieldProcessor()), -+ !success); -+ -+ return expected; -+} -+ -+int32_t zenny_atomic_fetch_add32(volatile atomic_long *object, int32_t operand) -+{ -+ int32_t expected = *object; -+ int32_t desired; -+ bool success; -+ -+ do -+ { -+ desired = expected + operand; -+ } while ((success = zenny_atomic_compare_exchange32(object, &expected, desired)), -+ (success ? (void)0 : YieldProcessor()), -+ !success); -+ -+ return expected; -+} -+ -+int64_t zenny_atomic_fetch_add64(volatile atomic_llong *object, int64_t operand) -+{ -+ int64_t expected = *object; -+ int64_t desired; -+ bool success; -+ -+ do -+ { -+ desired = expected + operand; -+ } while ((success = zenny_atomic_compare_exchange64(object, &expected, desired)), -+ (success ? (void)0 : YieldProcessor()), -+ !success); -+ -+ return expected; -+} -+ -+int8_t zenny_atomic_fetch_sub8(volatile atomic_schar *object, int8_t operand) -+{ -+ int8_t expected = *object; -+ int8_t desired; -+ bool success; -+ -+ do -+ { -+ desired = expected - operand; -+ } while ((success = zenny_atomic_compare_exchange8(object, &expected, desired)), -+ (success ? (void)0 : YieldProcessor()), -+ !success); -+ -+ return expected; -+} -+ -+int16_t zenny_atomic_fetch_sub16(volatile atomic_short *object, int16_t operand) -+{ -+ int16_t expected = *object; -+ int16_t desired; -+ bool success; -+ -+ do -+ { -+ desired = expected - operand; -+ } while ((success = zenny_atomic_compare_exchange16(object, &expected, desired)), -+ (success ? (void)0 : YieldProcessor()), -+ !success); -+ -+ return expected; -+} -+ -+int32_t zenny_atomic_fetch_sub32(volatile atomic_long *object, int32_t operand) -+{ -+ int32_t expected = *object; -+ int32_t desired; -+ bool success; -+ -+ do -+ { -+ desired = expected - operand; -+ } while ((success = zenny_atomic_compare_exchange32(object, &expected, desired)), -+ (success ? (void)0 : YieldProcessor()), -+ !success); -+ -+ return expected; -+} -+ -+int64_t zenny_atomic_fetch_sub64(volatile atomic_llong *object, int64_t operand) -+{ -+ int64_t expected = *object; -+ int64_t desired; -+ bool success; -+ -+ do -+ { -+ desired = expected - operand; -+ } while ((success = zenny_atomic_compare_exchange64(object, &expected, desired)), -+ (success ? (void)0 : YieldProcessor()), -+ !success); -+ -+ return expected; -+} -+ -+int8_t zenny_atomic_fetch_or8(volatile atomic_schar *object, int8_t operand) -+{ -+ return _InterlockedOr8(object, operand); -+} -+ -+int16_t zenny_atomic_fetch_or16(volatile atomic_short *object, int16_t operand) -+{ -+ return _InterlockedOr16(object, operand); -+} -+ -+int32_t zenny_atomic_fetch_or32(volatile atomic_long *object, int32_t operand) -+{ -+ return _InterlockedOr(object, operand); -+} -+ -+int64_t zenny_atomic_fetch_or64(volatile atomic_llong *object, int64_t operand) -+{ -+ return _InterlockedOr64(object, operand); -+} -+ -+int8_t zenny_atomic_fetch_xor8(volatile atomic_schar *object, int8_t operand) -+{ -+ return _InterlockedXor8(object, operand); -+} -+ -+int16_t zenny_atomic_fetch_xor16(volatile atomic_short *object, int16_t operand) -+{ -+ return _InterlockedXor16(object, operand); -+} -+ -+int32_t zenny_atomic_fetch_xor32(volatile atomic_long *object, int32_t operand) -+{ -+ return _InterlockedXor(object, operand); -+} -+ -+int64_t zenny_atomic_fetch_xor64(volatile atomic_llong *object, int64_t operand) -+{ -+ return _InterlockedXor64(object, operand); -+} -+ -+int8_t zenny_atomic_fetch_and8(volatile atomic_schar *object, int8_t operand) -+{ -+ return _InterlockedAnd8(object, operand); -+} -+ -+int16_t zenny_atomic_fetch_and16(volatile atomic_short *object, int16_t operand) -+{ -+ return _InterlockedAnd16(object, operand); -+} -+ -+int32_t zenny_atomic_fetch_and32(volatile atomic_long *object, int32_t operand) -+{ -+ return _InterlockedAnd(object, operand); -+} -+ -+int64_t zenny_atomic_fetch_and64(volatile atomic_llong *object, int64_t operand) -+{ -+ return _InterlockedAnd64(object, operand); -+} -+ -+int8_t zenny_atomic_exchange8(volatile atomic_schar *object, int8_t desired) -+{ -+ return _InterlockedExchange8(object, desired); -+} -+ -+int16_t zenny_atomic_exchange16(volatile atomic_short *object, int16_t desired) -+{ -+ return _InterlockedExchange16(object, desired); -+} -+ -+int32_t zenny_atomic_exchange32(volatile atomic_long *object, int32_t desired) -+{ -+ return _InterlockedExchange(object, desired); -+} -+ -+int64_t zenny_atomic_exchange64(volatile atomic_llong *object, int64_t desired) -+{ -+ return _InterlockedExchange64(object, desired); -+} -+ -+bool zenny_atomic_compare_exchange8(volatile atomic_schar *object, int8_t *expected, int8_t desired) -+{ -+ int8_t comparand = *expected; -+ const int8_t dstValue = _InterlockedCompareExchange8(object, desired, comparand); -+ bool success = dstValue == comparand; -+ if (!success) -+ *expected = dstValue; -+ -+ return success; -+} -+ -+bool zenny_atomic_compare_exchange16(volatile atomic_short *object, int16_t *expected, int16_t desired) -+{ -+ int16_t comparand = *expected; -+ const int16_t dstValue = _InterlockedCompareExchange16(object, desired, comparand); -+ bool success = dstValue == comparand; -+ if (!success) -+ *expected = dstValue; -+ -+ return success; -+} -+ -+bool zenny_atomic_compare_exchange32(volatile atomic_long *object, int32_t *expected, int32_t desired) -+{ -+ int32_t comparand = *expected; -+ int32_t dstValue = _InterlockedCompareExchange(object, desired, comparand); -+ bool success = dstValue == comparand; -+ if (!success) -+ *expected = dstValue; -+ -+ return success; -+} -+ -+bool zenny_atomic_compare_exchange64(volatile atomic_llong *object, int64_t *expected, int64_t desired) -+{ -+ int64_t comparand = *expected; -+ int64_t dstValue = _InterlockedCompareExchange64(object, desired, comparand); -+ bool success = dstValue == comparand; -+ if (!success) -+ *expected = dstValue; -+ -+ return success; -+} -+ -+bool atomic_flag_test_and_set(volatile atomic_flag *flag) -+{ -+ return _InterlockedExchange8((volatile char *)flag, 1) == 1; -+} -+ -+bool atomic_flag_test_and_set_explicit(volatile atomic_flag *object, memory_order order) -+{ -+ return atomic_flag_test_and_set(object); -+} -+ -+void atomic_flag_clear(volatile atomic_flag *flag) -+{ -+ _InterlockedExchange8((volatile char *)flag, 0); -+} -+ -+void atomic_flag_clear_explicit(volatile atomic_flag *object, memory_order order) -+{ -+ atomic_flag_clear(object); -+} -+ -+#endif ++/** ++ * MSVC doesn't support C11 atomics (yet) ++ * This whole hack is hopefully provisional ++ */ ++ ++#ifdef _MSC_VER ++ ++#include ++#include "fluid_atomics.h" ++ ++#ifdef _WIN32 ++#pragma warning(disable : 4800) ++ ++#include ++ ++#define WIN32_LEAN_AND_MEAN ++#include ++ ++#ifndef _WIN64 ++/* The following is needed for x86 */ ++#define _InterlockedIncrement64 InterlockedIncrement64 ++#define _InterlockedDecrement64 InterlockedDecrement64 ++#define _InterlockedExchangeAdd64 InterlockedExchangeAdd64 ++#define _InterlockedOr64 InterlockedOr64 ++#define _InterlockedAnd64 InterlockedAnd64 ++#define _InterlockedXor64 InterlockedXor64 ++#define _InterlockedExchange64 InterlockedExchange64 ++#endif ++#endif ++ ++int8_t zenny_atomic_fetch_add8(volatile atomic_schar *object, int8_t operand) ++{ ++ int8_t expected = *object; ++ int8_t desired; ++ bool success; ++ ++ do ++ { ++ desired = expected + operand; ++ } while ((success = zenny_atomic_compare_exchange8(object, &expected, desired)), ++ (success ? (void)0 : YieldProcessor()), ++ !success); ++ ++ return expected; ++} ++ ++int16_t zenny_atomic_fetch_add16(volatile atomic_short *object, int16_t operand) ++{ ++ int16_t expected = *object; ++ int16_t desired; ++ bool success; ++ ++ do ++ { ++ desired = expected + operand; ++ } while ((success = zenny_atomic_compare_exchange16(object, &expected, desired)), ++ (success ? (void)0 : YieldProcessor()), ++ !success); ++ ++ return expected; ++} ++ ++int32_t zenny_atomic_fetch_add32(volatile atomic_long *object, int32_t operand) ++{ ++ int32_t expected = *object; ++ int32_t desired; ++ bool success; ++ ++ do ++ { ++ desired = expected + operand; ++ } while ((success = zenny_atomic_compare_exchange32(object, &expected, desired)), ++ (success ? (void)0 : YieldProcessor()), ++ !success); ++ ++ return expected; ++} ++ ++int64_t zenny_atomic_fetch_add64(volatile atomic_llong *object, int64_t operand) ++{ ++ int64_t expected = *object; ++ int64_t desired; ++ bool success; ++ ++ do ++ { ++ desired = expected + operand; ++ } while ((success = zenny_atomic_compare_exchange64(object, &expected, desired)), ++ (success ? (void)0 : YieldProcessor()), ++ !success); ++ ++ return expected; ++} ++ ++int8_t zenny_atomic_fetch_sub8(volatile atomic_schar *object, int8_t operand) ++{ ++ int8_t expected = *object; ++ int8_t desired; ++ bool success; ++ ++ do ++ { ++ desired = expected - operand; ++ } while ((success = zenny_atomic_compare_exchange8(object, &expected, desired)), ++ (success ? (void)0 : YieldProcessor()), ++ !success); ++ ++ return expected; ++} ++ ++int16_t zenny_atomic_fetch_sub16(volatile atomic_short *object, int16_t operand) ++{ ++ int16_t expected = *object; ++ int16_t desired; ++ bool success; ++ ++ do ++ { ++ desired = expected - operand; ++ } while ((success = zenny_atomic_compare_exchange16(object, &expected, desired)), ++ (success ? (void)0 : YieldProcessor()), ++ !success); ++ ++ return expected; ++} ++ ++int32_t zenny_atomic_fetch_sub32(volatile atomic_long *object, int32_t operand) ++{ ++ int32_t expected = *object; ++ int32_t desired; ++ bool success; ++ ++ do ++ { ++ desired = expected - operand; ++ } while ((success = zenny_atomic_compare_exchange32(object, &expected, desired)), ++ (success ? (void)0 : YieldProcessor()), ++ !success); ++ ++ return expected; ++} ++ ++int64_t zenny_atomic_fetch_sub64(volatile atomic_llong *object, int64_t operand) ++{ ++ int64_t expected = *object; ++ int64_t desired; ++ bool success; ++ ++ do ++ { ++ desired = expected - operand; ++ } while ((success = zenny_atomic_compare_exchange64(object, &expected, desired)), ++ (success ? (void)0 : YieldProcessor()), ++ !success); ++ ++ return expected; ++} ++ ++int8_t zenny_atomic_fetch_or8(volatile atomic_schar *object, int8_t operand) ++{ ++ return _InterlockedOr8(object, operand); ++} ++ ++int16_t zenny_atomic_fetch_or16(volatile atomic_short *object, int16_t operand) ++{ ++ return _InterlockedOr16(object, operand); ++} ++ ++int32_t zenny_atomic_fetch_or32(volatile atomic_long *object, int32_t operand) ++{ ++ return _InterlockedOr(object, operand); ++} ++ ++int64_t zenny_atomic_fetch_or64(volatile atomic_llong *object, int64_t operand) ++{ ++ return _InterlockedOr64(object, operand); ++} ++ ++int8_t zenny_atomic_fetch_xor8(volatile atomic_schar *object, int8_t operand) ++{ ++ return _InterlockedXor8(object, operand); ++} ++ ++int16_t zenny_atomic_fetch_xor16(volatile atomic_short *object, int16_t operand) ++{ ++ return _InterlockedXor16(object, operand); ++} ++ ++int32_t zenny_atomic_fetch_xor32(volatile atomic_long *object, int32_t operand) ++{ ++ return _InterlockedXor(object, operand); ++} ++ ++int64_t zenny_atomic_fetch_xor64(volatile atomic_llong *object, int64_t operand) ++{ ++ return _InterlockedXor64(object, operand); ++} ++ ++int8_t zenny_atomic_fetch_and8(volatile atomic_schar *object, int8_t operand) ++{ ++ return _InterlockedAnd8(object, operand); ++} ++ ++int16_t zenny_atomic_fetch_and16(volatile atomic_short *object, int16_t operand) ++{ ++ return _InterlockedAnd16(object, operand); ++} ++ ++int32_t zenny_atomic_fetch_and32(volatile atomic_long *object, int32_t operand) ++{ ++ return _InterlockedAnd(object, operand); ++} ++ ++int64_t zenny_atomic_fetch_and64(volatile atomic_llong *object, int64_t operand) ++{ ++ return _InterlockedAnd64(object, operand); ++} ++ ++int8_t zenny_atomic_exchange8(volatile atomic_schar *object, int8_t desired) ++{ ++ return _InterlockedExchange8(object, desired); ++} ++ ++int16_t zenny_atomic_exchange16(volatile atomic_short *object, int16_t desired) ++{ ++ return _InterlockedExchange16(object, desired); ++} ++ ++int32_t zenny_atomic_exchange32(volatile atomic_long *object, int32_t desired) ++{ ++ return _InterlockedExchange(object, desired); ++} ++ ++int64_t zenny_atomic_exchange64(volatile atomic_llong *object, int64_t desired) ++{ ++ return _InterlockedExchange64(object, desired); ++} ++ ++bool zenny_atomic_compare_exchange8(volatile atomic_schar *object, int8_t *expected, int8_t desired) ++{ ++ int8_t comparand = *expected; ++ const int8_t dstValue = _InterlockedCompareExchange8(object, desired, comparand); ++ bool success = dstValue == comparand; ++ if (!success) ++ *expected = dstValue; ++ ++ return success; ++} ++ ++bool zenny_atomic_compare_exchange16(volatile atomic_short *object, int16_t *expected, int16_t desired) ++{ ++ int16_t comparand = *expected; ++ const int16_t dstValue = _InterlockedCompareExchange16(object, desired, comparand); ++ bool success = dstValue == comparand; ++ if (!success) ++ *expected = dstValue; ++ ++ return success; ++} ++ ++bool zenny_atomic_compare_exchange32(volatile atomic_long *object, int32_t *expected, int32_t desired) ++{ ++ int32_t comparand = *expected; ++ int32_t dstValue = _InterlockedCompareExchange(object, desired, comparand); ++ bool success = dstValue == comparand; ++ if (!success) ++ *expected = dstValue; ++ ++ return success; ++} ++ ++bool zenny_atomic_compare_exchange64(volatile atomic_llong *object, int64_t *expected, int64_t desired) ++{ ++ int64_t comparand = *expected; ++ int64_t dstValue = _InterlockedCompareExchange64(object, desired, comparand); ++ bool success = dstValue == comparand; ++ if (!success) ++ *expected = dstValue; ++ ++ return success; ++} ++ ++bool atomic_flag_test_and_set(volatile atomic_flag *flag) ++{ ++ return _InterlockedExchange8((volatile char *)flag, 1) == 1; ++} ++ ++bool atomic_flag_test_and_set_explicit(volatile atomic_flag *object, memory_order order) ++{ ++ return atomic_flag_test_and_set(object); ++} ++ ++void atomic_flag_clear(volatile atomic_flag *flag) ++{ ++ _InterlockedExchange8((volatile char *)flag, 0); ++} ++ ++void atomic_flag_clear_explicit(volatile atomic_flag *object, memory_order order) ++{ ++ atomic_flag_clear(object); ++} ++ ++#endif diff --git a/src/utils/fluid_atomics.h b/src/utils/fluid_atomics.h new file mode 100644 -index 00000000..bbcd7b5a +index 00000000..f7d6aef0 --- /dev/null +++ b/src/utils/fluid_atomics.h @@ -0,0 +1,213 @@ -+#ifndef _FLUID_ATOMICS_H -+#define _FLUID_ATOMICS_H -+ -+/** -+ * Original code from https://github.com/zenny-chen/simple-stdatomic-for-VS-Clang -+ */ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#if defined(_MSC_VER) -+ -+#include -+#include -+#include -+ -+#define ATOMIC_VAR_INIT(value) (value) -+#define atomic_init(object, value) (void)(*(object) = (value)) -+ -+#ifdef __GNUC__ -+#define atomic_store(object, desired) (void)(*(volatile typeof(*(object)) *)(object) = (desired)) -+#define atomic_load(object) *(volatile typeof(*(object)) *)(object) -+#else -+#define atomic_store(object, desired) (void)(*(object) = (desired)) -+#define atomic_load(object) *(object) -+#endif -+ -+#define ATOMIC_FLAG_INIT \ -+ { \ -+ 0 \ -+ } -+ -+typedef enum memory_order -+{ -+ memory_order_relaxed, -+ memory_order_consume, -+ memory_order_acquire, -+ memory_order_release, -+ memory_order_acq_rel, -+ memory_order_seq_cst -+} memory_order; -+ -+#define atomic_load_explicit(object, order) atomic_load(object) -+#define atomic_store_explicit(object, desired, order) atomic_store((object), (desired)) -+ -+ -+typedef struct atomic_flag -+{ -+ bool _Value; -+} atomic_flag; -+ -+typedef bool atomic_bool; -+typedef char atomic_char; -+typedef unsigned char atomic_uchar; -+typedef signed char atomic_schar; -+typedef short atomic_short; -+typedef unsigned short atomic_ushort; -+typedef int atomic_int; -+typedef unsigned atomic_uint; -+typedef long atomic_long; -+typedef unsigned long atomic_ulong; -+typedef long long atomic_llong; -+typedef unsigned long long atomic_ullong; -+typedef intptr_t atomic_intptr_t; -+typedef uintptr_t atomic_uintptr_t; -+typedef size_t atomic_size_t; -+typedef ptrdiff_t atomic_ptrdiff_t; -+typedef intmax_t atomic_intmax_t; -+typedef uintmax_t atomic_uintmax_t; -+typedef char16_t atomic_char16_t; -+typedef char32_t atomic_char32_t; -+typedef wchar_t atomic_wchar_t; -+ -+ -+extern bool atomic_flag_test_and_set(volatile atomic_flag *object); -+extern bool atomic_flag_test_and_set_explicit(volatile atomic_flag *object, memory_order order); -+ -+extern void atomic_flag_clear(volatile atomic_flag *object); -+extern void atomic_flag_clear_explicit(volatile atomic_flag *object, memory_order order); -+ -+ -+#define atomic_fetch_add(object, operand) \ -+ ((sizeof(*(object)) == 1) ? \ -+ zenny_atomic_fetch_add8((volatile atomic_schar *)(object), (int8_t)(operand)) : \ -+ ((sizeof(*(object)) == 2) ? \ -+ zenny_atomic_fetch_add16((volatile atomic_short *)(object), (int16_t)(operand)) : \ -+ ((sizeof(*(object)) == 4) ? \ -+ zenny_atomic_fetch_add32((volatile atomic_long *)(object), (int32_t)(operand)) : \ -+ zenny_atomic_fetch_add64((volatile atomic_llong *)(object), (int64_t)(operand))))) -+ -+#define atomic_fetch_add_explicit(object, operand, order) atomic_fetch_add((object), (operand)) -+ -+extern int8_t zenny_atomic_fetch_add8(volatile atomic_schar *object, int8_t operand); -+extern int16_t zenny_atomic_fetch_add16(volatile atomic_short *object, int16_t operand); -+extern int32_t zenny_atomic_fetch_add32(volatile atomic_long *object, int32_t operand); -+extern int64_t zenny_atomic_fetch_add64(volatile atomic_llong *object, int64_t operand); -+ -+ -+#define atomic_fetch_sub(object, operand) \ -+ ((sizeof(*(object)) == 1) ? \ -+ zenny_atomic_fetch_sub8((volatile atomic_schar *)(object), (int8_t)(operand)) : \ -+ ((sizeof(*(object)) == 2) ? \ -+ zenny_atomic_fetch_sub16((volatile atomic_short *)(object), (int16_t)(operand)) : \ -+ ((sizeof(*(object)) == 4) ? \ -+ zenny_atomic_fetch_sub32((volatile atomic_long *)(object), (int32_t)(operand)) : \ -+ zenny_atomic_fetch_sub64((volatile atomic_llong *)(object), (int64_t)(operand))))) -+ -+#define atomic_fetch_sub_explicit(object, operand, order) atomic_fetch_sub((object), (operand)) -+ -+extern int8_t zenny_atomic_fetch_sub8(volatile atomic_schar *object, int8_t operand); -+extern int16_t zenny_atomic_fetch_sub16(volatile atomic_short *object, int16_t operand); -+extern int32_t zenny_atomic_fetch_sub32(volatile atomic_long *object, int32_t operand); -+extern int64_t zenny_atomic_fetch_sub64(volatile atomic_llong *object, int64_t operand); -+ -+ -+#define atomic_fetch_or(object, operand) \ -+ ((sizeof(*(object)) == 1) ? \ -+ zenny_atomic_fetch_or8((volatile atomic_schar *)(object), (int8_t)(operand)) : \ -+ ((sizeof(*(object)) == 2) ? \ -+ zenny_atomic_fetch_or16((volatile atomic_short *)(object), (int16_t)(operand)) : \ -+ ((sizeof(*(object)) == 4) ? \ -+ zenny_atomic_fetch_or32((volatile atomic_long *)(object), (int32_t)(operand)) : \ -+ zenny_atomic_fetch_or64((volatile atomic_llong *)(object), (int64_t)(operand))))) -+ -+#define atomic_fetch_or_explicit(object, operand, order) atomic_fetch_or((object), (operand)) -+ -+extern int8_t zenny_atomic_fetch_or8(volatile atomic_schar *object, int8_t operand); -+extern int16_t zenny_atomic_fetch_or16(volatile atomic_short *object, int16_t operand); -+extern int32_t zenny_atomic_fetch_or32(volatile atomic_long *object, int32_t operand); -+extern int64_t zenny_atomic_fetch_or64(volatile atomic_llong *object, int64_t operand); -+ -+ -+#define atomic_fetch_xor(object, operand) \ -+ ((sizeof(*(object)) == 1) ? \ -+ zenny_atomic_fetch_xor8((volatile atomic_schar *)(object), (int8_t)(operand)) : \ -+ ((sizeof(*(object)) == 2) ? \ -+ zenny_atomic_fetch_xor16((volatile atomic_short *)(object), (int16_t)(operand)) : \ -+ ((sizeof(*(object)) == 4) ? \ -+ zenny_atomic_fetch_xor32((volatile atomic_long *)(object), (int32_t)(operand)) : \ -+ zenny_atomic_fetch_xor64((volatile atomic_llong *)(object), (int64_t)(operand))))) -+ -+#define atomic_fetch_xor_explicit(object, operand, order) atomic_fetch_xor((object), (operand)) -+ -+extern int8_t zenny_atomic_fetch_xor8(volatile atomic_schar *object, int8_t operand); -+extern int16_t zenny_atomic_fetch_xor16(volatile atomic_short *object, int16_t operand); -+extern int32_t zenny_atomic_fetch_xor32(volatile atomic_long *object, int32_t operand); -+extern int64_t zenny_atomic_fetch_xor64(volatile atomic_llong *object, int64_t operand); -+ -+ -+#define atomic_fetch_and(object, operand) \ -+ ((sizeof(*(object)) == 1) ? \ -+ zenny_atomic_fetch_and8((volatile atomic_schar *)(object), (int8_t)(operand)) : \ -+ ((sizeof(*(object)) == 2) ? \ -+ zenny_atomic_fetch_and16((volatile atomic_short *)(object), (int16_t)(operand)) : \ -+ ((sizeof(*(object)) == 4) ? \ -+ zenny_atomic_fetch_and32((volatile atomic_long *)(object), (int32_t)(operand)) : \ -+ zenny_atomic_fetch_and64((volatile atomic_llong *)(object), (int64_t)(operand))))) -+ -+#define atomic_fetch_and_explicit(object, operand, order) atomic_fetch_and((object), (operand)) -+ -+extern int8_t zenny_atomic_fetch_and8(volatile atomic_schar *object, int8_t operand); -+extern int16_t zenny_atomic_fetch_and16(volatile atomic_short *object, int16_t operand); -+extern int32_t zenny_atomic_fetch_and32(volatile atomic_long *object, int32_t operand); -+extern int64_t zenny_atomic_fetch_and64(volatile atomic_llong *object, int64_t operand); -+ -+ -+#define atomic_exchange(object, desired) \ -+ ((sizeof(*(object)) == 1) ? \ -+ zenny_atomic_exchange8((volatile atomic_schar *)(object), (int8_t)(desired)) : \ -+ ((sizeof(*(object)) == 2) ? \ -+ zenny_atomic_exchange16((volatile atomic_short *)(object), (int16_t)(desired)) : \ -+ ((sizeof(*(object)) == 4) ? \ -+ zenny_atomic_exchange32((volatile atomic_long *)(object), (int32_t)(desired)) : \ -+ zenny_atomic_exchange64((volatile atomic_llong *)(object), (int64_t)(desired))))) -+ -+#define atomic_exchange_explicit(object, desired, order) atomic_exchange((object), (desired)) -+ -+extern int8_t zenny_atomic_exchange8(volatile atomic_schar *object, int8_t desired); -+extern int16_t zenny_atomic_exchange16(volatile atomic_short *object, int16_t desired); -+extern int32_t zenny_atomic_exchange32(volatile atomic_long *object, int32_t desired); -+extern int64_t zenny_atomic_exchange64(volatile atomic_llong *object, int64_t desired); -+ -+ -+#define atomic_compare_exchange_strong(object, expected, desired) \ -+ (sizeof(*(object)) == 1 ? \ -+ zenny_atomic_compare_exchange8((volatile atomic_schar *)(object), (int8_t *)(expected), (int8_t)(desired)) : \ -+ (sizeof(*(object)) == 2 ? \ -+ zenny_atomic_compare_exchange16((volatile atomic_short *)(object), (int16_t *)(expected), (int16_t)(desired)) : \ -+ (sizeof(*(object)) == 4 ? \ -+ zenny_atomic_compare_exchange32((volatile atomic_long *)(object), (int32_t *)(expected), (int32_t)(desired)) : \ -+ zenny_atomic_compare_exchange64((volatile atomic_llong *)(object), (int64_t *)(expected), (int64_t)(desired))))) -+ -+#define atomic_compare_exchange_weak atomic_compare_exchange_strong -+ -+#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ -+ atomic_compare_exchange_strong((object), (expected), (desired)) -+#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ -+ atomic_compare_exchange_weak((object), (expected), (desired)) -+ -+extern bool zenny_atomic_compare_exchange8(volatile atomic_schar *object, int8_t *expected, int8_t desired); -+extern bool zenny_atomic_compare_exchange16(volatile atomic_short *object, int16_t *expected, int16_t desired); -+extern bool zenny_atomic_compare_exchange32(volatile atomic_long *object, int32_t *expected, int32_t desired); -+extern bool zenny_atomic_compare_exchange64(volatile atomic_llong *object, int64_t *expected, int64_t desired); -+ -+#endif // #if defined(_MSC_VER) -+ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ++#ifndef _FLUID_ATOMICS_H ++#define _FLUID_ATOMICS_H ++ ++/** ++ * Original code from https://github.com/zenny-chen/simple-stdatomic-for-VS-Clang ++ */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#if defined(_MSC_VER) ++ ++#include ++#include ++#include ++ ++#define ATOMIC_VAR_INIT(value) (value) ++#define atomic_init(object, value) (void)(*(object) = (value)) ++ ++#ifdef __GNUC__ ++#define atomic_store(object, desired) (void)(*(volatile typeof(*(object)) *)(object) = (desired)) ++#define atomic_load(object) *(volatile typeof(*(object)) *)(object) ++#else ++#define atomic_store(object, desired) (void)(*(object) = (desired)) ++#define atomic_load(object) *(object) ++#endif ++ ++#define ATOMIC_FLAG_INIT \ ++ { \ ++ 0 \ ++ } ++ ++typedef enum memory_order ++{ ++ memory_order_relaxed, ++ memory_order_consume, ++ memory_order_acquire, ++ memory_order_release, ++ memory_order_acq_rel, ++ memory_order_seq_cst ++} memory_order; ++ ++#define atomic_load_explicit(object, order) atomic_load(object) ++#define atomic_store_explicit(object, desired, order) atomic_store((object), (desired)) ++ ++ ++typedef struct atomic_flag ++{ ++ bool _Value; ++} atomic_flag; ++ ++typedef bool atomic_bool; ++typedef char atomic_char; ++typedef unsigned char atomic_uchar; ++typedef signed char atomic_schar; ++typedef short atomic_short; ++typedef unsigned short atomic_ushort; ++typedef int atomic_int; ++typedef unsigned atomic_uint; ++typedef long atomic_long; ++typedef unsigned long atomic_ulong; ++typedef long long atomic_llong; ++typedef unsigned long long atomic_ullong; ++typedef intptr_t atomic_intptr_t; ++typedef uintptr_t atomic_uintptr_t; ++typedef size_t atomic_size_t; ++typedef ptrdiff_t atomic_ptrdiff_t; ++typedef intmax_t atomic_intmax_t; ++typedef uintmax_t atomic_uintmax_t; ++typedef char16_t atomic_char16_t; ++typedef char32_t atomic_char32_t; ++typedef wchar_t atomic_wchar_t; ++ ++ ++extern bool atomic_flag_test_and_set(volatile atomic_flag *object); ++extern bool atomic_flag_test_and_set_explicit(volatile atomic_flag *object, memory_order order); ++ ++extern void atomic_flag_clear(volatile atomic_flag *object); ++extern void atomic_flag_clear_explicit(volatile atomic_flag *object, memory_order order); ++ ++ ++#define atomic_fetch_add(object, operand) \ ++ ((sizeof(*(object)) == 1) ? \ ++ zenny_atomic_fetch_add8((volatile atomic_schar *)(object), (int8_t)(operand)) : \ ++ ((sizeof(*(object)) == 2) ? \ ++ zenny_atomic_fetch_add16((volatile atomic_short *)(object), (int16_t)(operand)) : \ ++ ((sizeof(*(object)) == 4) ? \ ++ zenny_atomic_fetch_add32((volatile atomic_long *)(object), (int32_t)(operand)) : \ ++ zenny_atomic_fetch_add64((volatile atomic_llong *)(object), (int64_t)(operand))))) ++ ++#define atomic_fetch_add_explicit(object, operand, order) atomic_fetch_add((object), (operand)) ++ ++extern int8_t zenny_atomic_fetch_add8(volatile atomic_schar *object, int8_t operand); ++extern int16_t zenny_atomic_fetch_add16(volatile atomic_short *object, int16_t operand); ++extern int32_t zenny_atomic_fetch_add32(volatile atomic_long *object, int32_t operand); ++extern int64_t zenny_atomic_fetch_add64(volatile atomic_llong *object, int64_t operand); ++ ++ ++#define atomic_fetch_sub(object, operand) \ ++ ((sizeof(*(object)) == 1) ? \ ++ zenny_atomic_fetch_sub8((volatile atomic_schar *)(object), (int8_t)(operand)) : \ ++ ((sizeof(*(object)) == 2) ? \ ++ zenny_atomic_fetch_sub16((volatile atomic_short *)(object), (int16_t)(operand)) : \ ++ ((sizeof(*(object)) == 4) ? \ ++ zenny_atomic_fetch_sub32((volatile atomic_long *)(object), (int32_t)(operand)) : \ ++ zenny_atomic_fetch_sub64((volatile atomic_llong *)(object), (int64_t)(operand))))) ++ ++#define atomic_fetch_sub_explicit(object, operand, order) atomic_fetch_sub((object), (operand)) ++ ++extern int8_t zenny_atomic_fetch_sub8(volatile atomic_schar *object, int8_t operand); ++extern int16_t zenny_atomic_fetch_sub16(volatile atomic_short *object, int16_t operand); ++extern int32_t zenny_atomic_fetch_sub32(volatile atomic_long *object, int32_t operand); ++extern int64_t zenny_atomic_fetch_sub64(volatile atomic_llong *object, int64_t operand); ++ ++ ++#define atomic_fetch_or(object, operand) \ ++ ((sizeof(*(object)) == 1) ? \ ++ zenny_atomic_fetch_or8((volatile atomic_schar *)(object), (int8_t)(operand)) : \ ++ ((sizeof(*(object)) == 2) ? \ ++ zenny_atomic_fetch_or16((volatile atomic_short *)(object), (int16_t)(operand)) : \ ++ ((sizeof(*(object)) == 4) ? \ ++ zenny_atomic_fetch_or32((volatile atomic_long *)(object), (int32_t)(operand)) : \ ++ zenny_atomic_fetch_or64((volatile atomic_llong *)(object), (int64_t)(operand))))) ++ ++#define atomic_fetch_or_explicit(object, operand, order) atomic_fetch_or((object), (operand)) ++ ++extern int8_t zenny_atomic_fetch_or8(volatile atomic_schar *object, int8_t operand); ++extern int16_t zenny_atomic_fetch_or16(volatile atomic_short *object, int16_t operand); ++extern int32_t zenny_atomic_fetch_or32(volatile atomic_long *object, int32_t operand); ++extern int64_t zenny_atomic_fetch_or64(volatile atomic_llong *object, int64_t operand); ++ ++ ++#define atomic_fetch_xor(object, operand) \ ++ ((sizeof(*(object)) == 1) ? \ ++ zenny_atomic_fetch_xor8((volatile atomic_schar *)(object), (int8_t)(operand)) : \ ++ ((sizeof(*(object)) == 2) ? \ ++ zenny_atomic_fetch_xor16((volatile atomic_short *)(object), (int16_t)(operand)) : \ ++ ((sizeof(*(object)) == 4) ? \ ++ zenny_atomic_fetch_xor32((volatile atomic_long *)(object), (int32_t)(operand)) : \ ++ zenny_atomic_fetch_xor64((volatile atomic_llong *)(object), (int64_t)(operand))))) ++ ++#define atomic_fetch_xor_explicit(object, operand, order) atomic_fetch_xor((object), (operand)) ++ ++extern int8_t zenny_atomic_fetch_xor8(volatile atomic_schar *object, int8_t operand); ++extern int16_t zenny_atomic_fetch_xor16(volatile atomic_short *object, int16_t operand); ++extern int32_t zenny_atomic_fetch_xor32(volatile atomic_long *object, int32_t operand); ++extern int64_t zenny_atomic_fetch_xor64(volatile atomic_llong *object, int64_t operand); ++ ++ ++#define atomic_fetch_and(object, operand) \ ++ ((sizeof(*(object)) == 1) ? \ ++ zenny_atomic_fetch_and8((volatile atomic_schar *)(object), (int8_t)(operand)) : \ ++ ((sizeof(*(object)) == 2) ? \ ++ zenny_atomic_fetch_and16((volatile atomic_short *)(object), (int16_t)(operand)) : \ ++ ((sizeof(*(object)) == 4) ? \ ++ zenny_atomic_fetch_and32((volatile atomic_long *)(object), (int32_t)(operand)) : \ ++ zenny_atomic_fetch_and64((volatile atomic_llong *)(object), (int64_t)(operand))))) ++ ++#define atomic_fetch_and_explicit(object, operand, order) atomic_fetch_and((object), (operand)) ++ ++extern int8_t zenny_atomic_fetch_and8(volatile atomic_schar *object, int8_t operand); ++extern int16_t zenny_atomic_fetch_and16(volatile atomic_short *object, int16_t operand); ++extern int32_t zenny_atomic_fetch_and32(volatile atomic_long *object, int32_t operand); ++extern int64_t zenny_atomic_fetch_and64(volatile atomic_llong *object, int64_t operand); ++ ++ ++#define atomic_exchange(object, desired) \ ++ ((sizeof(*(object)) == 1) ? \ ++ zenny_atomic_exchange8((volatile atomic_schar *)(object), (int8_t)(desired)) : \ ++ ((sizeof(*(object)) == 2) ? \ ++ zenny_atomic_exchange16((volatile atomic_short *)(object), (int16_t)(desired)) : \ ++ ((sizeof(*(object)) == 4) ? \ ++ zenny_atomic_exchange32((volatile atomic_long *)(object), (int32_t)(desired)) : \ ++ zenny_atomic_exchange64((volatile atomic_llong *)(object), (int64_t)(desired))))) ++ ++#define atomic_exchange_explicit(object, desired, order) atomic_exchange((object), (desired)) ++ ++extern int8_t zenny_atomic_exchange8(volatile atomic_schar *object, int8_t desired); ++extern int16_t zenny_atomic_exchange16(volatile atomic_short *object, int16_t desired); ++extern int32_t zenny_atomic_exchange32(volatile atomic_long *object, int32_t desired); ++extern int64_t zenny_atomic_exchange64(volatile atomic_llong *object, int64_t desired); ++ ++ ++#define atomic_compare_exchange_strong(object, expected, desired) \ ++ (sizeof(*(object)) == 1 ? \ ++ zenny_atomic_compare_exchange8((volatile atomic_schar *)(object), (int8_t *)(expected), (int8_t)(desired)) : \ ++ (sizeof(*(object)) == 2 ? \ ++ zenny_atomic_compare_exchange16((volatile atomic_short *)(object), (int16_t *)(expected), (int16_t)(desired)) : \ ++ (sizeof(*(object)) == 4 ? \ ++ zenny_atomic_compare_exchange32((volatile atomic_long *)(object), (int32_t *)(expected), (int32_t)(desired)) : \ ++ zenny_atomic_compare_exchange64((volatile atomic_llong *)(object), (int64_t *)(expected), (int64_t)(desired))))) ++ ++#define atomic_compare_exchange_weak atomic_compare_exchange_strong ++ ++#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ ++ atomic_compare_exchange_strong((object), (expected), (desired)) ++#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ ++ atomic_compare_exchange_weak((object), (expected), (desired)) ++ ++extern bool zenny_atomic_compare_exchange8(volatile atomic_schar *object, int8_t *expected, int8_t desired); ++extern bool zenny_atomic_compare_exchange16(volatile atomic_short *object, int16_t *expected, int16_t desired); ++extern bool zenny_atomic_compare_exchange32(volatile atomic_long *object, int32_t *expected, int32_t desired); ++extern bool zenny_atomic_compare_exchange64(volatile atomic_llong *object, int64_t *expected, int64_t desired); ++ ++#endif // #if defined(_MSC_VER) ++ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif diff --git a/src/utils/fluid_sys.c b/src/utils/fluid_sys.c index e3c0ea4d..e3d0bd3b 100644 --- a/src/utils/fluid_sys.c @@ -953,7 +963,7 @@ index e3c0ea4d..e3d0bd3b 100644 if(errMsg != NULL) { diff --git a/src/utils/fluid_sys.h b/src/utils/fluid_sys.h -index 86a47f32..ce12dc0f 100644 +index 635bcf6d..f65e2407 100644 --- a/src/utils/fluid_sys.h +++ b/src/utils/fluid_sys.h @@ -115,20 +115,20 @@ @@ -1022,7 +1032,7 @@ index 86a47f32..ce12dc0f 100644 #if FLUID_IS_BIG_ENDIAN #define FLUID_FOURCC(_a, _b, _c, _d) \ -@@ -238,42 +245,36 @@ int fluid_timer_stop(fluid_timer_t *timer); +@@ -241,42 +248,36 @@ int fluid_timer_stop(fluid_timer_t *timer); int fluid_timer_is_running(const fluid_timer_t *timer); long fluid_timer_get_interval(const fluid_timer_t * timer); @@ -1081,7 +1091,7 @@ index 86a47f32..ce12dc0f 100644 return (mutex); } -@@ -281,22 +282,22 @@ static FLUID_INLINE void +@@ -284,22 +285,22 @@ static FLUID_INLINE void delete_fluid_cond_mutex(fluid_cond_mutex_t *m) { fluid_return_if_fail(m != NULL); @@ -1113,7 +1123,7 @@ index 86a47f32..ce12dc0f 100644 return (cond); } -@@ -304,109 +305,36 @@ static FLUID_INLINE void +@@ -307,109 +308,36 @@ static FLUID_INLINE void delete_fluid_cond(fluid_cond_t *cond) { fluid_return_if_fail(cond != NULL); @@ -1238,7 +1248,7 @@ index 86a47f32..ce12dc0f 100644 static FLUID_INLINE void fluid_atomic_float_set(fluid_atomic_float_t *fptr, float val) -@@ -434,12 +362,12 @@ typedef void *fluid_thread_return_t; +@@ -437,12 +365,12 @@ typedef void *fluid_thread_return_t; /* static return value for thread functions which requires a return value */ #define FLUID_THREAD_RETURN_VALUE (NULL) @@ -1254,7 +1264,7 @@ index 86a47f32..ce12dc0f 100644 fluid_thread_t *new_fluid_thread(const char *name, fluid_thread_func_t func, void *data, int prio_level, int detach); -@@ -484,23 +412,16 @@ fluid_istream_t fluid_socket_get_istream(fluid_socket_t sock); +@@ -487,23 +415,16 @@ fluid_istream_t fluid_socket_get_istream(fluid_socket_t sock); fluid_ostream_t fluid_socket_get_ostream(fluid_socket_t sock); /* File access */ @@ -1289,238 +1299,238 @@ index 86a47f32..ce12dc0f 100644 FILE* fluid_file_open(const char* filename, const char** errMsg); diff --git a/src/utils/fluid_threading.cpp b/src/utils/fluid_threading.cpp new file mode 100644 -index 00000000..4e9bf89a +index 00000000..82104de9 --- /dev/null +++ b/src/utils/fluid_threading.cpp @@ -0,0 +1,157 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "fluid_threading.h" -+ -+thread_local void *privs[16]; -+bool occupied[16] = { false }; -+ -+void _mutex_init(_mutex *mutex) -+{ -+ mutex->mutex = (void *)(new std::mutex); -+} -+ -+void _mutex_clear(_mutex *mutex) -+{ -+ delete (std::mutex *)(mutex->mutex); -+ mutex->mutex = NULL; -+} -+ -+void _mutex_lock(_mutex *mutex) -+{ -+ if (!mutex->mutex) -+ mutex->mutex = (void *)(new std::mutex); -+ ((std::mutex *)(mutex->mutex))->lock(); -+} -+ -+void _mutex_unlock(_mutex *mutex) -+{ -+ if (!mutex->mutex) -+ mutex->mutex = (void *)(new std::mutex); -+ ((std::mutex *)(mutex->mutex))->unlock(); -+} -+ -+void _rec_mutex_init(_rec_mutex *recmutex) -+{ -+ recmutex->recmutex = (void *)(new std::recursive_mutex); -+} -+ -+void _rec_mutex_clear(_rec_mutex *recmutex) -+{ -+ delete (std::recursive_mutex *)(recmutex->recmutex); -+ recmutex->recmutex = NULL; -+} -+ -+void _rec_mutex_lock(_rec_mutex *recmutex) -+{ -+ if (!recmutex->recmutex) -+ recmutex->recmutex = (void *)(new std::recursive_mutex); -+ ((std::recursive_mutex *)(recmutex->recmutex))->lock(); -+} -+ -+void _rec_mutex_unlock(_rec_mutex *recmutex) -+{ -+ if (!recmutex->recmutex) -+ recmutex->recmutex = (void *)(new std::recursive_mutex); -+ ((std::recursive_mutex *)(recmutex->recmutex))->unlock(); -+} -+ -+void _cond_init(_cond *cond) -+{ -+ cond->cond = (void *)(new std::condition_variable_any); -+} -+ -+void _cond_clear(_cond *cond) -+{ -+ delete (std::condition_variable_any *)(cond->cond); -+} -+ -+void _cond_signal(_cond *cond) -+{ -+ ((std::condition_variable_any *)(cond->cond))->notify_one(); -+} -+ -+void _cond_broadcast(_cond *cond) -+{ -+ ((std::condition_variable_any *)(cond->cond))->notify_all(); -+} -+ -+void _cond_wait(_cond *cond, _mutex *mutex) -+{ -+ ((std::condition_variable_any *)(cond->cond))->wait(*(std::mutex *)(mutex->mutex)); -+} -+ -+void *_private_get(_private *priv) -+{ -+ if (!priv->id) -+ for (int i = 0; i < 16; ++i) -+ if (!occupied[i]) -+ { -+ priv->id = i + 1; -+ break; -+ } -+ if (priv->id) -+ return privs[priv->id - 1]; -+ else -+ return NULL; -+} -+ -+void _private_set(_private *priv, void *val) -+{ -+ if (!priv->id) -+ for (int i = 0; i < 16; ++i) -+ if (!occupied[i]) -+ { -+ priv->id = i + 1; -+ break; -+ } -+ if (priv->id) -+ privs[priv->id - 1] = val; -+} -+ -+unsigned _thread_get_id(void) -+{ -+ std::hash h; -+ return h(std::this_thread::get_id()); -+} -+ -+void _thread_create(_thread *th, _thread_func_t func, void *data) -+{ -+ th->thrd = (void *)(new std::thread(func, data)); -+} -+ -+void _thread_detach(_thread *th) -+{ -+ if (!th->thrd) -+ return; -+ ((std::thread *)(th->thrd))->detach(); -+ delete (std::thread *)(th->thrd); -+ th->thrd = nullptr; -+} -+ -+void _thread_join(_thread *th) -+{ -+ if (!th->thrd) -+ return; -+ ((std::thread *)(th->thrd))->join(); -+ delete (std::thread *)(th->thrd); -+ th->thrd = nullptr; -+} -+ -+void _thread_sleep(unsigned long us) -+{ -+ std::this_thread::sleep_for(std::chrono::microseconds(us)); -+} -+ -+double _monotonic_time() -+{ -+ return std::chrono::duration_cast>( -+ std::chrono::steady_clock::now().time_since_epoch()) -+ .count(); -+} ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "fluid_threading.h" ++ ++thread_local void *privs[16]; ++bool occupied[16] = { false }; ++ ++void _mutex_init(_mutex *mutex) ++{ ++ mutex->mutex = (void *)(new std::mutex); ++} ++ ++void _mutex_clear(_mutex *mutex) ++{ ++ delete (std::mutex *)(mutex->mutex); ++ mutex->mutex = NULL; ++} ++ ++void _mutex_lock(_mutex *mutex) ++{ ++ if (!mutex->mutex) ++ mutex->mutex = (void *)(new std::mutex); ++ ((std::mutex *)(mutex->mutex))->lock(); ++} ++ ++void _mutex_unlock(_mutex *mutex) ++{ ++ if (!mutex->mutex) ++ mutex->mutex = (void *)(new std::mutex); ++ ((std::mutex *)(mutex->mutex))->unlock(); ++} ++ ++void _rec_mutex_init(_rec_mutex *recmutex) ++{ ++ recmutex->recmutex = (void *)(new std::recursive_mutex); ++} ++ ++void _rec_mutex_clear(_rec_mutex *recmutex) ++{ ++ delete (std::recursive_mutex *)(recmutex->recmutex); ++ recmutex->recmutex = NULL; ++} ++ ++void _rec_mutex_lock(_rec_mutex *recmutex) ++{ ++ if (!recmutex->recmutex) ++ recmutex->recmutex = (void *)(new std::recursive_mutex); ++ ((std::recursive_mutex *)(recmutex->recmutex))->lock(); ++} ++ ++void _rec_mutex_unlock(_rec_mutex *recmutex) ++{ ++ if (!recmutex->recmutex) ++ recmutex->recmutex = (void *)(new std::recursive_mutex); ++ ((std::recursive_mutex *)(recmutex->recmutex))->unlock(); ++} ++ ++void _cond_init(_cond *cond) ++{ ++ cond->cond = (void *)(new std::condition_variable_any); ++} ++ ++void _cond_clear(_cond *cond) ++{ ++ delete (std::condition_variable_any *)(cond->cond); ++} ++ ++void _cond_signal(_cond *cond) ++{ ++ ((std::condition_variable_any *)(cond->cond))->notify_one(); ++} ++ ++void _cond_broadcast(_cond *cond) ++{ ++ ((std::condition_variable_any *)(cond->cond))->notify_all(); ++} ++ ++void _cond_wait(_cond *cond, _mutex *mutex) ++{ ++ ((std::condition_variable_any *)(cond->cond))->wait(*(std::mutex *)(mutex->mutex)); ++} ++ ++void *_private_get(_private *priv) ++{ ++ if (!priv->id) ++ for (int i = 0; i < 16; ++i) ++ if (!occupied[i]) ++ { ++ priv->id = i + 1; ++ break; ++ } ++ if (priv->id) ++ return privs[priv->id - 1]; ++ else ++ return NULL; ++} ++ ++void _private_set(_private *priv, void *val) ++{ ++ if (!priv->id) ++ for (int i = 0; i < 16; ++i) ++ if (!occupied[i]) ++ { ++ priv->id = i + 1; ++ break; ++ } ++ if (priv->id) ++ privs[priv->id - 1] = val; ++} ++ ++unsigned _thread_get_id(void) ++{ ++ std::hash h; ++ return h(std::this_thread::get_id()); ++} ++ ++void _thread_create(_thread *th, _thread_func_t func, void *data) ++{ ++ th->thrd = (void *)(new std::thread(func, data)); ++} ++ ++void _thread_detach(_thread *th) ++{ ++ if (!th->thrd) ++ return; ++ ((std::thread *)(th->thrd))->detach(); ++ delete (std::thread *)(th->thrd); ++ th->thrd = nullptr; ++} ++ ++void _thread_join(_thread *th) ++{ ++ if (!th->thrd) ++ return; ++ ((std::thread *)(th->thrd))->join(); ++ delete (std::thread *)(th->thrd); ++ th->thrd = nullptr; ++} ++ ++void _thread_sleep(unsigned long us) ++{ ++ std::this_thread::sleep_for(std::chrono::microseconds(us)); ++} ++ ++double _monotonic_time() ++{ ++ return std::chrono::duration_cast>( ++ std::chrono::steady_clock::now().time_since_epoch()) ++ .count(); ++} diff --git a/src/utils/fluid_threading.h b/src/utils/fluid_threading.h new file mode 100644 -index 00000000..0e23cc69 +index 00000000..5ff498e7 --- /dev/null +++ b/src/utils/fluid_threading.h @@ -0,0 +1,65 @@ -+#ifndef _FLUID_THREADING_H -+#define _FLUID_THREADING_H -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+typedef void* (*_thread_func_t)(void *data); -+ -+typedef struct __mtx -+{ -+ void *mutex; -+} _mutex; -+ -+typedef struct __recmtx -+{ -+ void *recmutex; -+} _rec_mutex; -+ -+typedef struct __cnd -+{ -+ void *cond; -+} _cond; -+ -+typedef struct __prvt -+{ -+ int id; -+} _private; -+ -+typedef struct __thrd -+{ -+ void *thrd; -+} _thread; -+ -+void _mutex_init(_mutex *mutex); -+void _mutex_clear(_mutex *mutex); -+void _mutex_lock(_mutex *mutex); -+void _mutex_unlock(_mutex *mutex); -+ -+void _rec_mutex_init(_rec_mutex *recmutex); -+void _rec_mutex_clear(_rec_mutex *recmutex); -+void _rec_mutex_lock(_rec_mutex *recmutex); -+void _rec_mutex_unlock(_rec_mutex *recmutex); -+ -+void _cond_init(_cond *cond); -+void _cond_clear(_cond *cond); -+void _cond_signal(_cond *cond); -+void _cond_broadcast(_cond *cond); -+void _cond_wait(_cond *cond, _mutex *mutex); -+ -+void *_private_get(_private *priv); -+void _private_set(_private *priv, void *val); -+ -+unsigned _thread_get_id(void); -+void _thread_create(_thread *th, _thread_func_t func, void *data); -+void _thread_detach(_thread *th); -+void _thread_join(_thread *th); -+void _thread_sleep(unsigned long us); -+double _monotonic_time(void); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ++#ifndef _FLUID_THREADING_H ++#define _FLUID_THREADING_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++typedef void* (*_thread_func_t)(void *data); ++ ++typedef struct __mtx ++{ ++ void *mutex; ++} _mutex; ++ ++typedef struct __recmtx ++{ ++ void *recmutex; ++} _rec_mutex; ++ ++typedef struct __cnd ++{ ++ void *cond; ++} _cond; ++ ++typedef struct __prvt ++{ ++ int id; ++} _private; ++ ++typedef struct __thrd ++{ ++ void *thrd; ++} _thread; ++ ++void _mutex_init(_mutex *mutex); ++void _mutex_clear(_mutex *mutex); ++void _mutex_lock(_mutex *mutex); ++void _mutex_unlock(_mutex *mutex); ++ ++void _rec_mutex_init(_rec_mutex *recmutex); ++void _rec_mutex_clear(_rec_mutex *recmutex); ++void _rec_mutex_lock(_rec_mutex *recmutex); ++void _rec_mutex_unlock(_rec_mutex *recmutex); ++ ++void _cond_init(_cond *cond); ++void _cond_clear(_cond *cond); ++void _cond_signal(_cond *cond); ++void _cond_broadcast(_cond *cond); ++void _cond_wait(_cond *cond, _mutex *mutex); ++ ++void *_private_get(_private *priv); ++void _private_set(_private *priv, void *val); ++ ++unsigned _thread_get_id(void); ++void _thread_create(_thread *th, _thread_func_t func, void *data); ++void _thread_detach(_thread *th); ++void _thread_join(_thread *th); ++void _thread_sleep(unsigned long us); ++double _monotonic_time(void); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif diff --git a/src/utils/fluidsynth_priv.h b/src/utils/fluidsynth_priv.h index f8f36381..83a0a951 100644 --- a/src/utils/fluidsynth_priv.h