Make water atomic methods compatible with MSVC
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
f75582a2f3
commit
e06df7ae82
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Cross-platform C++ library for Carla, based on Juce v4
|
||||
* Copyright (C) 2015 ROLI Ltd.
|
||||
* Copyright (C) 2017-2022 Filipe Coelho <falktx@falktx.com>
|
||||
* Copyright (C) 2017-2023 Filipe Coelho <falktx@falktx.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
|
@ -16,6 +16,8 @@
|
|||
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "maths/MathsFunctions.h"
|
||||
#include "misc/Result.h"
|
||||
|
||||
|
|
|
@ -28,6 +28,15 @@
|
|||
|
||||
#include "../water.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# define WIN32_LEAN_AND_MEAN 1
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace water {
|
||||
|
@ -161,7 +170,7 @@ public:
|
|||
#else
|
||||
__attribute__ ((aligned (4)))
|
||||
#endif
|
||||
volatile Type value;
|
||||
mutable volatile Type value;
|
||||
|
||||
private:
|
||||
template <typename Dest, typename Source>
|
||||
|
@ -171,8 +180,10 @@ private:
|
|||
static inline Type castFrom64Bit (int64 value) noexcept { return castTo <Type, int64> (value); }
|
||||
static inline Type castFrom32Bit (uint32 value) noexcept { return castTo <Type, uint32> (value); }
|
||||
static inline Type castFrom64Bit (uint64 value) noexcept { return castTo <Type, uint64> (value); }
|
||||
static inline Type castFromLong (long value) noexcept { return castTo <Type, long> (value); }
|
||||
static inline int32 castTo32Bit (Type value) noexcept { return castTo <int32, Type> (value); }
|
||||
static inline int64 castTo64Bit (Type value) noexcept { return castTo <int64, Type> (value); }
|
||||
static inline long castToLong (Type value) noexcept { return castTo <long, Type> (value); }
|
||||
|
||||
Type operator++ (int); // better to just use pre-increment with atomics..
|
||||
Type operator-- (int);
|
||||
|
@ -202,7 +213,11 @@ inline int32 Atomic<int32>::get() const noexcept
|
|||
#ifdef CARLA_PROPER_CPP11_SUPPORT
|
||||
static_wassert (sizeof (int32) == 4);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return castFromLong (_InterlockedExchangeAdd (reinterpret_cast<volatile long*> (&value), 0));
|
||||
#else
|
||||
return castFrom32Bit ((int32) __sync_add_and_fetch (const_cast<volatile int32*>(&value), 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -211,7 +226,11 @@ inline int64 Atomic<int64>::get() const noexcept
|
|||
#ifdef CARLA_PROPER_CPP11_SUPPORT
|
||||
static_wassert (sizeof (int64) == 8);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return castFrom64Bit (_InterlockedExchangeAdd64 (reinterpret_cast<volatile int64*> (&value), 0));
|
||||
#else
|
||||
return castFrom64Bit ((int64) __sync_add_and_fetch (const_cast<volatile int64*>(&value), 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -220,7 +239,11 @@ inline uint32 Atomic<uint32>::get() const noexcept
|
|||
#ifdef CARLA_PROPER_CPP11_SUPPORT
|
||||
static_wassert (sizeof (uint32) == 4);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return castFromLong (_InterlockedExchangeAdd (reinterpret_cast<volatile long*> (&value), 0));
|
||||
#else
|
||||
return castFrom32Bit ((uint32) __sync_add_and_fetch (const_cast<volatile uint32*>(&value), 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -229,21 +252,35 @@ inline uint64 Atomic<uint64>::get() const noexcept
|
|||
#ifdef CARLA_PROPER_CPP11_SUPPORT
|
||||
static_wassert (sizeof (uint64) == 8);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return castFrom64Bit (_InterlockedExchangeAdd64 (reinterpret_cast<volatile int64*> (&value), 0));
|
||||
#else
|
||||
return castFrom64Bit ((uint64) __sync_add_and_fetch (const_cast<volatile uint64*>(&value), 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline Type Atomic<Type>::exchange (const Type newValue) noexcept
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
return sizeof (Type) == 4 ? castFromLong (_InterlockedExchange (reinterpret_cast<volatile long*> (&value), castToLong (newValue)))
|
||||
: castFrom64Bit (_InterlockedExchange64 (reinterpret_cast<volatile int64*> (&value), castTo64Bit (newValue)));
|
||||
#else
|
||||
Type currentVal = value;
|
||||
while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; }
|
||||
return currentVal;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline Type Atomic<Type>::operator+= (const Type amountToAdd) noexcept
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
return sizeof (Type) == 4 ? castFromLong (_InterlockedExchangeAdd (reinterpret_cast<volatile long*> (&value), castToLong (amountToAdd)))
|
||||
: castFrom64Bit (_InterlockedExchangeAdd64 (reinterpret_cast<volatile int64*> (&value), castTo64Bit (amountToAdd)));
|
||||
#else
|
||||
return (Type) __sync_add_and_fetch (&value, amountToAdd);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
|
@ -255,35 +292,58 @@ inline Type Atomic<Type>::operator-= (const Type amountToSubtract) noexcept
|
|||
template <typename Type>
|
||||
inline Type Atomic<Type>::operator++() noexcept
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
return sizeof (Type) == 4 ? castFromLong (_InterlockedIncrement (reinterpret_cast<volatile long*> (&value)))
|
||||
: castFrom64Bit (_InterlockedIncrement64 (reinterpret_cast<volatile int64*> (&value)));
|
||||
#else
|
||||
return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (&value, (Type) 1)
|
||||
: (Type) __sync_add_and_fetch ((volatile int64*) &value, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline Type Atomic<Type>::operator--() noexcept
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
return sizeof (Type) == 4 ? castFromLong (_InterlockedDecrement (reinterpret_cast<volatile long*> (&value)))
|
||||
: castFrom64Bit (_InterlockedDecrement64 (reinterpret_cast<volatile int64*> (&value)));
|
||||
#else
|
||||
return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (&value, (Type) -1)
|
||||
: (Type) __sync_add_and_fetch ((volatile int64*) &value, -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline bool Atomic<Type>::compareAndSetBool (const Type newValue, const Type valueToCompare) noexcept
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
return compareAndSetValue (newValue, valueToCompare) == valueToCompare;
|
||||
#else
|
||||
return sizeof (Type) == 4 ? __sync_bool_compare_and_swap ((volatile int32*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue))
|
||||
: __sync_bool_compare_and_swap ((volatile int64*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline Type Atomic<Type>::compareAndSetValue (const Type newValue, const Type valueToCompare) noexcept
|
||||
{
|
||||
return sizeof (Type) == 4 ? castFrom32Bit ((int32) __sync_val_compare_and_swap ((volatile int32*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue)))
|
||||
: castFrom64Bit ((int64) __sync_val_compare_and_swap ((volatile int64*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue)));
|
||||
#ifdef _MSC_VER
|
||||
return sizeof (Type) == 4 ? castFromLong (_InterlockedCompareExchange (reinterpret_cast<volatile long*> (&value), castToLong (valueToCompare), castToLong (newValue)))
|
||||
: castFrom64Bit (_InterlockedCompareExchange64 (reinterpret_cast<volatile int64*> (&value), castTo64Bit (valueToCompare), castTo64Bit (newValue)));
|
||||
#else
|
||||
return sizeof (Type) == 4 ? castFrom32Bit ((int32) __sync_val_compare_and_swap (reinterpret_cast<volatile int32*> (&value), castTo32Bit (valueToCompare), castTo32Bit (newValue)))
|
||||
: castFrom64Bit ((int64) __sync_val_compare_and_swap (reinterpret_cast<volatile int64*> (&value), castTo64Bit (valueToCompare), castTo64Bit (newValue)));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline void Atomic<Type>::memoryBarrier() noexcept
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
_ReadWriteBarrier();
|
||||
#else
|
||||
__sync_synchronize();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
|
|
|
@ -64,7 +64,7 @@ HINSTANCE getCurrentModuleInstanceHandle() noexcept
|
|||
#include "streams/OutputStream.cpp"
|
||||
|
||||
// #include "synthesisers/Synthesiser.cpp"
|
||||
//
|
||||
|
||||
#include "text/CharacterFunctions.cpp"
|
||||
#include "text/Identifier.cpp"
|
||||
#include "text/StringArray.cpp"
|
||||
|
|
Loading…
Reference in New Issue