Skip to content

Commit d8d2dae

Browse files
committed
Use std::atomic instead of the windows-only primitives for atomic operations in the song renderer
1 parent 4d7493e commit d8d2dae

File tree

4 files changed

+62
-4
lines changed

4 files changed

+62
-4
lines changed

WaveSabreCore/CMakeLists.txt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,13 @@ add_library(WaveSabreCore
5252
src/StateVariableFilter.cpp
5353
src/SynthDevice.cpp
5454
src/Thunder.cpp
55-
src/Twister.cpp)
55+
src/Twister.cpp
56+
)
57+
58+
if(MSVC)
59+
target_link_libraries(WaveSabreCore PUBLIC Msacm32.lib)
60+
endif()
5661

57-
target_link_libraries(WaveSabreCore Msacm32.lib)
5862
target_include_directories(WaveSabreCore PUBLIC include)
5963

6064
if(MSVC)
@@ -69,4 +73,13 @@ if(MSVC)
6973
target_compile_options(WaveSabreCore PUBLIC
7074
$<$<CONFIG:MinSizeRel>:/Zc:sizedDealloc->)
7175
endif()
76+
else()
77+
# assuming GCC or clang for now
78+
79+
if(CMAKE_BUILD_TYPE NOTEQUAL Debug)
80+
set_property(TARGET WaveSabreCore PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
81+
target_compile_options(WaveSabreCore
82+
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>
83+
PRIVATE $<$<CONFIG:MinSizeRel>:-fno-math-errno -march=nocona -ffunction-sections -fdata-sections -Wl,--gc-sections)
84+
endif()
7285
endif()

WaveSabrePlayerLib/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
add_library(WaveSabrePlayerLib
2+
include/WaveSabrePlayerLib/AtomicHelpers.h
23
include/WaveSabrePlayerLib/CriticalSection.h
34
include/WaveSabrePlayerLib/PreRenderPlayer.h
45
include/WaveSabrePlayerLib/WavWriter.h
@@ -22,6 +23,9 @@ target_link_libraries(WaveSabrePlayerLib
2223

2324
target_include_directories(WaveSabrePlayerLib PUBLIC include)
2425

26+
# we need C++11 for std::atomic
27+
set_property(TARGET WaveSabrePlayerLib PROPERTY CXX_STANDARD 11)
28+
2529
if(MSVC)
2630
target_compile_definitions(WaveSabrePlayerLib PRIVATE _CRT_SECURE_NO_WARNINGS)
2731
target_compile_options(WaveSabrePlayerLib PUBLIC
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#ifndef __WAVESABREPLAYERLIB_ATOMIC_HELPERS_H__
2+
#define __WAVESABREPLAYERLIB_ATOMIC_HELPERS_H__
3+
4+
#ifdef _WIN32
5+
#include <Windows.h>
6+
#else
7+
#include <atomic>
8+
#endif
9+
10+
namespace WaveSabreCore
11+
{
12+
namespace AtomicHelpers
13+
{
14+
template<typename T>
15+
inline bool CmpXchg(T* value, T newval, T expect)
16+
{
17+
#ifdef _WIN32
18+
return InterlockedCompareExchange((unsigned int*)value,
19+
(unsigned int)newval, (unsigned int)expect)
20+
== (unsigned int)expect;
21+
#else
22+
return std::atomic_compare_exchange_strong((std::atomic_int*)value,
23+
(int*)&expect, newval);
24+
#endif
25+
}
26+
27+
template<typename T>
28+
inline T XDec(T* value)
29+
{
30+
#ifdef _WIN32
31+
return (T)InterlockedDecrement((unsigned int*)value);
32+
#else
33+
// returns the value *before* the call
34+
return (T)(std::atomic_fetch_sub((std::atomic_int*)value, 1) - 1);
35+
#endif
36+
}
37+
}
38+
}
39+
40+
#endif

WaveSabrePlayerLib/src/SongRenderer.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <WaveSabrePlayerLib/AtomicHelpers.h>
12
#include <WaveSabrePlayerLib/SongRenderer.h>
23

34
using namespace WaveSabreCore;
@@ -195,7 +196,7 @@ namespace WaveSabrePlayerLib
195196

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

209-
if (!InterlockedDecrement(&renderThreadsRunning))
210+
if (AtomicHelpers::XDec(&renderThreadsRunning) == 0)
210211
SetEvent(renderDoneEvent);
211212

212213
return true;

0 commit comments

Comments
 (0)