1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Resolves thread data race on Macintosh audio output.

This commit is contained in:
Thomas Harte 2020-07-28 22:21:52 -04:00
parent b7760bb052
commit 1942742d73
2 changed files with 3 additions and 3 deletions

View File

@ -25,7 +25,7 @@ Audio::Audio(Concurrency::DeferringAsyncTaskQueue &task_queue) : task_queue_(tas
void Audio::post_sample(uint8_t sample) { void Audio::post_sample(uint8_t sample) {
// Store sample directly indexed by current write pointer; this ensures that collected samples // Store sample directly indexed by current write pointer; this ensures that collected samples
// directly map to volume and enabled/disabled states. // directly map to volume and enabled/disabled states.
sample_queue_.buffer[sample_queue_.write_pointer] = sample; sample_queue_.buffer[sample_queue_.write_pointer].store(sample, std::memory_order::memory_order_relaxed);
sample_queue_.write_pointer = (sample_queue_.write_pointer + 1) % sample_queue_.buffer.size(); sample_queue_.write_pointer = (sample_queue_.write_pointer + 1) % sample_queue_.buffer.size();
} }
@ -80,7 +80,7 @@ void Audio::get_samples(std::size_t number_of_samples, int16_t *target) {
// Determine the output level, and output that many samples. // Determine the output level, and output that many samples.
// (Hoping that the copiler substitutes an effective memset16-type operation here). // (Hoping that the copiler substitutes an effective memset16-type operation here).
const int16_t output_level = volume_multiplier_ * (int16_t(sample_queue_.buffer[sample_queue_.read_pointer]) - 128); const int16_t output_level = volume_multiplier_ * (int16_t(sample_queue_.buffer[sample_queue_.read_pointer].load(std::memory_order::memory_order_relaxed)) - 128);
for(size_t c = 0; c < cycles_left_in_sample; ++c) { for(size_t c = 0; c < cycles_left_in_sample; ++c) {
target[c] = output_level; target[c] = output_level;
} }

View File

@ -63,7 +63,7 @@ class Audio: public ::Outputs::Speaker::SampleSource {
// A queue of fetched samples; read from by one thread, // A queue of fetched samples; read from by one thread,
// written to by another. // written to by another.
struct { struct {
std::array<uint8_t, 740> buffer; std::array<std::atomic<uint8_t>, 740> buffer;
size_t read_pointer = 0, write_pointer = 0; size_t read_pointer = 0, write_pointer = 0;
} sample_queue_; } sample_queue_;