Skip to content

Commit

Permalink
Use std::atomic instead of the windows-only primitives for atomic ope…
Browse files Browse the repository at this point in the history
…rations in the song renderer
  • Loading branch information
PoroCYon committed Sep 13, 2020
1 parent 4d7493e commit d8d2dae
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 4 deletions.
17 changes: 15 additions & 2 deletions WaveSabreCore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,13 @@ add_library(WaveSabreCore
src/StateVariableFilter.cpp
src/SynthDevice.cpp
src/Thunder.cpp
src/Twister.cpp)
src/Twister.cpp
)

if(MSVC)
target_link_libraries(WaveSabreCore PUBLIC Msacm32.lib)
endif()

target_link_libraries(WaveSabreCore Msacm32.lib)
target_include_directories(WaveSabreCore PUBLIC include)

if(MSVC)
Expand All @@ -69,4 +73,13 @@ if(MSVC)
target_compile_options(WaveSabreCore PUBLIC
$<$<CONFIG:MinSizeRel>:/Zc:sizedDealloc->)
endif()
else()
# assuming GCC or clang for now

if(CMAKE_BUILD_TYPE NOTEQUAL Debug)
set_property(TARGET WaveSabreCore PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
target_compile_options(WaveSabreCore
PUBLIC $<$<CONFIG:MinSizeRel>:-Os -fno-exceptions -fno-rtti -fno-stack-protector -fno-stack-check -fno-unwind-tables -fno-asynchronous-unwind-tables -fomit-frame-pointer -fno-threadsafe-statics>
PRIVATE $<$<CONFIG:MinSizeRel>:-fno-math-errno -march=nocona -ffunction-sections -fdata-sections -Wl,--gc-sections)
endif()
endif()
4 changes: 4 additions & 0 deletions WaveSabrePlayerLib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_library(WaveSabrePlayerLib
include/WaveSabrePlayerLib/AtomicHelpers.h
include/WaveSabrePlayerLib/CriticalSection.h
include/WaveSabrePlayerLib/PreRenderPlayer.h
include/WaveSabrePlayerLib/WavWriter.h
Expand All @@ -22,6 +23,9 @@ target_link_libraries(WaveSabrePlayerLib

target_include_directories(WaveSabrePlayerLib PUBLIC include)

# we need C++11 for std::atomic
set_property(TARGET WaveSabrePlayerLib PROPERTY CXX_STANDARD 11)

if(MSVC)
target_compile_definitions(WaveSabrePlayerLib PRIVATE _CRT_SECURE_NO_WARNINGS)
target_compile_options(WaveSabrePlayerLib PUBLIC
Expand Down
40 changes: 40 additions & 0 deletions WaveSabrePlayerLib/include/WaveSabrePlayerLib/AtomicHelpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef __WAVESABREPLAYERLIB_ATOMIC_HELPERS_H__
#define __WAVESABREPLAYERLIB_ATOMIC_HELPERS_H__

#ifdef _WIN32
#include <Windows.h>
#else
#include <atomic>
#endif

namespace WaveSabreCore
{
namespace AtomicHelpers
{
template<typename T>
inline bool CmpXchg(T* value, T newval, T expect)
{
#ifdef _WIN32
return InterlockedCompareExchange((unsigned int*)value,
(unsigned int)newval, (unsigned int)expect)
== (unsigned int)expect;
#else
return std::atomic_compare_exchange_strong((std::atomic_int*)value,
(int*)&expect, newval);
#endif
}

template<typename T>
inline T XDec(T* value)
{
#ifdef _WIN32
return (T)InterlockedDecrement((unsigned int*)value);
#else
// returns the value *before* the call
return (T)(std::atomic_fetch_sub((std::atomic_int*)value, 1) - 1);
#endif
}
}
}

#endif
5 changes: 3 additions & 2 deletions WaveSabrePlayerLib/src/SongRenderer.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <WaveSabrePlayerLib/AtomicHelpers.h>
#include <WaveSabrePlayerLib/SongRenderer.h>

using namespace WaveSabreCore;
Expand Down Expand Up @@ -195,7 +196,7 @@ namespace WaveSabrePlayerLib

// We have a free track that we can work on, yay!
// Let's try to mark it so that no other thread takes it
if ((TrackRenderState)InterlockedCompareExchange((unsigned int *)&trackRenderStates[i], (unsigned int)TrackRenderState::Rendering, (unsigned int)TrackRenderState::Idle) == TrackRenderState::Idle)
if (AtomicHelpers::CmpXchg(&trackRenderStates[i], TrackRenderState::Rendering, TrackRenderState::Idle))
{
// We marked it successfully, so now we'll do the work
tracks[i]->Run(renderThreadNumFloatSamples);
Expand All @@ -206,7 +207,7 @@ namespace WaveSabrePlayerLib
}
}

if (!InterlockedDecrement(&renderThreadsRunning))
if (AtomicHelpers::XDec(&renderThreadsRunning) == 0)
SetEvent(renderDoneEvent);

return true;
Expand Down

0 comments on commit d8d2dae

Please sign in to comment.