7 #include "tbb/task_scheduler_init.h" 8 #include "tbb/task_scheduler_observer.h" 9 #include "tbb/tbb_thread.h" 10 #include "tbb/tick_count.h" 15 namespace Concurrency {
25 declareProperty(
"ThreadInitTools", m_threadInitTools,
"ToolHandleArray of IThreadInitTools" );
35 warning() <<
"Base class could not be initialized" <<
endmsg;
39 if ( m_threadInitTools.retrieve().isFailure() ) {
40 error() <<
"Unable to retrieve ThreadInitTools Array" <<
endmsg;
44 if ( m_threadInitTools.size() != 0 ) {
45 info() <<
"retrieved " << m_threadInitTools.size() <<
" thread init tools" <<
endmsg;
47 info() <<
"no thread init tools attached" <<
endmsg;
58 warning() <<
"Looks like the ThreadPoolSvc was created, but thread pool " 59 <<
"was never initialized" <<
endmsg;
69 tbb::spin_mutex::scoped_lock lock( m_initMutex );
71 m_threadPoolSize = poolSize;
73 if ( msgLevel(
MSG::DEBUG ) ) debug() <<
"ThreadPoolSvc::initPool() poolSize = " << poolSize <<
endmsg;
85 if ( -100 != m_threadPoolSize ) {
86 if ( msgLevel(
MSG::DEBUG ) ) debug() <<
"Initialising a thread pool of size " << m_threadPoolSize <<
endmsg;
90 int thePoolSize = m_threadPoolSize;
91 if ( thePoolSize != -1 ) thePoolSize += 1;
94 m_tbbSchedInit = std::make_unique<tbb::task_scheduler_init>( thePoolSize );
96 if ( m_threadPoolSize <= -1 ) {
97 thePoolSize = m_tbbSchedInit->default_num_threads();
98 m_threadPoolSize = thePoolSize;
100 if ( msgLevel(
MSG::DEBUG ) ) { debug() <<
"creating barrier of size " << thePoolSize <<
endmsg; }
103 m_barrier = std::make_unique<boost::barrier>( thePoolSize );
110 const bool terminate =
false;
113 if ( msgLevel(
MSG::DEBUG ) ) debug() <<
"Thread Pool initialization complete!" <<
endmsg;
123 tbb::spin_mutex::scoped_lock lock( m_initMutex );
124 if ( msgLevel(
MSG::DEBUG ) ) debug() <<
"ThreadPoolSvc::terminatePool()" <<
endmsg;
127 error() <<
"Trying to terminate uninitialized thread pool!" <<
endmsg;
132 const bool terminate =
true;
135 if ( msgLevel(
MSG::DEBUG ) ) debug() <<
"Thread pool termination complete!" <<
endmsg;
144 const std::string taskType = terminate ?
"termination" :
"initialization";
148 if ( m_tbbSchedInit ) {
151 for (
int i = 0; i < m_threadPoolSize; ++i ) {
152 if ( msgLevel(
MSG::DEBUG ) ) debug() <<
"creating ThreadInitTask " << i <<
endmsg;
153 tbb::task* t =
new ( tbb::task::allocate_root() )
154 ThreadInitTask( m_threadInitTools, m_barrier.get(), serviceLocator(), terminate );
157 tbb::task::enqueue( *t );
158 this_tbb_thread::sleep( tbb::tick_count::interval_t( .02 ) );
162 if ( msgLevel(
MSG::DEBUG ) ) debug() <<
"waiting at barrier for all ThreadInitTool to finish executing" <<
endmsg;
167 for (
auto& t : m_threadInitTools ) {
169 int numInit = t->nInit();
171 int expectedNumInit = terminate ? 0 : m_threadPoolSize;
172 if ( numInit != expectedNumInit ) {
174 ost <<
"not all threads " << ( terminate ?
"terminated" :
"initialized" ) <<
" for tool " << t <<
" : " 175 << t->nInit() <<
" out of " << m_threadPoolSize <<
" are currently active.";
192 if ( msgLevel(
MSG::DEBUG ) ) debug() <<
"launching ThreadInitTask " << taskType <<
"in this thread." <<
endmsg;
193 boost::barrier* noBarrier =
nullptr;
194 ThreadInitTask theTask( m_threadInitTools, noBarrier, serviceLocator(), terminate );
200 error() <<
"a ThreadInitTask failed to execute successfully" <<
endmsg;
218 error() <<
"initThisThread triggered, but thread already initialized" <<
endmsg;
222 boost::barrier* noBarrier =
nullptr;
223 ThreadInitTask theTask( m_threadInitTools, noBarrier, serviceLocator(),
false );
StatusCode finalize() override final
Finalise.
static GAUDI_API void setNumThreads(const std::size_t &nT)
StatusCode initialize() override
tbb::task * execute() override
Execute the task.
Define general base for Gaudi exception.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
StatusCode terminatePool() override final
Terminate the thread pool and launch thread termination tasks.
Special TBB task used by ThreadPoolSvc to wrap execution of IThreadInitTools.
constexpr static const auto SUCCESS
#define DECLARE_COMPONENT(type)
virtual void initThisThread() override
This class is used for returning status codes from appropriate routines.
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, TYPE &value, const std::string &doc="none")
Declare a property (templated)
StatusCode initialize() override final
Initialise.
thread_local bool ThreadInitDone
Base class used to extend a class implementing other interfaces.
A service which initializes a TBB thread pool.
constexpr static const auto FAILURE
StatusCode initPool(const int &poolSize) override final
Initialize the thread pool and launch the ThreadInitTasks.
StatusCode launchTasks(bool finalize=false)
Launch tasks to execute the ThreadInitTools.
Helper functions to set/get the application return code.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.