1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
#if defined(WITH_THREADS)
#include "ThreadPool.h"
#include "../../Main.h"
namespace nCine
{
ThreadPool::ThreadPool()
: ThreadPool(Thread::GetProcessorCount())
{
}
ThreadPool::ThreadPool(std::size_t numThreads)
: threads_(numThreads), numThreads_(numThreads)
{
threadStruct_.queue = &queue_;
threadStruct_.queueMutex = &queueMutex_;
threadStruct_.queueCV = &queueCV_;
threadStruct_.shouldQuit = false;
quitMutex_.Lock();
for (std::size_t i = 0; i < numThreads_; i++) {
threads_.emplace_back(WorkerFunction, &threadStruct_);
}
}
ThreadPool::~ThreadPool()
{
threadStruct_.shouldQuit = true;
queueCV_.Broadcast();
for (std::size_t i = 0; i < numThreads_; i++) {
threads_[i].Join();
}
}
void ThreadPool::EnqueueCommand(std::unique_ptr<IThreadCommand>&& threadCommand)
{
DEATH_ASSERT(threadCommand);
queueMutex_.Lock();
queue_.push_back(std::move(threadCommand));
queueCV_.Broadcast();
queueMutex_.Unlock();
}
void ThreadPool::WorkerFunction(void* arg)
{
ThreadStruct* threadStruct = static_cast<ThreadStruct*>(arg);
LOGD("Worker thread {} is starting", Thread::GetCurrentId());
while (true) {
threadStruct->queueMutex->Lock();
while (threadStruct->queue->empty() && !threadStruct->shouldQuit) {
threadStruct->queueCV->Wait(*(threadStruct->queueMutex));
}
if (threadStruct->shouldQuit) {
threadStruct->queueMutex->Unlock();
break;
}
std::unique_ptr<IThreadCommand> threadCommand = std::move(threadStruct->queue->front());
threadStruct->queue->pop_front();
threadStruct->queueMutex->Unlock();
LOGD("Worker thread {} is executing its command", Thread::GetCurrentId());
threadCommand->Execute();
}
LOGD("Worker thread {} is exiting", Thread::GetCurrentId());
}
}
#endif
|