Skip to content

Commit 3980638

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

File tree

4 files changed

+58
-3
lines changed

4 files changed

+58
-3
lines changed

WaveSabreCore/CMakeLists.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ add_library(WaveSabreCore
5454
src/Thunder.cpp
5555
src/Twister.cpp)
5656

57-
target_link_libraries(WaveSabreCore Msacm32.lib)
57+
target_link_libraries(WaveSabreCore PUBLIC Msacm32.lib)
58+
5859
target_include_directories(WaveSabreCore PUBLIC include)
5960

6061
if(MSVC)
@@ -69,4 +70,13 @@ if(MSVC)
6970
target_compile_options(WaveSabreCore PUBLIC
7071
$<$<CONFIG:MinSizeRel>:/Zc:sizedDealloc->)
7172
endif()
73+
else()
74+
# assuming GCC or clang for now
75+
76+
if(CMAKE_BUILD_TYPE NOTEQUAL Debug)
77+
set_property(TARGET WaveSabreCore PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
78+
target_compile_options(WaveSabreCore
79+
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>
80+
PRIVATE $<$<CONFIG:MinSizeRel>:-fno-math-errno -march=nocona -ffunction-sections -fdata-sections -Wl,--gc-sections)
81+
endif()
7282
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
@@ -28,4 +29,7 @@ if(MSVC)
2829
$<$<CONFIG:MinSizeRel>:/EHs-c->)
2930
set_property(TARGET WaveSabrePlayerLib APPEND_STRING PROPERTY STATIC_LIBRARY_FLAGS_MINSIZEREL
3031
" /LTCG")
32+
else()
33+
# we need C++11 for std::atomic
34+
set_property(TARGET WaveSabrePlayerLib PROPERTY CXX_STANDARD 11)
3135
endif()
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)