diff options
author | David Robillard <d@drobilla.net> | 2022-08-09 22:03:00 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2022-08-12 01:05:22 -0400 |
commit | 524a5ed9505aae03d143c5f27805d475ba5eecfa (patch) | |
tree | 4f6a17b8c0f6634d447807c6c7bd8395078b2b24 /test/allocator_test.c | |
parent | c99c6d4cf66dca1e9a13d6068da8a993f6540486 (diff) | |
download | zix-524a5ed9505aae03d143c5f27805d475ba5eecfa.tar.gz zix-524a5ed9505aae03d143c5f27805d475ba5eecfa.tar.bz2 zix-524a5ed9505aae03d143c5f27805d475ba5eecfa.zip |
Fix ring thread safety
The previous code was "probably fine" in practice, but was both missing some
necessary synchronization, and using unnecessarily heavyweight barriers on
Windows.
Since this code conveniently has a 1:1 relationship between barriers and atomic
accesses anyway, rewrite things to use an "atomic" interface closer to standard
C11 and C++11. Harden things in the process, so that the thread-safety
guarantees are followed, and hopefully clearer to see in the code (1
synchronized read of "their" index, then maybe 1 synchronized write of "your"
index).
Windows/MSVC annoyingly does not provide a suitable C API for this, so just
ignore the existence of Windows on ARM and use x86/x64 Windows intrinsics to
prevent compiler reordering (which is all that's required on those
architectures). Note that MSVC can make some reordering guarantees about
volatile variables, but:
* Only with a certain option, /volatile:ms, which Microsoft "strongly
recommend" against using. It is disabled by default (and painfully slow if
enabled) on ARM.
* This guarantee does not prevent reordering of access to other memory (only
the volatile variables themselves), which is required by a ring buffer.
So, deal with that case by using explicit read and write barriers like before,
but only in the atomic abstractions. In the process, switch to more
lightweight barriers, which should marginally improve performance on Windows.
When MSVC adds stdatomic.h support, most of the platform-specific gunk here can
go away entirely.
Diffstat (limited to 'test/allocator_test.c')
0 files changed, 0 insertions, 0 deletions