Added atomic guards to clear promises
And a specific thread to avoid useless race conditions
This commit is contained in:
parent
d1e031e8e2
commit
528593fa76
2 changed files with 35 additions and 7 deletions
|
|
@ -27,10 +27,10 @@
|
|||
#include "Config.h"
|
||||
#include "Debug.h"
|
||||
#include "Oversampler.h"
|
||||
#include "AtomicGuard.h"
|
||||
#include "absl/types/span.h"
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <sndfile.hh>
|
||||
#include <thread>
|
||||
using namespace std::chrono_literals;
|
||||
|
|
@ -149,12 +149,28 @@ void sfz::FilePool::setPreloadSize(uint32_t preloadSize) noexcept
|
|||
this->preloadSize = preloadSize;
|
||||
}
|
||||
|
||||
void sfz::FilePool::tryToClearPromises()
|
||||
{
|
||||
AtomicDisabler disabler { canAddPromisesToClear };
|
||||
|
||||
while (addingPromisesToClear)
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
promisesToClear.clear();
|
||||
}
|
||||
|
||||
void sfz::FilePool::clearingThread()
|
||||
{
|
||||
while (!quitThread) {
|
||||
tryToClearPromises();
|
||||
std::this_thread::sleep_for(50ms);
|
||||
}
|
||||
}
|
||||
|
||||
void sfz::FilePool::loadingThread() noexcept
|
||||
{
|
||||
FilePromisePtr promise;
|
||||
while (!quitThread) {
|
||||
promisesToClean.clear();
|
||||
|
||||
if (emptyQueue) {
|
||||
while(promiseQueue.try_dequeue(promise)) {
|
||||
// We're just dequeuing
|
||||
|
|
@ -197,11 +213,16 @@ void sfz::FilePool::clear()
|
|||
emptyFileLoadingQueues();
|
||||
preloadedFiles.clear();
|
||||
temporaryFilePromises.clear();
|
||||
promisesToClean.clear();
|
||||
promisesToClear.clear();
|
||||
}
|
||||
|
||||
void sfz::FilePool::cleanupPromises() noexcept
|
||||
{
|
||||
AtomicGuard guard { addingPromisesToClear };
|
||||
|
||||
if (!canAddPromisesToClear)
|
||||
return;
|
||||
|
||||
FilePromisePtr promise;
|
||||
// Remove stuff from the filled queue and put them in a linear storage
|
||||
while (filledPromiseQueue.try_dequeue(promise))
|
||||
|
|
@ -211,7 +232,7 @@ void sfz::FilePool::cleanupPromises() noexcept
|
|||
auto sentinel = temporaryFilePromises.end() - 1;
|
||||
while (promiseIterator != temporaryFilePromises.end()) {
|
||||
if (promiseIterator->use_count() == 1) {
|
||||
promisesToClean.push_back(*promiseIterator);
|
||||
promisesToClear.push_back(*promiseIterator);
|
||||
std::iter_swap(promiseIterator, sentinel);
|
||||
sentinel--;
|
||||
temporaryFilePromises.pop_back();
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "Defaults.h"
|
||||
#include "LeakDetector.h"
|
||||
#include "AudioBuffer.h"
|
||||
#include "AudioSpan.h"
|
||||
#include "SIMDHelpers.h"
|
||||
#include "ghc/fs_std.hpp"
|
||||
#include <absl/container/flat_hash_map.h>
|
||||
|
|
@ -61,7 +62,7 @@ struct FilePromise
|
|||
AudioBufferPtr preloadedData {};
|
||||
std::unique_ptr<AudioBuffer<float>> fileData {};
|
||||
float sampleRate { config::defaultSampleRate };
|
||||
std::atomic<int> availableFrames { 0 };
|
||||
std::atomic_size_t availableFrames { 0 };
|
||||
std::atomic<bool> dataReady { false };
|
||||
Oversampling oversamplingFactor { config::defaultOversamplingFactor };
|
||||
};
|
||||
|
|
@ -92,6 +93,7 @@ public:
|
|||
{
|
||||
for (int i = 0; i < config::numBackgroundThreads; ++i)
|
||||
fileLoadingThreadPool.emplace_back( &FilePool::loadingThread, this );
|
||||
fileLoadingThreadPool.emplace_back( &FilePool::clearingThread, this );
|
||||
}
|
||||
|
||||
~FilePool()
|
||||
|
|
@ -200,6 +202,8 @@ public:
|
|||
private:
|
||||
fs::path rootDirectory;
|
||||
void loadingThread() noexcept;
|
||||
void clearingThread();
|
||||
void tryToClearPromises();
|
||||
|
||||
moodycamel::BlockingConcurrentQueue<FilePromisePtr> promiseQueue { config::maxVoices };
|
||||
moodycamel::BlockingConcurrentQueue<FilePromisePtr> filledPromiseQueue { config::maxVoices };
|
||||
|
|
@ -211,7 +215,10 @@ private:
|
|||
std::atomic<int> threadsLoading { 0 };
|
||||
|
||||
std::vector<FilePromisePtr> temporaryFilePromises;
|
||||
std::vector<FilePromisePtr> promisesToClean;
|
||||
std::vector<FilePromisePtr> promisesToClear;
|
||||
std::atomic<bool> addingPromisesToClear;
|
||||
std::atomic<bool> canAddPromisesToClear;
|
||||
|
||||
absl::flat_hash_map<absl::string_view, PreloadedFileHandle> preloadedFiles;
|
||||
std::vector<std::thread> fileLoadingThreadPool { };
|
||||
LEAK_DETECTOR(FilePool);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue