#include #include #include "TracyTaskDispatch.hpp" namespace tracy { TaskDispatch::TaskDispatch( size_t workers ) : m_exit( false ) , m_jobs( 0 ) { assert( workers >= 1 ); m_workers.reserve( workers ); for( size_t i=0; i& f ) { std::lock_guard lock( m_queueLock ); m_queue.emplace_back( f ); m_cvWork.notify_one(); } void TaskDispatch::Queue( std::function&& f ) { std::lock_guard lock( m_queueLock ); m_queue.emplace_back( std::move( f ) ); m_cvWork.notify_one(); } void TaskDispatch::Sync() { std::unique_lock lock( m_queueLock ); while( !m_queue.empty() ) { auto f = m_queue.back(); m_queue.pop_back(); lock.unlock(); f(); lock.lock(); } m_cvJobs.wait( lock, [this]{ return m_jobs == 0; } ); } void TaskDispatch::Worker() { for(;;) { std::unique_lock lock( m_queueLock ); m_cvWork.wait( lock, [this]{ return !m_queue.empty() || m_exit.load( std::memory_order_acquire ); } ); if( m_exit.load( std::memory_order_acquire ) ) return; auto f = m_queue.back(); m_queue.pop_back(); m_jobs++; lock.unlock(); f(); lock.lock(); m_jobs--; if( m_jobs == 0 && m_queue.empty() ) m_cvJobs.notify_one(); lock.unlock(); } } }