| The Gaudi Framework v27r1

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

ThreadPoolSvc.cpp
Go to the documentation of this file.
1 #include "ThreadPoolSvc.h"
2
3 #include "GaudiKernel/SvcFactory.h"
4 #include "ThreadInitTask.h"
5
6 #include "tbb/task_scheduler_init.h"
7 #include "tbb/task_scheduler_observer.h"
8 #include "tbb/task.h"
9 #include "tbb/tick_count.h"
10 #include "tbb/tbb_thread.h"
11
12 using namespace tbb;
13
14 DECLARE_SERVICE_FACTORY(ThreadPoolSvc)
15
16 //===========================================================================
17
18
19 ThreadPoolSvc::ThreadPoolSvc( const std::string& name, ISvcLocator* svcLoc ):
20 base_class(name,svcLoc),
21 m_init(false),
22 m_threadPoolSize(0),
23 m_threadInitTools(this),
24 m_tbbSchedInit(0),
25 m_barrier(0)
26 {
27
28 declareProperty("ThreadInitTools", m_threadInitTools, "ToolHandleArray of IThreadInitTools");
29
30 }
31
32 //---------------------------------------------------------------------------
33
34 ThreadPoolSvc::~ThreadPoolSvc() {
35
36 if (m_tbbSchedInit)
37 delete m_tbbSchedInit;
38
39 if (m_barrier)
40 delete m_barrier;
41
42 }
43
44 //---------------------------------------------------------------------------
45
46 StatusCode
47 ThreadPoolSvc::initialize() {
48
49 // Initialise mother class (read properties, ...)
50 StatusCode sc(Service::initialize());
51 if (!sc.isSuccess()) {
52 warning () << "Base class could not be initialized" << endmsg;
53 return StatusCode::FAILURE;
54 }
55
56 if (m_threadInitTools.retrieve().isFailure()) {
57 error() << "Unable to retrieve ThreadInitTools Array"
58 << endmsg;
59
60 return StatusCode::FAILURE;
61 } else {
62 if (m_threadInitTools.size() != 0) {
63 info() << "retrieved " << m_threadInitTools.size() << " thread init tools"
64 << endmsg;
65 } else {
66 info() << "no thread init tools attached"
67 << endmsg;
68 }
69 }
70
71 return StatusCode::SUCCESS;
72
73 }
74
75 //---------------------------------------------------------------------------
76
77 StatusCode
78 ThreadPoolSvc::finalize() {
79
80 if (!m_init) {
81 warning() << "Looks like the ThreadPoolSvc was created, but thread pool was never initialized"
82 << endmsg;
83 }
84
85 return StatusCode::SUCCESS;
86
87 }
88
89 //---------------------------------------------------------------------------
90
91 StatusCode
92 ThreadPoolSvc::initPool(const int& poolSize) {
93
94 tbb::spin_mutex::scoped_lock lock( m_initMutex );
95
96 m_threadPoolSize = poolSize;
97
98 if (msgLevel(MSG::DEBUG))
99 debug() << "ThreadPoolSvc::initPool() poolSize = " << poolSize << endmsg;
100
101 // -100 prevents the creation of the pool and the scheduler directly executes
102 // the tasks.
103 if (-100 != m_threadPoolSize){
104 if (msgLevel(MSG::DEBUG))
105 debug() << "Initialising a ThreadPool thread pool of size " << m_threadPoolSize
106 << endmsg;
107 // Leave -1 in case selected, increment otherwise
108 int thePoolSize=m_threadPoolSize;
109 if (thePoolSize!=-1)
110 thePoolSize+=1;
111 m_tbbSchedInit = new tbb::task_scheduler_init (thePoolSize);
112
113 // execute the Thread Init Tools if there are any, and wait at barrier
114 if (m_threadInitTools.size() > 0) {
115 if (msgLevel(MSG::DEBUG))
116 debug() << "creating barrier of size " << m_threadPoolSize + 1 << endmsg;
117 m_barrier = new boost::barrier( m_threadPoolSize + 1 );
118
119 // create ThreadInitTasks, wait until all have executed
120 for (int i=0; i<m_threadPoolSize; ++i) {
121 if (msgLevel(MSG::DEBUG))
122 debug() << "creating ThreadInitTask " << i << endmsg;
123 tbb::task* t = new(tbb::task::allocate_root())
124 ThreadInitTask( m_threadInitTools, m_barrier, serviceLocator() );
125
126 tbb::task::enqueue( *t );
127 this_tbb_thread::sleep(tbb::tick_count::interval_t(.1));
128 }
129 }
130
131 } else {
132 if (msgLevel(MSG::DEBUG))
133 debug() << "Thread pool size is one. Pool not initialised." << endmsg;
134
135 if (m_threadInitTools.size() > 0) {
136 if (msgLevel(MSG::DEBUG))
137 debug() << "doing ThreadInitTask init in this thread" << endmsg;
138 ThreadInitTask theTask(m_threadInitTools, m_barrier, serviceLocator() );
139 theTask.execute();
140 }
141
142 }
143
144 if (m_barrier) {
145 if (msgLevel(MSG::DEBUG))
146 debug() << "waiting at barrier for all ThreadInitTool to finish executing" << endmsg;
147 m_barrier->wait();
148 }
149
150 if (ThreadInitTask::execFailed()) {
151 error() << "a ThreadInitTask failed to execute successfully" << endmsg;
152 return StatusCode::FAILURE;
153 }
154
155 // check to make sure all Tools were initialized
156 for (auto t : m_threadInitTools) {
157 if (t->nInit() != (unsigned int)m_threadPoolSize && m_threadPoolSize != -100) {
158 error() << " not all threads initialized for tool " << t << " : "
159 << t->nInit() << " out of " << m_threadPoolSize
160 << endmsg;
161 return StatusCode::FAILURE;
162 }
163 }
164
165 if (msgLevel(MSG::DEBUG))
166 debug() << " Thread Pool initialization complete!" << endmsg;
167
168 m_init = true;
169
170 return StatusCode::SUCCESS;
171
172 }
173
174 //---------------------------------------------------------------------------
175
176 std::vector<IThreadInitTool*>
177 ThreadPoolSvc::getThreadInitTools() const {
178
179 std::vector<IThreadInitTool*> tools;
180
181 ToolHandleArray<IThreadInitTool>::const_iterator ito = m_threadInitTools.begin();
182 for ( ; ito != m_threadInitTools.end(); ++ito ) {
183 IThreadInitTool* it = &(**ito);
184 tools.push_back(it);
185 }
186
187 return tools;
188 }
Service::initialize
StatusCode initialize() override
Definition: Service.cpp:68
ISvcLocator
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
gaudiComponentHelp.name
name
Definition: gaudiComponentHelp.py:28
ThreadPoolSvc::~ThreadPoolSvc
~ThreadPoolSvc()
Destructor.
Definition: ThreadPoolSvc.cpp:34
StatusCode::isSuccess
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
MSG::DEBUG
Definition: IMessageSvc.h:18
ThreadInitTask
Definition: ThreadInitTask.h:14
std
STL namespace.
ToolHandleArray
Array of Handles to be used in lieu of vector of naked pointers to tools.
Definition: PropertyMgr.h:24
merge_files.sc
int sc
Definition: merge_files.py:167
ThreadInitTask.h
ThreadPoolSvc::initPool
virtual StatusCode initPool(const int &poolSize)
Definition: ThreadPoolSvc.cpp:92
std::vector::push_back
T push_back(T...args)
SvcFactory.h
StatusCode::FAILURE
Definition: StatusCode.h:29
GaudiHandleArray::begin
iterator begin()
Definition: GaudiHandle.h:448
StatusCode::SUCCESS
Definition: StatusCode.h:30
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
ThreadInitTask::execFailed
static bool execFailed()
Definition: ThreadInitTask.h:28
locker.lock
def lock(file)
Definition: locker.py:16
DECLARE_SERVICE_FACTORY
#define DECLARE_SERVICE_FACTORY(x)
Definition: Service.h:361
ThreadPoolSvc.h
ThreadInitTask::execute
virtual tbb::task * execute()
Definition: ThreadInitTask.cpp:13
std::vector
STL class.
ThreadPoolSvc
Definition: ThreadPoolSvc.h:15
tbb
Definition: HiveEventLoopMgr.h:28
CommonMessaging
Definition: CommonMessaging.h:58
GaudiHandleArray< ToolHandle< T > >::end
iterator end()
Definition: GaudiHandle.h:452
ThreadPoolSvc::initialize
virtual StatusCode initialize()
Initialise.
Definition: ThreadPoolSvc.cpp:47
ThreadPoolSvc::getThreadInitTools
virtual std::vector< IThreadInitTool * > getThreadInitTools() const
Definition: ThreadPoolSvc.cpp:177
ana.i
list i
Definition: ana.py:128
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
ThreadPoolSvc::finalize
virtual StatusCode finalize()
Finalise.
Definition: ThreadPoolSvc.cpp:78
IThreadInitTool
IThreadInitTool GaudiKernel/IThreadInitTool.h.
Definition: IThreadInitTool.h:18