aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/workthreadpool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zencore/workthreadpool.cpp')
-rw-r--r--src/zencore/workthreadpool.cpp69
1 files changed, 43 insertions, 26 deletions
diff --git a/src/zencore/workthreadpool.cpp b/src/zencore/workthreadpool.cpp
index cb84bbe06..df24d4185 100644
--- a/src/zencore/workthreadpool.cpp
+++ b/src/zencore/workthreadpool.cpp
@@ -18,9 +18,7 @@ ZEN_THIRD_PARTY_INCLUDES_START
#include <gsl/gsl-lite.hpp>
ZEN_THIRD_PARTY_INCLUDES_END
-#define ZEN_USE_WINDOWS_THREADPOOL 1
-
-#if ZEN_PLATFORM_WINDOWS && ZEN_USE_WINDOWS_THREADPOOL
+#if ZEN_PLATFORM_WINDOWS
# include <zencore/windows.h>
#endif
@@ -38,13 +36,21 @@ namespace detail {
//////////////////////////////////////////////////////////////////////////
-#if ZEN_USE_WINDOWS_THREADPOOL && ZEN_PLATFORM_WINDOWS
+struct WorkerThreadPool::Impl
+{
+ virtual ~Impl() = default;
+ [[nodiscard]] virtual Ref<IWork> ScheduleWork(Ref<IWork> Work, WorkerThreadPool::EMode Mode) = 0;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+#if ZEN_PLATFORM_WINDOWS
namespace {
thread_local bool t_IsThreadNamed{false};
}
-struct WorkerThreadPool::Impl
+struct WinTpImpl : WorkerThreadPool::Impl
{
const int m_ThreadCount = 0;
PTP_POOL m_ThreadPool = nullptr;
@@ -59,7 +65,7 @@ struct WorkerThreadPool::Impl
mutable RwLock m_QueueLock;
std::deque<Ref<IWork>> m_WorkQueue;
- Impl(int InThreadCount, std::string_view WorkerThreadBaseName)
+ WinTpImpl(int InThreadCount, std::string_view WorkerThreadBaseName)
: m_ThreadCount(InThreadCount)
, m_WorkerThreadBaseName(WorkerThreadBaseName)
, m_FreeWorkerCount(m_ThreadCount)
@@ -96,14 +102,14 @@ struct WorkerThreadPool::Impl
}
}
- ~Impl()
+ ~WinTpImpl() override
{
WaitForThreadpoolWorkCallbacks(m_Work, /* CancelPendingCallbacks */ TRUE);
CloseThreadpoolWork(m_Work);
CloseThreadpool(m_ThreadPool);
}
- [[nodiscard]] Ref<IWork> ScheduleWork(Ref<IWork> Work, WorkerThreadPool::EMode Mode)
+ [[nodiscard]] Ref<IWork> ScheduleWork(Ref<IWork> Work, WorkerThreadPool::EMode Mode) override
{
if (Mode == WorkerThreadPool::EMode::DisableBacklog)
{
@@ -130,7 +136,7 @@ struct WorkerThreadPool::Impl
static VOID CALLBACK WorkCallback(_Inout_ PTP_CALLBACK_INSTANCE Instance, _Inout_opt_ PVOID Context, _Inout_ PTP_WORK Work)
{
ZEN_UNUSED(Instance, Work);
- Impl* ThisPtr = reinterpret_cast<Impl*>(Context);
+ WinTpImpl* ThisPtr = reinterpret_cast<WinTpImpl*>(Context);
ThisPtr->DoWork();
}
@@ -175,7 +181,9 @@ struct WorkerThreadPool::Impl
}
};
-#else
+#endif
+
+//////////////////////////////////////////////////////////////////////////
struct WorkerThreadPool::ThreadStartInfo
{
@@ -183,39 +191,39 @@ struct WorkerThreadPool::ThreadStartInfo
zen::Latch* Latch;
};
-struct WorkerThreadPool::Impl
+struct ExplicitImpl : WorkerThreadPool::Impl
{
const int m_ThreadCount = 0;
- void WorkerThreadFunction(ThreadStartInfo Info);
+ void WorkerThreadFunction(WorkerThreadPool::ThreadStartInfo Info);
std::string m_WorkerThreadBaseName;
std::vector<std::thread> m_WorkerThreads;
BlockingQueue<Ref<IWork>> m_WorkQueue;
std::atomic<int> m_FreeWorkerCount{0};
- Impl(int InThreadCount, std::string_view WorkerThreadBaseName)
+ ExplicitImpl(int InThreadCount, std::string_view WorkerThreadBaseName)
: m_ThreadCount(InThreadCount)
, m_WorkerThreadBaseName(WorkerThreadBaseName)
, m_FreeWorkerCount(m_ThreadCount)
{
-# if ZEN_WITH_TRACE
+#if ZEN_WITH_TRACE
trace::ThreadGroupBegin(m_WorkerThreadBaseName.c_str());
-# endif
+#endif
zen::Latch WorkerLatch{m_ThreadCount};
for (int i = 0; i < m_ThreadCount; ++i)
{
- m_WorkerThreads.emplace_back(&Impl::WorkerThreadFunction, this, ThreadStartInfo{i + 1, &WorkerLatch});
+ m_WorkerThreads.emplace_back(&ExplicitImpl::WorkerThreadFunction, this, WorkerThreadPool::ThreadStartInfo{i + 1, &WorkerLatch});
}
WorkerLatch.Wait();
-# if ZEN_WITH_TRACE
+#if ZEN_WITH_TRACE
trace::ThreadGroupEnd();
-# endif
+#endif
}
- ~Impl()
+ ~ExplicitImpl() override
{
m_WorkQueue.CompleteAdding();
@@ -230,7 +238,7 @@ struct WorkerThreadPool::Impl
m_WorkerThreads.clear();
}
- [[nodiscard]] Ref<IWork> ScheduleWork(Ref<IWork> Work, WorkerThreadPool::EMode Mode)
+ [[nodiscard]] Ref<IWork> ScheduleWork(Ref<IWork> Work, WorkerThreadPool::EMode Mode) override
{
if (Mode == WorkerThreadPool::EMode::DisableBacklog)
{
@@ -250,7 +258,7 @@ struct WorkerThreadPool::Impl
};
void
-WorkerThreadPool::Impl::WorkerThreadFunction(ThreadStartInfo Info)
+ExplicitImpl::WorkerThreadFunction(WorkerThreadPool::ThreadStartInfo Info)
{
SetCurrentThreadName(fmt::format("{}_{}", m_WorkerThreadBaseName, Info.ThreadNumber));
@@ -288,18 +296,27 @@ WorkerThreadPool::Impl::WorkerThreadFunction(ThreadStartInfo Info)
} while (true);
}
-#endif
-
//////////////////////////////////////////////////////////////////////////
-WorkerThreadPool::WorkerThreadPool(int InThreadCount) : WorkerThreadPool(InThreadCount, "workerthread")
+WorkerThreadPool::WorkerThreadPool(int InThreadCount, bool UseExplicitThreads)
+: WorkerThreadPool(InThreadCount, "workerthread", UseExplicitThreads)
{
}
-WorkerThreadPool::WorkerThreadPool(int InThreadCount, std::string_view WorkerThreadBaseName)
+WorkerThreadPool::WorkerThreadPool(int InThreadCount, std::string_view WorkerThreadBaseName, bool UseExplicitThreads)
{
if (InThreadCount > 0)
{
- m_Impl = std::make_unique<Impl>(InThreadCount, WorkerThreadBaseName);
+#if ZEN_PLATFORM_WINDOWS
+ if (!UseExplicitThreads)
+ {
+ m_Impl = std::make_unique<WinTpImpl>(InThreadCount, WorkerThreadBaseName);
+ }
+ else
+#endif
+ {
+ ZEN_UNUSED(UseExplicitThreads);
+ m_Impl = std::make_unique<ExplicitImpl>(InThreadCount, WorkerThreadBaseName);
+ }
}
}