Using mutex to synchronize threads

pull/88/head^2
Marcin Kondej 2019-09-27 11:17:03 +02:00
rodzic 3a68f2f3e8
commit a85a77342a
2 zmienionych plików z 21 dodań i 13 usunięć

Wyświetl plik

@ -120,7 +120,8 @@ struct AllocatedMemory {
bool Transmitter::transmitting = false; bool Transmitter::transmitting = false;
volatile ClockRegisters *Transmitter::output = nullptr; volatile ClockRegisters *Transmitter::output = nullptr;
uint32_t Transmitter::sampleOffset, Transmitter::clockDivisor, Transmitter::divisorRange, Transmitter::sampleRate; uint32_t Transmitter::sampleOffset, Transmitter::clockDivisor, Transmitter::divisorRange, Transmitter::sampleRate;
std::vector<Sample> *Transmitter::loadedSamples; std::vector<Sample> Transmitter::samples;
std::mutex Transmitter::samplesAccess;
void *Transmitter::peripherals; void *Transmitter::peripherals;
Transmitter::Transmitter() Transmitter::Transmitter()
@ -311,7 +312,7 @@ void Transmitter::transmit(WaveReader &reader, float frequency, float bandwidth,
void Transmitter::transmitViaCpu(WaveReader &reader, uint32_t bufferSize) void Transmitter::transmitViaCpu(WaveReader &reader, uint32_t bufferSize)
{ {
std::vector<Sample> samples = reader.getSamples(bufferSize, transmitting); samples = reader.getSamples(bufferSize, transmitting);
if (!samples.size()) { if (!samples.size()) {
return; return;
} }
@ -327,20 +328,23 @@ void Transmitter::transmitViaCpu(WaveReader &reader, uint32_t bufferSize)
auto finally = [&]() { auto finally = [&]() {
transmitting = false; transmitting = false;
txThread.join(); txThread.join();
samples.clear();
}; };
try { try {
while (!eof && transmitting) { while (!eof && transmitting) {
if (loadedSamples == nullptr) { if (samplesAccess.try_lock() && samples.size()) {
if (!reader.setSampleOffset(sampleOffset + bufferSize)) { if (!reader.setSampleOffset(sampleOffset + bufferSize)) {
break; samplesAccess.unlock();
break;
} }
samples = reader.getSamples(bufferSize, transmitting); samples = reader.getSamples(bufferSize, transmitting);
if (!samples.size()) { if (!samples.size()) {
break; samplesAccess.unlock();
break;
} }
eof = samples.size() < bufferSize; eof = samples.size() < bufferSize;
loadedSamples = &samples; samplesAccess.unlock();
} }
usleep(BUFFER_TIME / 2); usleep(BUFFER_TIME / 2);
} }
@ -358,7 +362,7 @@ void Transmitter::transmitViaDma(WaveReader &reader, uint32_t bufferSize, uint8_
throw std::runtime_error("DMA channel number out of range (0 - 15)"); throw std::runtime_error("DMA channel number out of range (0 - 15)");
} }
std::vector<Sample> samples = reader.getSamples(bufferSize, transmitting); samples = reader.getSamples(bufferSize, transmitting);
if (!samples.size()) { if (!samples.size()) {
return; return;
} }
@ -422,6 +426,7 @@ void Transmitter::transmitViaDma(WaveReader &reader, uint32_t bufferSize, uint8_
freeMemory(dmaMemory); freeMemory(dmaMemory);
transmitting = false; transmitting = false;
samples.clear();
}; };
try { try {
@ -465,26 +470,27 @@ void Transmitter::transmitThread()
while (transmitting) { while (transmitting) {
uint64_t start = current; uint64_t start = current;
while ((loadedSamples == nullptr) && transmitting) { while (!samplesAccess.try_lock() && transmitting) {
usleep(1); usleep(1);
current = *(reinterpret_cast<volatile uint64_t *>(&timer->low)); current = *(reinterpret_cast<volatile uint64_t *>(&timer->low));
} }
if (!transmitting) { if (!transmitting) {
samplesAccess.unlock();
break; break;
} }
std::vector<Sample> samples(*loadedSamples); std::vector<Sample> loaded(std::move(samples));
loadedSamples = nullptr; samplesAccess.unlock();
sampleOffset = (current - playbackStart) * sampleRate / 1000000; sampleOffset = (current - playbackStart) * sampleRate / 1000000;
uint32_t offset = (current - start) * sampleRate / 1000000; uint32_t offset = (current - start) * sampleRate / 1000000;
while (true) { while (true) {
if (offset >= samples.size()) { if (offset >= loaded.size()) {
break; break;
} }
uint32_t prevOffset = offset; uint32_t prevOffset = offset;
float value = samples[offset].getMonoValue(); float value = loaded[offset].getMonoValue();
#ifndef NO_PREEMP #ifndef NO_PREEMP
value = preEmphasis.filter(value); value = preEmphasis.filter(value);
#endif #endif

Wyświetl plik

@ -35,6 +35,7 @@
#define TRANSMITTER_HPP #define TRANSMITTER_HPP
#include "wave_reader.hpp" #include "wave_reader.hpp"
#include <mutex>
struct AllocatedMemory; struct AllocatedMemory;
struct PWMRegisters; struct PWMRegisters;
@ -77,7 +78,8 @@ class Transmitter
static bool transmitting; static bool transmitting;
static uint32_t sampleOffset, clockDivisor, divisorRange, sampleRate; static uint32_t sampleOffset, clockDivisor, divisorRange, sampleRate;
static volatile ClockRegisters *output; static volatile ClockRegisters *output;
static std::vector<Sample> *loadedSamples; static std::vector<Sample> samples;
static std::mutex samplesAccess;
}; };
#endif // TRANSMITTER_HPP #endif // TRANSMITTER_HPP