iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ThreadPools.H
Go to the documentation of this file.
1 /*! @file
2  @author Shane Grant
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 
36 #ifndef INCLUDE_NRT_CORE_DESIGN_THREADPOOLS_H
37 #define INCLUDE_NRT_CORE_DESIGN_THREADPOOLS_H
38 
41 
42 #include <future>
43 #include <vector>
44 #include <thread>
45 
46 namespace nrt
47 {
48  //! A bounded thread pool with a shared work queue
49  /*! This thread pool consists of some fixed number of threads which
50  attempt to get jobs from a work queue, sleeping while they have no
51  work to do.
52 
53  The work queue is shared amongst all threads.
54 
55  Based off of an implementation in C++ Concurrency in Action: Practical Multithreading
56  by Anthony Williams */
58  {
59  public:
60  BoundedThreadPool( size_t const numThreads = std::thread::hardware_concurrency() );
61 
63 
64  template <class Func>
65  std::future<typename std::result_of<Func()>::type>
66  pushJob( Func f );
67 
68  protected:
69  void workerThread();
70 
71  private:
72  std::atomic_bool itsDoWork;
74 
75  std::vector<std::thread> itsThreads;
76  ThreadJoiner<std::vector> itsThreadJoiner;
77  };
78 
79 // Clang does not support thread_local as of clang version 3.3 (trunk 178896) (llvm/trunk 178895)
80 #ifndef __clang__
81 
82  //! A bounded thread pool with thread local work queues
83  /*! This thread pool consists of some fixed number of threads which
84  attempt to get jobs from a work queue, sleeping while they have no
85  work to do.
86 
87  Each thread will first attempt to use its own work queue for jobs before
88  looking in a shared work queue amongst all jobs. Threads will also attempt
89  to steal jobs from other thread local job queues if they have no work to do.
90 
91  Based off of an implementation in C++ Concurrency in Action: Practical Multithreading
92  by Anthony Williams */
94  {
95  public:
96  BoundedLocalQueueThreadPool( size_t const numThreads = std::thread::hardware_concurrency() );
97 
99 
100  template <class Func>
101  std::future<typename std::result_of<Func()>::type>
102  pushJob( Func f );
103 
104  void runPendingTask();
105 
106  protected:
107  void workerThread( size_t index );
108 
109  bool popTaskFromLocalQueue( FunctionWrapper & task );
110 
111  bool popTaskFromPoolQueue( FunctionWrapper & task );
112 
113  bool popTaskFromOtherThreadQueue( FunctionWrapper & task );
114 
115  private:
116  std::atomic_bool itsDoWork;
118 
119  std::vector<std::unique_ptr<WorkStealingQueue>> itsQueues;
120 
121  static thread_local WorkStealingQueue * itsLocalWorkQueue;
122  static thread_local size_t itsIndex;
123 
124  std::vector<std::thread> itsThreads;
125  ThreadJoiner<std::vector> itsThreadJoiner;
126  };
127 #endif // ifndef __clang__
128 
129  //! An unbounded thread pool with a shared work queue
130  /*! This is a version of BoundedThreadPool that grows automatically as new jobs
131  are pushed onto the thread pool. */
133  {
134  public:
135  UnboundedThreadPool( size_t const initialThreads = std::thread::hardware_concurrency(), size_t const maxThreads = std::numeric_limits<size_t>::max() );
136 
138 
139  template <class Func>
140  std::future<typename std::result_of<Func()>::type>
141  pushJob( Func f );
142 
143  protected:
144  void workerThread();
145  void checkAndIncrease();
146 
147  private:
148  std::atomic_bool itsDoWork;
150 
151  std::vector<std::thread> itsThreads;
152  ThreadJoiner<std::vector> itsThreadJoiner;
153 
154  size_t itsMaxThreads;
155  std::atomic<size_t> itsNumActiveThreads;
156  std::mutex itsResizeMutex;
157  };
158 
159 // Clang does not support thread_local as of clang version 3.3 (trunk 178896) (llvm/trunk 178895)
160 #ifndef __clang__
161  //! An unbounded thread pool with thread local work queues
162  /*! This is a version of BoundedThreadPool that grows automatically as new jobs
163  are pushed onto the thread pool. */
165  {
166  public:
167  UnboundedLocalQueueThreadPool( size_t const initialThreads = std::thread::hardware_concurrency(), size_t const maxThreads = std::numeric_limits<size_t>::max() );
168 
170 
171  template <class Func>
172  std::future<typename std::result_of<Func()>::type>
173  pushJob( Func f );
174 
175  void runPendingTask();
176 
177  protected:
178  void checkAndIncrease();
179 
180  void workerThread( size_t index );
181 
182  bool popTaskFromLocalQueue( FunctionWrapper & task );
183 
184  bool popTaskFromPoolQueue( FunctionWrapper & task );
185 
186  bool popTaskFromOtherThreadQueue( FunctionWrapper & task );
187 
188  private:
189  std::atomic_bool itsDoWork;
191 
192  std::vector<std::unique_ptr<WorkStealingQueue>> itsQueues;
193 
194  static thread_local WorkStealingQueue * itsLocalWorkQueue;
195  static thread_local size_t itsIndex;
196 
197  std::vector<std::thread> itsThreads;
198  ThreadJoiner<std::vector> itsThreadJoiner;
199 
200  size_t itsMaxThreads;
201  std::atomic<size_t> itsNumActiveThreads;
202  std::mutex itsResizeMutex;
203  };
204 #endif // ifndef __clang__
205 } // namespace nrt
206 
208 
209 #endif // INCLUDE_NRT_CORE_DESIGN_THREADPOOLS_H
210