libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
pool_thread.hpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2004 by J.M.McGuiness, coder@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE { namespace ppd { namespace pool { namespace private_ { namespace thread_types {
20 
21  template<class PTT, class QM>
23  public:
24  using queue_model=QM;
26  typedef typename base_t::os_traits os_traits;
28  typedef typename os_traits::lock_traits lock_traits;
30  using signalled_work_queue_type=typename PTT::template pool_thread_queue_details<QM>::container_type;
31  using statistics_type=typename PTT::template statistics_type<QM>;
32  using exit_requested_type=typename base_t::exit_requested_type;
34 
35  constexpr __stdcall steal(exit_requested_type &, signalled_work_queue_type &) noexcept(true) {}
36 
37  statistics_type const &__fastcall FORCE_INLINE
38  statistics() const noexcept(true) {
39  return statistics_;
40  }
41 
42  private:
43  statistics_type statistics_;
44 
45  typename thread_traits::api_params_type::states __fastcall FORCE_INLINE
46  process() noexcept(true) override {
47  return thread_traits::api_params_type::no_kernel_thread;
48  }
49  };
50 
51  template<class PTT>
54  public:
56  typedef pool_thread<thread_os_traits<generic_traits::api_type::posix_pthreads, heavyweight_threading>, typename PTT::template pool_thread_queue_details<queue_model>::exit_requested_type> base_t;
57  typedef typename base_t::os_traits os_traits;
59  typedef typename os_traits::lock_traits lock_traits;
61  using batch_type=typename PTT::template pool_thread_queue_details<queue_model>;
62  using statistics_type=typename batch_type::statistics_type;
63  using signalled_work_queue_type=typename batch_type::container_type;
64  using exit_requested_type=typename base_t::exit_requested_type;
66 
67  __stdcall steal(exit_requested_type &, signalled_work_queue_type &) noexcept(true) FORCE_INLINE;
68  ~steal() noexcept(false) FORCE_INLINE;
69 
70  bool __fastcall add_work_to_batch(typename signalled_work_queue_type::value_type &&wk) FORCE_INLINE;
71  bool __fastcall process_a_batch_item(typename os_traits::thread_exception const &exception_thrown_in_thread) FORCE_INLINE;
72 
73  statistics_type const &__fastcall FORCE_INLINE
74  statistics() const noexcept(true) {
75  return batch.statistics();
76  }
77 
78  private:
79  batch_type batch;
80 
81  typename thread_traits::api_params_type::states __fastcall process() noexcept(false) override;
82  };
83 
84  template<class PTT>
87  public:
89  typedef pool_thread<thread_os_traits<generic_traits::api_type::posix_pthreads, heavyweight_threading>, typename PTT::template pool_thread_queue_details<queue_model>::exit_requested_type> base_t;
90  typedef typename base_t::os_traits os_traits;
92  typedef typename os_traits::lock_traits lock_traits;
94  using container_type=typename PTT::template pool_thread_queue_details<queue_model>;
95  using statistics_type=typename container_type::statistics_type;
96  using signalled_work_queue_type=typename container_type::container_type;
97  using exit_requested_type=typename base_t::exit_requested_type;
99 
100  explicit steal(exit_requested_type &) noexcept(true) FORCE_INLINE;
101  ~steal() noexcept(false) FORCE_INLINE;
102 
103  bool __fastcall push_front(typename signalled_work_queue_type::value_type &&wk) FORCE_INLINE;
104  bool __fastcall process_a_batch_item(typename os_traits::thread_exception const &exception_thrown_in_thread) FORCE_INLINE;
105 
106  statistics_type const &__fastcall FORCE_INLINE
107  statistics() const noexcept(true) {
108  return work.statistics();
109  }
110 
111  private:
112  container_type work;
113 
114  typename thread_traits::api_params_type::states __fastcall process() noexcept(false) override;
115  };
116 
117  template<class PTT>
119  : public pool_thread<thread_os_traits<generic_traits::api_type::posix_pthreads, sequential_mode>, typename PTT::template pool_thread_queue_details<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>::exit_requested_type>, public sp_counter_type<long, thread_os_traits<generic_traits::api_type::posix_pthreads, sequential_mode>::lock_traits> {
120  public:
123  typedef typename base_t::os_traits os_traits;
125  typedef typename os_traits::lock_traits lock_traits;
128  using signalled_work_queue_type=typename PTT::template pool_thread_queue_details<queue_model>::container_type;
129  using statistics_type=typename PTT::template pool_thread_queue_details<queue_model>::statistics_type;
130  using exit_requested_type=typename base_t::exit_requested_type;
131  using deleter_t=default_delete<slave>;
133 
134  __stdcall slave(exit_requested_type &exit_requested, typename signalled_work_queue_type::value_type &) noexcept(true) FORCE_INLINE
135  : base_t(exit_requested) {
136  }
137  ~slave() noexcept(true) FORCE_INLINE {}
138 
139  statistics_type const &__fastcall FORCE_INLINE
140  statistics() const noexcept(true) {
141  return statistics_;
142  }
143 
144  private:
145  statistics_type statistics_;
146 
147  typename thread_traits::api_params_type::states __fastcall FORCE_INLINE
148  process() noexcept(true) override {
149  return thread_traits::api_params_type::no_kernel_thread;
150  }
151  };
152 
153  template<class PTT>
155  : public pool_thread<thread_os_traits<generic_traits::api_type::posix_pthreads, heavyweight_threading>, typename PTT::template pool_thread_queue_details<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>::exit_requested_type>, public sp_counter_type<long, thread_os_traits<generic_traits::api_type::posix_pthreads, heavyweight_threading>::lock_traits> {
156  public:
159  typedef typename base_t::os_traits os_traits;
161  typedef typename os_traits::lock_traits lock_traits;
164  using signalled_work_queue_type=typename PTT::template pool_thread_queue_details<queue_model>::container_type;
165  using statistics_type=typename PTT::template pool_thread_queue_details<queue_model>::statistics_type;
166  using exit_requested_type=typename base_t::exit_requested_type;
167  using deleter_t=default_delete<slave>;
169 
170  __stdcall slave(exit_requested_type &exit_requested, typename signalled_work_queue_type::value_type &&wk) noexcept(true) FORCE_INLINE;
171  ~slave() noexcept(true) FORCE_INLINE;
172 
173  statistics_type const &__fastcall statistics() const noexcept(true) {
174  return statistics_;
175  }
176 
177  private:
178  typename signalled_work_queue_type::value_type some_work;
179  statistics_type statistics_;
180 
181  typename thread_traits::api_params_type::states __fastcall process() noexcept(false) override FORCE_INLINE;
182  };
183 
184  /**
185  You can report back exceptions from this thread wrapper type. Oh - and make sure you construct the execution_context too (because you get the exceptions through that type).
186  */
187  template<class PTT, class QM>
190  public:
191  using queue_model=QM;
193  typedef typename base_t::os_traits os_traits;
195  typedef typename os_traits::lock_traits lock_traits;
197  using signalled_work_queue_type=typename PTT::template pool_thread_queue_details<QM>::container_type;
198  using statistics_type=typename signalled_work_queue_type::statistics_type;
199  using exit_requested_type=typename base_t::exit_requested_type;
201 
202  constexpr __stdcall steal(exit_requested_type &, signalled_work_queue_type &) noexcept(true) {}
203 
204  statistics_type const &__fastcall FORCE_INLINE
205  statistics() const noexcept(true) {
206  return statistics_;
207  }
208 
209  private:
210  statistics_type statistics_;
211 
212  typename thread_traits::api_params_type::states __fastcall FORCE_INLINE
213  process() noexcept(true) override {
214  return thread_traits::api_params_type::no_kernel_thread;
215  }
216  };
217 
218  /**
219  You can report back exceptions from this thread wrapper type. Oh - and make sure you construct the execution_context too (because you get the exceptions through that type).
220  */
221  template<class PTT>
224  public:
226  using base_t=pool_thread<thread_os_traits<generic_traits::api_type::posix_pthreads, heavyweight_threading>, typename PTT::template pool_thread_queue_details<queue_model>::exit_requested_type>;
227  using os_traits=typename base_t::os_traits;
228  using model_type=typename os_traits::thread_traits::model_type;
229  using lock_traits=typename os_traits::lock_traits;
230  using thread_traits=typename os_traits::thread_traits;
231  using batch_type=typename PTT::template pool_thread_queue_details<queue_model>;
232  using statistics_type=typename batch_type::statistics_type;
233  using signalled_work_queue_type=typename batch_type::container_type;
234  using exit_requested_type=typename base_t::exit_requested_type;
236 
237  __stdcall steal(exit_requested_type &, signalled_work_queue_type &) noexcept(true) FORCE_INLINE;
238  ~steal() noexcept(false) FORCE_INLINE;
239 
240  bool __fastcall add_work_to_batch(typename signalled_work_queue_type::value_type &&wk) FORCE_INLINE;
241  bool __fastcall process_a_batch_item(typename os_traits::thread_exception const &exception_thrown_in_thread) FORCE_INLINE;
242 
243  statistics_type const &__fastcall FORCE_INLINE
244  statistics() const noexcept(true) {
245  return batch.statistics();
246  }
247 
248  private:
249  batch_type batch;
250 
251  typename thread_traits::api_params_type::states __fastcall process() noexcept(false) override;
252  };
253 
254  /**
255  You can report back exceptions from this thread wrapper type. Oh - and make sure you construct the execution_context too (because you get the exceptions through that type).
256  */
257  template<class PTT>
260  public:
263  typedef typename base_t::os_traits os_traits;
265  typedef typename os_traits::lock_traits lock_traits;
267  using container_type=typename PTT::template pool_thread_queue_details<queue_model>;
268  using statistics_type=typename container_type::statistics_type;
269  using signalled_work_queue_type=typename container_type::container_type;
270  using exit_requested_type=typename base_t::exit_requested_type;
272 
273  explicit steal(exit_requested_type &) noexcept(true) FORCE_INLINE;
274  steal(steal &&) noexcept(true) FORCE_INLINE;
275  ~steal() noexcept(false) FORCE_INLINE;
276 
277  bool __fastcall push_front(typename signalled_work_queue_type::value_type &&wk) FORCE_INLINE;
278  bool __fastcall process_a_batch_item(typename os_traits::thread_exception const &exception_thrown_in_thread) FORCE_INLINE;
279 
280  statistics_type const &__fastcall FORCE_INLINE
281  statistics() const noexcept(true) {
282  return work.statistics();
283  }
284 
285  private:
286  container_type work;
287 
288  typename thread_traits::api_params_type::states __fastcall process() noexcept(false) override;
289  };
290 
291  /**
292  \todo JMG: Looks like this needs completing, as some fns are undefined! Maybe not used...
293  */
294  template<class PTT>
296  : public pool_thread<thread_os_traits<generic_traits::api_type::posix_pthreads, sequential_mode>, typename PTT::template pool_thread_queue_details<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>::exit_requested_type>, public sp_counter_type<long, thread_os_traits<generic_traits::api_type::posix_pthreads, sequential_mode>::lock_traits> {
297  public:
300  typedef typename base_t::os_traits os_traits;
302  typedef typename os_traits::lock_traits lock_traits;
305  using signalled_work_queue_type=typename PTT::template pool_thread_queue_details<queue_model>::container_type;
306  using statistics_type=typename PTT::template statistics_type<queue_model>;
307  using exit_requested_type=typename base_t::exit_requested_type;
308  using deleter_t=default_delete<slave>;
310 
311  __stdcall slave(exit_requested_type &exit_requested, typename signalled_work_queue_type::value_type &&wk) noexcept(true) FORCE_INLINE
312  : base_t(exit_requested), some_work(wk) {
313  }
314  ~slave() noexcept(true) FORCE_INLINE {}
315 
316  statistics_type const &__fastcall FORCE_INLINE
317  statistics() const noexcept(true) {
318  return statistics_;
319  }
320 
321  private:
322  typename signalled_work_queue_type::value_type some_work;
323  statistics_type statistics_;
324 
325  typename thread_traits::api_params_type::states __fastcall FORCE_INLINE
326  process() noexcept(true) override {
327  return thread_traits::api_params_type::no_kernel_thread;
328  }
329  };
330 
331  template<class PTT>
333  : public pool_thread<thread_os_traits<generic_traits::api_type::posix_pthreads, heavyweight_threading>, typename PTT::template pool_thread_queue_details<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>::exit_requested_type>, public sp_counter_type<long, thread_os_traits<generic_traits::api_type::posix_pthreads, heavyweight_threading>::lock_traits> {
334  public:
337  typedef typename base_t::os_traits os_traits;
339  typedef typename os_traits::lock_traits lock_traits;
342  using signalled_work_queue_type=typename PTT::template pool_thread_queue_details<queue_model>::container_type;
343  using statistics_type=typename PTT::template statistics_type<queue_model>;
344  using exit_requested_type=typename base_t::exit_requested_type;
345  using deleter_t=default_delete<slave>;
347 
348  __stdcall slave(exit_requested_type &exit_requested, typename signalled_work_queue_type::value_type &&wk) noexcept(true) FORCE_INLINE;
349  ~slave() noexcept(true) FORCE_INLINE;
350 
351  statistics_type const &__fastcall FORCE_INLINE
352  statistics() const noexcept(true) {
353  return statistics_;
354  }
355 
356  private:
357  typename signalled_work_queue_type::value_type some_work;
358  statistics_type statistics_;
359 
360  typename thread_traits::api_params_type::states __fastcall process() noexcept(false) override FORCE_INLINE;
361  };
362 
363 } } } } } }
364 
365 #include "pool_thread_impl.hpp"