OpenWalnut  1.4.0
WThreadedJobs.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
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.
14 //
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.
19 //
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/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WTHREADEDJOBS_H
26 #define WTHREADEDJOBS_H
27 
28 #include <string>
29 
30 #ifndef Q_MOC_RUN
31 #include <boost/shared_ptr.hpp>
32 #endif
33 
34 #include "WException.h"
35 #include "WFlag.h"
36 
37 /**
38  * \class WThreadedJobs
39  *
40  * A threaded functor base class for producer-consumer-style multithreaded computation.
41  *
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.
46  *
47  * Both the getJob() and the compute() functions need to be implemented.
48  *
49  * \ingroup common
50  */
51 template< class Input_T, class Job_T >
53 {
54 public:
55  //! the input type
56  typedef Input_T InputType;
57 
58  //! the job type
59  typedef Job_T JobType;
60 
61  /**
62  * Constructor.
63  *
64  * \param input The input.
65  */
66  WThreadedJobs( boost::shared_ptr< InputType const > input ); // NOLINT
67 
68  /**
69  * Destructor.
70  */
71  virtual ~WThreadedJobs();
72 
73  /**
74  * The threaded function operation. Pulls jobs and executes the \see compute()
75  * function.
76  *
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.
80  */
81  void operator() ( std::size_t id, std::size_t numThreads, WBoolFlag const& shutdown );
82 
83  /**
84  * Abstract function for the job aquisition.
85  *
86  * \param job The job (output).
87  * \return false, iff no more jobs need to be processed.
88  */
89  virtual bool getJob( JobType& job ) = 0; // NOLINT
90 
91  /**
92  * Abstract function that performs the actual computation per job.
93  *
94  * \param input The input data.
95  * \param job The current job.
96  */
97  virtual void compute( boost::shared_ptr< InputType const > input, JobType const& job ) = 0;
98 
99 protected:
100  //! the input
101  boost::shared_ptr< InputType const > m_input;
102 private:
103 };
104 
105 template< class Input_T, class Job_T >
106 WThreadedJobs< Input_T, Job_T >::WThreadedJobs( boost::shared_ptr< InputType const > input )
107  : m_input( input )
108 {
109  if( !m_input )
110  {
111  throw WException( std::string( "Invalid input." ) );
112  }
113 }
114 
115 template< class Input_T, class Job_T >
117 {
118 }
119 
120 template< class Input_T, class Job_T >
121 void WThreadedJobs< Input_T, Job_T >::operator() ( std::size_t /* id */, std::size_t /* numThreads */, WBoolFlag const& shutdown )
122 {
123  JobType job;
124  while( getJob( job ) && !shutdown() )
125  {
126  compute( m_input, job );
127  }
128 }
129 
130 /**
131  * Nearly the same class as WThreadedJobs, but this class is intended to be used for multithreaded operations on voxels and therefore it
132  * uses Striping to partition the data. This is necessarry since if the threads are not operating on blocks, they slow down!
133  */
134 template< class Input_T, class Job_T >
136 {
137 public:
138  //! the input type
139  typedef Input_T InputType;
140 
141  //! the job type
142  typedef Job_T JobType;
143 
144  /**
145  * Constructor.
146  *
147  * \param input The input.
148  */
149  WThreadedStripingJobs( boost::shared_ptr< InputType const > input ); // NOLINT
150 
151  /**
152  * Destructor.
153  */
154  virtual ~WThreadedStripingJobs();
155 
156  /**
157  * The threaded function operation. Pulls jobs and executes the \see compute()
158  * function.
159  *
160  * \param id The thread's ID.
161  * \param numThreads How many threads are working on the jobs.
162  * \param shutdown A shared flag indicating the thread should be stopped.
163  */
164  void operator() ( std::size_t id, std::size_t numThreads, WBoolFlag const& shutdown );
165 
166  /**
167  * Abstract function that performs the actual computation per voxel.
168  *
169  * \param input The input data.
170  * \param voxelNum The voxel number to operate on.
171  */
172  virtual void compute( boost::shared_ptr< InputType const > input, std::size_t voxelNum ) = 0;
173 
174 protected:
175  //! the input
176  boost::shared_ptr< InputType const > m_input;
177 private:
178 };
179 
180 template< class Input_T, class Job_T >
181 WThreadedStripingJobs< Input_T, Job_T >::WThreadedStripingJobs( boost::shared_ptr< InputType const > input )
182  : m_input( input )
183 {
184  if( !m_input )
185  {
186  throw WException( std::string( "Invalid input." ) );
187  }
188 }
189 
190 template< class Input_T, class Job_T >
192 {
193 }
194 
195 template< class Input_T, class Job_T >
196 void WThreadedStripingJobs< Input_T, Job_T >::operator() ( std::size_t id, std::size_t numThreads, WBoolFlag const& shutdown )
197 {
198  WAssert( m_input, "Bug: operations of an invalid input requested." );
199  size_t numElements = m_input->size();
200 
201  // partition the voxels via simple striping
202  size_t start = numElements / numThreads * id;
203  size_t end = ( id + 1 ) * ( numElements / numThreads );
204  if( id == numThreads - 1 ) // last thread may have less elements to take care.
205  {
206  end = numElements;
207  }
208 
209  for( size_t voxelNum = start; ( voxelNum < end ) && !shutdown(); ++voxelNum )
210  {
211  compute( m_input, voxelNum );
212  }
213 }
214 
215 #endif // WTHREADEDJOBS_H
A threaded functor base class for producer-consumer-style multithreaded computation.
Definition: WThreadedJobs.h:52
void operator()(std::size_t id, std::size_t numThreads, WBoolFlag const &shutdown)
The threaded function operation.
Job_T JobType
the job type
virtual void compute(boost::shared_ptr< InputType const > input, std::size_t voxelNum)=0
Abstract function that performs the actual computation per voxel.
virtual ~WThreadedStripingJobs()
Destructor.
virtual void compute(boost::shared_ptr< InputType const > input, JobType const &job)=0
Abstract function that performs the actual computation per job.
Input_T InputType
the input type
Definition: WThreadedJobs.h:56
virtual bool getJob(JobType &job)=0
Abstract function for the job aquisition.
boost::shared_ptr< InputType const > m_input
the input
Nearly the same class as WThreadedJobs, but this class is intended to be used for multithreaded opera...
virtual ~WThreadedJobs()
Destructor.
Basic exception handler.
Definition: WException.h:38
Input_T InputType
the input type
void operator()(std::size_t id, std::size_t numThreads, WBoolFlag const &shutdown)
The threaded function operation.
WThreadedJobs(boost::shared_ptr< InputType const > input)
Constructor.
WThreadedStripingJobs(boost::shared_ptr< InputType const > input)
Constructor.
boost::shared_ptr< InputType const > m_input
the input
Job_T JobType
the job type
Definition: WThreadedJobs.h:59