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-2019 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 #if __TBB_PREVIEW_CRITICAL_TASKS
318  || p == internal::priority_critical, "Invalid priority level value");
319 #else
320  __TBB_ASSERT(p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value");
321 #endif
322  enqueue_impl(std::forward<F>(f), p);
323  }
324 #else
325  void enqueue( const F& f, priority_t p ) {
326 #if __TBB_PREVIEW_CRITICAL_TASKS
328  || p == internal::priority_critical, "Invalid priority level value");
329 #else
330  __TBB_ASSERT(p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value");
331 #endif
332  enqueue_impl(f,p);
333  }
334 #endif
335 #endif// __TBB_TASK_PRIORITY
336 
341  template<typename F>
344  }
345 
350  template<typename F>
353  }
354 
355 #if __TBB_EXTRA_DEBUG
356  void debug_wait_until_empty() {
360  initialize();
361  internal_wait();
362  }
363 #endif //__TBB_EXTRA_DEBUG
364 
367  inline static int current_thread_index() {
368  return internal_current_slot();
369  }
370 
372  inline int max_concurrency() const {
373  // Handle special cases inside the library
374  return (my_max_concurrency>1) ? my_max_concurrency : internal_max_concurrency(this);
375  }
376 };
377 
378 #if __TBB_TASK_ISOLATION
379 namespace this_task_arena {
382  template<typename F>
385  }
386 
389  template<typename F>
392  }
393 }
394 #endif /* __TBB_TASK_ISOLATION */
395 } // namespace interfaceX
396 
397 using interface7::task_arena;
398 #if __TBB_TASK_ISOLATION
399 namespace this_task_arena {
400  using namespace interface7::this_task_arena;
401 }
402 #endif /* __TBB_TASK_ISOLATION */
403 
404 namespace this_task_arena {
406  inline int current_thread_index() {
408  return idx == -1 ? tbb::task_arena::not_initialized : idx;
409  }
410 
412  inline int max_concurrency() {
414  }
415 } // namespace this_task_arena
416 
417 } // namespace tbb
418 
419 #endif /* __TBB_task_arena_H */
Tag class used to indicate the "attaching" constructor.
Definition: task_arena.h:235
internal::return_type_or_void< F >::type isolate(const F &f)
Definition: task_arena.h:390
#define __TBB_override
Definition: tbb_stddef.h:244
static int current_thread_index()
Definition: task_arena.h:367
task_arena_base(int max_concurrency, unsigned reserved_for_masters)
Definition: task_arena.h:130
T * begin() const
Pointer to beginning of array.
Definition: aligned_space.h:39
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void operator()() const __TBB_override
Definition: task_arena.h:76
Used to form groups of tasks.
Definition: task.h:335
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
int max_concurrency() const
Returns the maximal number of threads that can work inside the arena.
Definition: task_arena.h:372
decltype(declval< F >()()) typedef type
Definition: task_arena.h:65
task_arena(const task_arena &s)
Copies settings from another task_arena.
Definition: task_arena.h:229
internal::return_type_or_void< F >::type execute(F &f)
Definition: task_arena.h:342
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
#define __TBB_TASK_PRIORITY
Definition: tbb_config.h:576
intptr_t my_version_and_traits
Special settings.
Definition: task_arena.h:120
int my_max_concurrency
Concurrency level for deferred initialization.
Definition: task_arena.h:114
Base class for user-defined tasks.
Definition: task.h:592
task_arena(attach)
Creates an instance of task_arena attached to the current arena of the thread.
Definition: task_arena.h:238
void const char const char int ITT_FORMAT __itt_group_sync p
Base class for types that should not be assigned.
Definition: tbb_stddef.h:324
void enqueue_impl(__TBB_FORWARDING_REF(F) f, priority_t p=priority_t(0))
Definition: task_arena.h:192
void initialize(int max_concurrency_, unsigned reserved_for_masters=1)
Overrides concurrency level and forces initialization of internal representation.
Definition: task_arena.h:255
priority_t
Definition: task.h:295
#define __TBB_EXPORTED_METHOD
Definition: tbb_stddef.h:102
int max_concurrency()
Returns the maximal number of threads that can work inside the arena.
Definition: task_arena.h:412
#define __TBB_FORWARDING_REF(A)
Definition: tbb_stddef.h:500
internal::return_type_or_void< F >::type execute(const F &f)
Definition: task_arena.h:351
The graph class.
void __TBB_EXPORTED_FUNC isolate_within_arena(delegate_base &d, intptr_t reserved=0)
task_arena(int max_concurrency_=automatic, unsigned reserved_for_masters=1)
Creates task_arena with certain concurrency limits.
Definition: task_arena.h:223
unsigned my_master_slots
Reserved master slots.
Definition: task_arena.h:117
#define __TBB_EXPORTED_FUNC
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309
void enqueue(F &&f, priority_t p)
Definition: task_arena.h:315
void const char const char int ITT_FORMAT __itt_group_sync s
void initialize(attach)
Attaches this instance to the current arena of the thread.
Definition: task_arena.h:266
int current_thread_index()
Returns the index, aka slot number, of the calling thread in its current arena.
Definition: task_arena.h:406
internal::arena * my_arena
NULL if not currently initialized.
Definition: task_arena.h:106
static internal::allocate_root_proxy allocate_root()
Returns proxy for overloaded new that allocates a root task.
Definition: task.h:636
static int __TBB_EXPORTED_FUNC internal_max_concurrency(const task_arena *)
Definition: arena.cpp:1046
static const int priority_critical
Definition: task.h:291
Identifiers declared inside namespace internal should never be used directly by client code.
Definition: atomic.h:55
void initialize()
Forces allocation of the resources for the task_arena as specified in constructor arguments.
Definition: task_arena.h:247
Release.
Definition: atomic.h:49
atomic< T > & as_atomic(T &t)
Definition: atomic.h:547
tbb::aligned_space< R > my_return_storage
Definition: task_arena.h:74
#define __TBB_TASK_GROUP_CONTEXT
Definition: tbb_config.h:546

Copyright © 2005-2019 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.