1
//---------------------------------------------------------------------------
3
// Project: OpenWalnut ( http://www.openwalnut.org )
5
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6
// For more information see http://www.openwalnut.org/copying
8
// This file is part of OpenWalnut.
10
// OpenWalnut is free software: you can redistribute it and/or modify
11
// it under the terms of the GNU Lesser General Public License as published by
12
// the Free Software Foundation, either version 3 of the License, or
13
// (at your option) any later version.
15
// OpenWalnut is distributed in the hope that it will be useful,
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
// GNU Lesser General Public License for more details.
20
// You should have received a copy of the GNU Lesser General Public License
21
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
23
//---------------------------------------------------------------------------
25
#ifndef WTHREADEDJOBS_H
26
#define WTHREADEDJOBS_H
31
#include <boost/shared_ptr.hpp>
33
#include "WException.h"
38
* \class WThreadedJobs
40
* A threaded functor base class for producer-consumer-style multithreaded computation.
42
* A job generator function produces jobs that are then distributed to the threads in
43
* a first come first serve manner. The first template parameter is the type of the input data,
44
* for example a WDataSetScalar. The second template parameter is the type of object that
45
* represents the jobs.
47
* Both the getJob() and the compute() functions need to be implemented.
51
template< class Input_T, class Job_T >
56
typedef Input_T InputType;
59
typedef Job_T JobType;
64
* \param input The input.
66
WThreadedJobs( boost::shared_ptr< InputType const > input ); // NOLINT
71
virtual ~WThreadedJobs();
74
* The threaded function operation. Pulls jobs and executes the \see compute()
77
* \param id The thread's ID.
78
* \param numThreads How many threads are working on the jobs.
79
* \param shutdown A shared flag indicating the thread should be stopped.
81
void operator() ( std::size_t id, std::size_t numThreads, WBoolFlag const& shutdown );
84
* Abstract function for the job aquisition.
86
* \param job The job (output).
87
* \return false, iff no more jobs need to be processed.
89
virtual bool getJob( JobType& job ) = 0; // NOLINT
92
* Abstract function that performs the actual computation per job.
94
* \param input The input data.
95
* \param job The current job.
97
virtual void compute( boost::shared_ptr< InputType const > input, JobType const& job ) = 0;
102
boost::shared_ptr< InputType const > m_input;
106
template< class Input_T, class Job_T >
107
WThreadedJobs< Input_T, Job_T >::WThreadedJobs( boost::shared_ptr< InputType const > input )
112
throw WException( std::string( "Invalid input." ) );
116
template< class Input_T, class Job_T >
117
WThreadedJobs< Input_T, Job_T >::~WThreadedJobs()
121
template< class Input_T, class Job_T >
122
void WThreadedJobs< Input_T, Job_T >::operator() ( std::size_t /* id */, std::size_t /* numThreads */, WBoolFlag const& shutdown )
125
while( getJob( job ) && !shutdown() )
127
compute( m_input, job );
132
* Nearly the same class as WThreadedJobs, but this class is intended to be used for multithreaded operations on voxels and therefore it
133
* uses Striping to partition the data. This is necessarry since if the threads are not operating on blocks, they slow down!
135
template< class Input_T, class Job_T >
136
class WThreadedStripingJobs
140
typedef Input_T InputType;
143
typedef Job_T JobType;
148
* \param input The input.
150
WThreadedStripingJobs( boost::shared_ptr< InputType const > input ); // NOLINT
155
virtual ~WThreadedStripingJobs();
158
* The threaded function operation. Pulls jobs and executes the \see compute()
161
* \param id The thread's ID.
162
* \param numThreads How many threads are working on the jobs.
163
* \param shutdown A shared flag indicating the thread should be stopped.
165
void operator() ( std::size_t id, std::size_t numThreads, WBoolFlag const& shutdown );
168
* Abstract function that performs the actual computation per voxel.
170
* \param input The input data.
171
* \param voxelNum The voxel number to operate on.
173
virtual void compute( boost::shared_ptr< InputType const > input, std::size_t voxelNum ) = 0;
178
boost::shared_ptr< InputType const > m_input;
182
template< class Input_T, class Job_T >
183
WThreadedStripingJobs< Input_T, Job_T >::WThreadedStripingJobs( boost::shared_ptr< InputType const > input )
188
throw WException( std::string( "Invalid input." ) );
192
template< class Input_T, class Job_T >
193
WThreadedStripingJobs< Input_T, Job_T >::~WThreadedStripingJobs()
197
template< class Input_T, class Job_T >
198
void WThreadedStripingJobs< Input_T, Job_T >::operator() ( std::size_t id, std::size_t numThreads, WBoolFlag const& shutdown )
200
WAssert( m_input, "Bug: operations of an invalid input requested." );
201
size_t numElements = m_input->size();
203
// partition the voxels via simple striping
204
size_t start = numElements / numThreads * id;
205
size_t end = ( id + 1 ) * ( numElements / numThreads );
206
if( id == numThreads - 1 ) // last thread may have less elements to take care.
211
for( size_t voxelNum = start; ( voxelNum < end ) && !shutdown(); ++voxelNum )
213
compute( m_input, voxelNum );
217
#endif // WTHREADEDJOBS_H