#ifndef _RAR_THREADPOOL_ #define _RAR_THREADPOOL_ #ifndef RAR_SMP const uint MaxPoolThreads=1; // For single threaded version. #else const uint MaxPoolThreads=32; #ifdef _UNIX #include #include #endif // Undefine for debugging. #define USE_THREADS #ifdef _UNIX #define NATIVE_THREAD_TYPE void* typedef void* (*NATIVE_THREAD_PTR)(void *Data); typedef pthread_t THREAD_HANDLE; typedef pthread_mutex_t CRITSECT_HANDLE; #else #define NATIVE_THREAD_TYPE DWORD WINAPI typedef DWORD (WINAPI *NATIVE_THREAD_PTR)(void *Data); typedef HANDLE THREAD_HANDLE; typedef CRITICAL_SECTION CRITSECT_HANDLE; #endif typedef void (*PTHREAD_PROC)(void *Data); #define THREAD_PROC(fn) void fn(void *Data) uint GetNumberOfCPU(); uint GetNumberOfThreads(); class ThreadPool { private: struct QueueEntry { PTHREAD_PROC Proc; void *Param; }; void CreateThreads(); static NATIVE_THREAD_TYPE PoolThread(void *Param); void PoolThreadLoop(); bool GetQueuedTask(QueueEntry *Task); // Number of threads in the pool. Must not exceed MaxPoolThreads. uint MaxAllowedThreads; THREAD_HANDLE ThreadHandles[MaxPoolThreads]; // Number of actually created threads. uint ThreadsCreatedCount; uint ActiveThreads; QueueEntry TaskQueue[MaxPoolThreads]; uint QueueTop; uint QueueBottom; bool Closing; // Set true to quit all threads. #ifdef _WIN_ALL // Semaphore counting number of tasks stored in queue. HANDLE QueuedTasksCnt; // Event signalling if no active tasks are performing now. HANDLE NoneActive; #elif defined(_UNIX) // Semaphores seem to be slower than conditional variables in pthreads, // so we use the conditional variable to count tasks stored in queue. uint QueuedTasksCnt; pthread_cond_t QueuedTasksCntCond; pthread_mutex_t QueuedTasksCntMutex; bool AnyActive; // Active tasks present flag. pthread_cond_t AnyActiveCond; pthread_mutex_t AnyActiveMutex; #endif // Pool critical section. We use the single section for all branches // to avoid deadlocks, when thread1 has section1 and wants section2 // and thread2 has section2 and wants section1. CRITSECT_HANDLE CritSection; public: ThreadPool(uint MaxThreads); ~ThreadPool(); void AddTask(PTHREAD_PROC Proc,void *Data); void WaitDone(); #ifdef _WIN_ALL static int ThreadPriority; static void SetPriority(int Priority) {ThreadPriority=Priority;} #endif }; ThreadPool* CreateThreadPool(); void DestroyThreadPool(ThreadPool *Pool); #endif // RAR_SMP #endif // _RAR_THREADPOOL_