Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
task_arena.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2018 Intel Corporation
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 
16 
17 
18 
19 */
20 
21 #ifndef __TBB_task_arena_H
22 #define __TBB_task_arena_H
23 
24 #include "task.h"
25 #include "tbb_exception.h"
27 #if TBB_USE_THREADING_TOOLS
28 #include "atomic.h" // for as_atomic
29 #endif
30 #include "aligned_space.h"
31 
32 namespace tbb {
33 
34 namespace this_task_arena {
35  int max_concurrency();
36 } // namespace this_task_arena
37 
39 namespace internal {
41 
42  class arena;
44 } // namespace internal
46 
47 namespace interface7 {
48 class task_arena;
49 
51 namespace internal {
52 using namespace tbb::internal; //e.g. function_task from task.h
53 
55 public:
56  virtual void operator()() const = 0;
57  virtual ~delegate_base() {}
58 };
59 
60 // If decltype is availabe, the helper detects the return type of functor of specified type,
61 // otherwise it defines the void type.
62 template <typename F>
64 #if __TBB_CPP11_DECLTYPE_PRESENT && !__TBB_CPP11_DECLTYPE_OF_FUNCTION_RETURN_TYPE_BROKEN
65  typedef decltype(declval<F>()()) type;
66 #else
67  typedef void type;
68 #endif
69 };
70 
71 template<typename F, typename R>
73  F &my_func;
75  // The function should be called only once.
76  void operator()() const __TBB_override {
77  new (my_return_storage.begin()) R(my_func());
78  }
79 public:
80  delegated_function(F& f) : my_func(f) {}
81  // The function can be called only after operator() and only once.
82  R consume_result() const {
83  return tbb::internal::move(*(my_return_storage.begin()));
84  }
86  my_return_storage.begin()->~R();
87  }
88 };
89 
90 template<typename F>
92  F &my_func;
93  void operator()() const __TBB_override {
94  my_func();
95  }
96 public:
97  delegated_function(F& f) : my_func(f) {}
98  void consume_result() const {}
99 
100  friend class task_arena_base;
101 };
102 
104 protected:
106  internal::arena* my_arena;
107 
108 #if __TBB_TASK_GROUP_CONTEXT
109  task_group_context *my_context;
111 #endif
112 
115 
117  unsigned my_master_slots;
118 
121 
122  enum {
123  default_flags = 0
124 #if __TBB_TASK_GROUP_CONTEXT
126  , exact_exception_flag = task_group_context::exact_exception // used to specify flag for context directly
127 #endif
128  };
129 
130  task_arena_base(int max_concurrency, unsigned reserved_for_masters)
131  : my_arena(0)
133  , my_context(0)
134 #endif
135  , my_max_concurrency(max_concurrency)
136  , my_master_slots(reserved_for_masters)
137  , my_version_and_traits(default_flags)
138  {}
139 
140  void __TBB_EXPORTED_METHOD internal_initialize();
141  void __TBB_EXPORTED_METHOD internal_terminate();
142  void __TBB_EXPORTED_METHOD internal_attach();
143  void __TBB_EXPORTED_METHOD internal_enqueue( task&, intptr_t ) const;
144  void __TBB_EXPORTED_METHOD internal_execute( delegate_base& ) const;
145  void __TBB_EXPORTED_METHOD internal_wait() const;
146  static int __TBB_EXPORTED_FUNC internal_current_slot();
147  static int __TBB_EXPORTED_FUNC internal_max_concurrency( const task_arena * );
148 public:
150  static const int automatic = -1;
151  static const int not_initialized = -2;
152 
153 };
154 
155 #if __TBB_TASK_ISOLATION
156 void __TBB_EXPORTED_FUNC isolate_within_arena( delegate_base& d, intptr_t reserved = 0 );
157 
158 template<typename R, typename F>
159 R isolate_impl(F& f) {
162  return d.consume_result();
163 }
164 #endif /* __TBB_TASK_ISOLATION */
165 } // namespace internal
167 
173 class task_arena : public internal::task_arena_base {
178  __TBB_ASSERT( my_arena, "task_arena initialization is incomplete" );
179 #if __TBB_TASK_GROUP_CONTEXT
180  __TBB_ASSERT( my_context, "task_arena initialization is incomplete" );
181 #endif
182 #if TBB_USE_THREADING_TOOLS
183  // Actual synchronization happens in internal_initialize & internal_attach.
184  // The race on setting my_initialized is benign, but should be hidden from Intel(R) Inspector
185  internal::as_atomic(my_initialized).fetch_and_store<release>(true);
186 #else
187  my_initialized = true;
188 #endif
189  }
190 
191  template<typename F>
194  , priority_t p = priority_t(0)
195 #endif
196  ) {
197 #if !__TBB_TASK_PRIORITY
198  intptr_t p = 0;
199 #endif
200  initialize();
201 #if __TBB_TASK_GROUP_CONTEXT
202  internal_enqueue(*new(task::allocate_root(*my_context)) internal::function_task< typename internal::strip<F>::type >(internal::forward<F>(f)), p);
203 #else
204  internal_enqueue(*new(task::allocate_root()) internal::function_task< typename internal::strip<F>::type >(internal::forward<F>(f)), p);
205 #endif /* __TBB_TASK_GROUP_CONTEXT */
206  }
207 
208  template<typename R, typename F>
209  R execute_impl(F& f) {
210  initialize();
211  internal::delegated_function<F, R> d(f);
212  internal_execute(d);
213  return d.consume_result();
214  }
215 
216 public:
218 
223  task_arena(int max_concurrency_ = automatic, unsigned reserved_for_masters = 1)
224  : task_arena_base(max_concurrency_, reserved_for_masters)
225  , my_initialized(false)
226  {}
227 
229  task_arena(const task_arena &s) // copy settings but not the reference or instance
230  : task_arena_base(s.my_max_concurrency, s.my_master_slots)
231  , my_initialized(false)
232  {}
233 
235  struct attach {};
236 
238  explicit task_arena( attach )
239  : task_arena_base(automatic, 1) // use default settings if attach fails
240  , my_initialized(false)
241  {
242  internal_attach();
243  if( my_arena ) my_initialized = true;
244  }
245 
247  inline void initialize() {
248  if( !my_initialized ) {
249  internal_initialize();
250  mark_initialized();
251  }
252  }
253 
255  inline void initialize(int max_concurrency_, unsigned reserved_for_masters = 1) {
256  // TODO: decide if this call must be thread-safe
257  __TBB_ASSERT(!my_arena, "Impossible to modify settings of an already initialized task_arena");
258  if( !my_initialized ) {
259  my_max_concurrency = max_concurrency_;
260  my_master_slots = reserved_for_masters;
261  initialize();
262  }
263  }
264 
266  inline void initialize(attach) {
267  // TODO: decide if this call must be thread-safe
268  __TBB_ASSERT(!my_arena, "Impossible to modify settings of an already initialized task_arena");
269  if( !my_initialized ) {
270  internal_attach();
271  if ( !my_arena ) internal_initialize();
272  mark_initialized();
273  }
274  }
275 
278  inline void terminate() {
279  if( my_initialized ) {
280  internal_terminate();
281  my_initialized = false;
282  }
283  }
284 
288  terminate();
289  }
290 
293  bool is_active() const { return my_initialized; }
294 
297 
298 #if __TBB_CPP11_RVALUE_REF_PRESENT
299  template<typename F>
300  void enqueue( F&& f ) {
301  enqueue_impl(std::forward<F>(f));
302  }
303 #else
304  template<typename F>
305  void enqueue( const F& f ) {
306  enqueue_impl(f);
307  }
308 #endif
309 
310 #if __TBB_TASK_PRIORITY
311  template<typename F>
314 #if __TBB_CPP11_RVALUE_REF_PRESENT
315  void enqueue( F&& f, priority_t p ) {
316  __TBB_ASSERT(p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value");
317  enqueue_impl(std::forward<F>(f), p);
318  }
319 #else
320  void enqueue( const F& f, priority_t p ) {
321  __TBB_ASSERT(p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value");
322  enqueue_impl(f,p);
323  }
324 #endif
325 #endif// __TBB_TASK_PRIORITY
326 
331  template<typename F>
334  }
335 
340  template<typename F>
343  }
344 
345 #if __TBB_EXTRA_DEBUG
346  void debug_wait_until_empty() {
350  initialize();
351  internal_wait();
352  }
353 #endif //__TBB_EXTRA_DEBUG
354 
357  inline static int current_thread_index() {
358  return internal_current_slot();
359  }
360 
362  inline int max_concurrency() const {
363  // Handle special cases inside the library
364  return (my_max_concurrency>1) ? my_max_concurrency : internal_max_concurrency(this);
365  }
366 };
367 
368 #if __TBB_TASK_ISOLATION
369 namespace this_task_arena {
372  template<typename F>
375  }
376 
379  template<typename F>
382  }
383 }
384 #endif /* __TBB_TASK_ISOLATION */
385 } // namespace interfaceX
386 
387 using interface7::task_arena;
388 #if __TBB_TASK_ISOLATION
389 namespace this_task_arena {
390  using namespace interface7::this_task_arena;
391 }
392 #endif /* __TBB_TASK_ISOLATION */
393 
394 namespace this_task_arena {
396  inline int current_thread_index() {
398  return idx == -1 ? tbb::task_arena::not_initialized : idx;
399  }
400 
402  inline int max_concurrency() {
404  }
405 } // namespace this_task_arena
406 
407 } // namespace tbb
408 
409 #endif /* __TBB_task_arena_H */
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type type
Base class for user-defined tasks.
Definition: task.h:576
#define __TBB_EXPORTED_FUNC
atomic< T > & as_atomic(T &t)
Definition: atomic.h:547
void const char const char int ITT_FORMAT __itt_group_sync s
Identifiers declared inside namespace internal should never be used directly by client code.
Definition: atomic.h:55
decltype(declval< F >()()) typedef type
Definition: task_arena.h:65
#define __TBB_TASK_PRIORITY
Definition: tbb_config.h:569
#define __TBB_EXPORTED_METHOD
Definition: tbb_stddef.h:102
#define __TBB_FORWARDING_REF(A)
Definition: tbb_stddef.h:509
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
Release.
Definition: atomic.h:49
#define __TBB_override
Definition: tbb_stddef.h:244
void const char const char int ITT_FORMAT __itt_group_sync p
int max_concurrency()
Returns the maximal number of threads that can work inside the arena.
Definition: task_arena.h:402
Tag class used to indicate the "attaching" constructor.
Definition: task_arena.h:235
void enqueue_impl(__TBB_FORWARDING_REF(F) f, priority_t p=priority_t(0))
Definition: task_arena.h:192
task_arena(const task_arena &s)
Copies settings from another task_arena.
Definition: task_arena.h:229
Base class for types that should not be assigned.
Definition: tbb_stddef.h:324
void initialize(int max_concurrency_, unsigned reserved_for_masters=1)
Overrides concurrency level and forces initialization of internal representation.
Definition: task_arena.h:255
intptr_t my_version_and_traits
Special settings.
Definition: task_arena.h:120
task_arena_base(int max_concurrency, unsigned reserved_for_masters)
Definition: task_arena.h:130
int my_max_concurrency
Concurrency level for deferred initialization.
Definition: task_arena.h:114
tbb::aligned_space< R > my_return_storage
Definition: task_arena.h:74
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d
void __TBB_EXPORTED_FUNC isolate_within_arena(delegate_base &d, intptr_t reserved=0)
Used to form groups of tasks.
Definition: task.h:319
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309
internal::arena * my_arena
NULL if not currently initialized.
Definition: task_arena.h:106
task_arena(int max_concurrency_=automatic, unsigned reserved_for_masters=1)
Creates task_arena with certain concurrency limits.
Definition: task_arena.h:223
internal::return_type_or_void< F >::type execute(const F &f)
Definition: task_arena.h:341
void initialize()
Forces allocation of the resources for the task_arena as specified in constructor arguments.
Definition: task_arena.h:247
unsigned my_master_slots
Reserved master slots.
Definition: task_arena.h:117
internal::return_type_or_void< F >::type isolate(const F &f)
Definition: task_arena.h:380
T * begin() const
Pointer to beginning of array.
Definition: aligned_space.h:39
The graph class.
internal::return_type_or_void< F >::type execute(F &f)
Definition: task_arena.h:332
int max_concurrency() const
Returns the maximal number of threads that can work inside the arena.
Definition: task_arena.h:362
static int current_thread_index()
Definition: task_arena.h:357
static internal::allocate_root_proxy allocate_root()
Returns proxy for overloaded new that allocates a root task.
Definition: task.h:620
task_arena(attach)
Creates an instance of task_arena attached to the current arena of the thread.
Definition: task_arena.h:238
int current_thread_index()
Returns the index, aka slot number, of the calling thread in its current arena.
Definition: task_arena.h:396
static int __TBB_EXPORTED_FUNC internal_max_concurrency(const task_arena *)
Definition: arena.cpp:998
#define __TBB_TASK_GROUP_CONTEXT
Definition: tbb_config.h:535
void operator()() const __TBB_override
Definition: task_arena.h:76
void initialize(attach)
Attaches this instance to the current arena of the thread.
Definition: task_arena.h:266
priority_t
Definition: task.h:279
void enqueue(F &&f, priority_t p)
Definition: task_arena.h:315

Copyright © 2005-2018 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.