diff --git a/src/sfizz/Config.h b/src/sfizz/Config.h index 918264ca..9268cb89 100644 --- a/src/sfizz/Config.h +++ b/src/sfizz/Config.h @@ -99,6 +99,10 @@ namespace config { static constexpr double amplitudeTriangle = 0.625; static constexpr double amplitudeSaw = 0.515; static constexpr double amplitudeSquare = 0.515; + /** + Background file loading + */ + static constexpr int backgroundLoaderPthreadPriority = 50; // expressed in % } // namespace config } // namespace sfz diff --git a/src/sfizz/FilePool.cpp b/src/sfizz/FilePool.cpp index 2abf3b45..95647340 100644 --- a/src/sfizz/FilePool.cpp +++ b/src/sfizz/FilePool.cpp @@ -37,8 +37,14 @@ #include "absl/memory/memory.h" #include #include -#include #include +#include +#include +#if defined(_WIN32) +#include +#else +#include +#endif void readBaseFile(SndfileHandle& sndFile, sfz::FileAudioBuffer& output, uint32_t numFrames, bool reverse) { @@ -365,6 +371,8 @@ void sfz::FilePool::tryToClearPromises() void sfz::FilePool::clearingThread() { + raiseCurrentThreadPriority(); + RTSemaphore& request = semClearingRequest; do { request.wait(); @@ -376,6 +384,8 @@ void sfz::FilePool::clearingThread() void sfz::FilePool::loadingThread() noexcept { + raiseCurrentThreadPriority(); + FilePromisePtr promise; do { workerBarrier.wait(); @@ -502,3 +512,36 @@ void sfz::FilePool::waitForBackgroundLoading() noexcept std::this_thread::sleep_for(std::chrono::microseconds(100)); } } + +void sfz::FilePool::raiseCurrentThreadPriority() noexcept +{ +#if defined(_WIN32) + #pragma message("Implement Win32 thread background priority") + HANDLE thread = GetCurrentThread(); + const int priority = THREAD_PRIORITY_ABOVE_NORMAL; /*THREAD_PRIORITY_HIGHEST*/ + if (!SetThreadPriority(thread, priority)) { + std::system_error error(GetLastError(), std::system_category()); + DBG("[sfizz] Cannot set current thread priority: " << error.what()); + } +#else + pthread_t thread = pthread_self(); + int policy; + sched_param param; + + if (pthread_getschedparam(thread, &policy, ¶m) != 0) { + DBG("[sfizz] Cannot get current thread scheduling parameters"); + return; + } + + policy = SCHED_RR; + const int minprio = sched_get_priority_min(policy); + const int maxprio = sched_get_priority_max(policy); + param.sched_priority = minprio + + config::backgroundLoaderPthreadPriority * (maxprio - minprio) / 100; + + if (pthread_setschedparam(thread, policy, ¶m) != 0) { + DBG("[sfizz] Cannot set current thread scheduling parameters"); + return; + } +#endif +} diff --git a/src/sfizz/FilePool.h b/src/sfizz/FilePool.h index ee81c268..2547591f 100644 --- a/src/sfizz/FilePool.h +++ b/src/sfizz/FilePool.h @@ -259,6 +259,11 @@ public: * in the queue. */ void waitForBackgroundLoading() noexcept; + /** + * @brief Assign the current thread a priority which is appropriate + * for background sample file processing. + */ + static void raiseCurrentThreadPriority() noexcept; private: Logger& logger; fs::path rootDirectory;