22 #ifndef __ND_THREAD_POOL_H_
23 #define __ND_THREAD_POOL_H_
25 #include "ndCoreStdafx.h"
29 #include "ndSyncMutex.h"
30 #include "ndSemaphore.h"
31 #include "ndClassAlloc.h"
34 #define D_MAX_THREADS_COUNT 32
41 ndStartEnd(ndInt32 count, ndInt32 threadIndex, ndInt32 threads)
43 ndInt32 stride = count / threads;
44 ndInt32 residual = count - stride * threads;
45 m_start = stride * threadIndex;
46 stride += (threadIndex < residual) ? 1 : 0;
47 m_start += (threadIndex < residual) ? threadIndex : residual;
48 m_end = m_start + stride;
60 virtual void Execute()
const = 0;
69 D_CORE_API ndWorker();
70 D_CORE_API
virtual ~ndWorker();
79 ndInt32 m_threadIndex;
87 ndInt32 GetThreadCount()
const;
88 D_CORE_API
static ndInt32 GetMaxThreads();
89 D_CORE_API
void SetThreadCount(ndInt32 count);
91 D_CORE_API
void TickOne();
92 D_CORE_API
void Begin();
93 D_CORE_API
void End();
95 template <
typename Function>
96 void ParallelExecute(
const Function&
ndFunction);
99 D_CORE_API
virtual void Release();
106 inline ndInt32 ndThreadPool::GetThreadCount()
const
111 template <
typename Type,
typename ... Args>
113 :
public ndFunction<decltype(&Type::operator())(Args...)>
117 template <
typename Type>
126 void operator()(ndInt32 threadIndex, ndInt32 threadCount)
const
128 m_object.operator()(threadIndex, threadCount);
135 namespace ndMakeObject
139 return ::ndFunction<Type>(obj);
143 template <
typename Function>
150 ,m_threadPool(threadPool)
151 ,m_threadIndex(threadIndex)
152 ,m_threadCount(threadPool->GetThreadCount())
163 m_function(m_threadIndex, m_threadCount);
168 const ndInt32 m_threadIndex;
169 const ndInt32 m_threadCount;
173 template <
typename Function>
174 void ndThreadPool::ParallelExecute(
const Function& callback)
176 const ndInt32 threadCount = GetThreadCount();
179 for (ndInt32 i = 0; i < threadCount; ++i)
187 #ifdef D_USE_THREAD_EMULATION
188 for (ndInt32 i = 0; i < threadCount; ++i)
191 callback(job->m_threadIndex, job->m_threadCount);
194 for (ndInt32 i = 0; i < m_count; ++i)
197 m_workers[i].m_task.store(job);
201 callback(job->m_threadIndex, job->m_threadCount);
203 bool jobsInProgress =
true;
207 bool inProgess =
false;
208 for (ndInt32 i = 0; i < m_count; ++i)
210 inProgess = inProgess | (m_workers[i].m_task.load() !=
nullptr);
212 jobsInProgress = jobsInProgress & inProgess;
213 }
while (jobsInProgress);
219 callback(job->m_threadIndex, job->m_threadCount);