2011-10-11 18:52:24 +00:00
// This code is in the public domain -- castano@gmail.com
# pragma once
# ifndef NV_THREAD_THREADPOOL_H
# define NV_THREAD_THREADPOOL_H
2011-09-27 17:48:46 +00:00
# include "nvthread.h"
# include "Event.h"
# include "Thread.h"
2012-07-20 16:19:03 +00:00
// The thread pool creates one worker thread for each physical core.
// The threads are idle waiting for their start events so that they do not consume any resources while inactive.
// The thread pool runs the same function in all worker threads, the idea is to use this as the foundation of a custom task scheduler.
2015-03-24 19:14:49 +00:00
// When the thread pool starts, the main thread continues running, but the common use case is to inmmediately wait for the termination events of the worker threads.
2012-07-20 16:19:03 +00:00
// @@ The start and wait methods could probably be merged.
2015-10-29 06:53:08 +00:00
// It may be running the thread function on the invoking thread to avoid thread switches.
2012-07-20 16:19:03 +00:00
2011-09-27 17:48:46 +00:00
namespace nv {
class Thread ;
class Event ;
2015-10-29 06:53:08 +00:00
typedef void ThreadTask ( void * context , int id ) ;
2011-09-27 17:48:46 +00:00
class ThreadPool {
NV_FORBID_COPY ( ThreadPool ) ;
public :
2015-10-29 06:53:08 +00:00
static void setup ( uint workerCount , bool useThreadAffinity , bool useCallingThread ) ;
2011-09-27 17:48:46 +00:00
static ThreadPool * acquire ( ) ;
static void release ( ThreadPool * ) ;
2015-10-29 06:53:08 +00:00
ThreadPool ( uint workerCount = processorCount ( ) , bool useThreadAffinity = true , bool useCallingThread = false ) ;
2011-09-27 17:48:46 +00:00
~ ThreadPool ( ) ;
2015-10-29 06:53:08 +00:00
void run ( ThreadTask * func , void * arg ) ;
void start ( ThreadTask * func , void * arg ) ;
2011-09-27 17:48:46 +00:00
void wait ( ) ;
2015-10-29 06:53:08 +00:00
//NV_THREAD_LOCAL static uint threadId;
2011-09-27 17:48:46 +00:00
private :
static void workerFunc ( void * arg ) ;
2015-10-29 06:53:08 +00:00
bool useThreadAffinity ;
bool useCallingThread ;
2011-09-27 17:48:46 +00:00
uint workerCount ;
2015-10-29 06:53:08 +00:00
2011-09-27 17:48:46 +00:00
Thread * workers ;
Event * startEvents ;
Event * finishEvents ;
uint allIdle ;
// Current function:
2015-10-29 06:53:08 +00:00
ThreadTask * func ;
2011-09-27 17:48:46 +00:00
void * arg ;
} ;
2015-10-29 06:53:08 +00:00
# if NV_CC_CPP11
template < typename F >
void thread_pool_run ( F f ) {
// Transform lambda into function pointer.
auto lambda = [ ] ( void * context , int id ) {
F & f = * reinterpret_cast < F * > ( context ) ;
f ( id ) ;
} ;
ThreadPool * pool = ThreadPool : : acquire ( ) ;
pool - > run ( lambda , & f ) ;
ThreadPool : : release ( pool ) ;
}
# endif // NV_CC_CPP11
2011-09-27 17:48:46 +00:00
} // namespace nv
# endif // NV_THREAD_THREADPOOL_H