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 #ifndef __TBB_task_arena_H
18 #define __TBB_task_arena_H
19 
20 #include "task.h"
21 #include "tbb_exception.h"
23 #if TBB_USE_THREADING_TOOLS
24 #include "atomic.h" // for as_atomic
25 #endif
26 #include "aligned_space.h"
27 
28 namespace tbb {
29 
30 namespace this_task_arena {
31  int max_concurrency();
32 } // namespace this_task_arena
33 
35 namespace internal {
37 
38  class arena;
40 } // namespace internal
42 
43 namespace interface7 {
44 class task_arena;
45 
47 namespace internal {
48 using namespace tbb::internal; //e.g. function_task from task.h
49 
51 public:
52  virtual void operator()() const = 0;
53  virtual ~delegate_base() {}
54 };
55 
56 // If decltype is available, the helper detects the return type of functor of specified type,
57 // otherwise it defines the void type.
58 template <typename F>
60 #if __TBB_CPP11_DECLTYPE_PRESENT && !__TBB_CPP11_DECLTYPE_OF_FUNCTION_RETURN_TYPE_BROKEN
61  typedef decltype(declval<F>()()) type;
62 #else
63  typedef void type;
64 #endif
65 };
66 
67 template<typename F, typename R>
69  F &my_func;
71  // The function should be called only once.
72  void operator()() const __TBB_override {
73  new (my_return_storage.begin()) R(my_func());
74  }
75 public:
76  delegated_function(F& f) : my_func(f) {}
77  // The function can be called only after operator() and only once.
78  R consume_result() const {
79  return tbb::internal::move(*(my_return_storage.begin()));
80  }
82  my_return_storage.begin()->~R();
83  }
84 };
85 
86 template<typename F>
88  F &my_func;
89  void operator()() const __TBB_override {
90  my_func();
91  }
92 public:
93  delegated_function(F& f) : my_func(f) {}
94  void consume_result() const {}
95 
96  friend class task_arena_base;
97 };
98 
100 protected:
102  internal::arena* my_arena;
103 
104 #if __TBB_TASK_GROUP_CONTEXT
105  task_group_context *my_context;
107 #endif
108 
111 
113  unsigned my_master_slots;
114 
117 
118  enum {
119  default_flags = 0
120 #if __TBB_TASK_GROUP_CONTEXT
122  , exact_exception_flag = task_group_context::exact_exception // used to specify flag for context directly
123 #endif
124  };
125 
126  task_arena_base(int max_concurrency, unsigned reserved_for_masters)
127  : my_arena(0)
129  , my_context(0)
130 #endif
131  , my_max_concurrency(max_concurrency)
132  , my_master_slots(reserved_for_masters)
133  , my_version_and_traits(default_flags)
134  {}
135 
136  void __TBB_EXPORTED_METHOD internal_initialize();
137  void __TBB_EXPORTED_METHOD internal_terminate();
138  void __TBB_EXPORTED_METHOD internal_attach();
139  void __TBB_EXPORTED_METHOD internal_enqueue( task&, intptr_t ) const;
140  void __TBB_EXPORTED_METHOD internal_execute( delegate_base& ) const;
141  void __TBB_EXPORTED_METHOD internal_wait() const;
142  static int __TBB_EXPORTED_FUNC internal_current_slot();
143  static int __TBB_EXPORTED_FUNC internal_max_concurrency( const task_arena * );
144 public:
146  static const int automatic = -1;
147  static const int not_initialized = -2;
148 
149 };
150 
151 #if __TBB_TASK_ISOLATION
152 void __TBB_EXPORTED_FUNC isolate_within_arena( delegate_base& d, intptr_t reserved = 0 );
153 
154 template<typename R, typename F>
155 R isolate_impl(F& f) {
158  return d.consume_result();
159 }
160 #endif /* __TBB_TASK_ISOLATION */
161 } // namespace internal
163 
169 class task_arena : public internal::task_arena_base {
171  friend void task::enqueue(task&, task_arena&
173  , priority_t
174 #endif
175  );
179  __TBB_ASSERT( my_arena, "task_arena initialization is incomplete" );
180 #if __TBB_TASK_GROUP_CONTEXT
181  __TBB_ASSERT( my_context, "task_arena initialization is incomplete" );
182 #endif
183 #if TBB_USE_THREADING_TOOLS
184  // Actual synchronization happens in internal_initialize & internal_attach.
185  // The race on setting my_initialized is benign, but should be hidden from Intel(R) Inspector
186  internal::as_atomic(my_initialized).fetch_and_store<release>(true);
187 #else
188  my_initialized = true;
189 #endif
190  }
191 
192  template<typename F>
195  , priority_t p = priority_t(0)
196 #endif
197  ) {
198 #if !__TBB_TASK_PRIORITY
199  intptr_t p = 0;
200 #endif
201  initialize();
202 #if __TBB_TASK_GROUP_CONTEXT
203  internal_enqueue(*new(task::allocate_root(*my_context)) internal::function_task< typename internal::strip<F>::type >(internal::forward<F>(f)), p);
204 #else
205  internal_enqueue(*new(task::allocate_root()) internal::function_task< typename internal::strip<F>::type >(internal::forward<F>(f)), p);
206 #endif /* __TBB_TASK_GROUP_CONTEXT */
207  }
208 
209  template<typename R, typename F>
210  R execute_impl(F& f) {
211  initialize();
212  internal::delegated_function<F, R> d(f);
213  internal_execute(d);
214  return d.consume_result();
215  }
216 
217 public:
219 
224  task_arena(int max_concurrency_ = automatic, unsigned reserved_for_masters = 1)
225  : task_arena_base(max_concurrency_, reserved_for_masters)
226  , my_initialized(false)
227  {}
228 
230  task_arena(const task_arena &s) // copy settings but not the reference or instance
231  : task_arena_base(s.my_max_concurrency, s.my_master_slots)
232  , my_initialized(false)
233  {}
234 
236  struct attach {};
237 
239  explicit task_arena( attach )
240  : task_arena_base(automatic, 1) // use default settings if attach fails
241  , my_initialized(false)
242  {
243  internal_attach();
244  if( my_arena ) my_initialized = true;
245  }
246 
248  inline void initialize() {
249  if( !my_initialized ) {
250  internal_initialize();
251  mark_initialized();
252  }
253  }
254 
256  inline void initialize(int max_concurrency_, unsigned reserved_for_masters = 1) {
257  // TODO: decide if this call must be thread-safe
258  __TBB_ASSERT(!my_arena, "Impossible to modify settings of an already initialized task_arena");
259  if( !my_initialized ) {
260  my_max_concurrency = max_concurrency_;
261  my_master_slots = reserved_for_masters;
262  initialize();
263  }
264  }
265 
267  inline void initialize(attach) {
268  // TODO: decide if this call must be thread-safe
269  __TBB_ASSERT(!my_arena, "Impossible to modify settings of an already initialized task_arena");
270  if( !my_initialized ) {
271  internal_attach();
272  if ( !my_arena ) internal_initialize();
273  mark_initialized();
274  }
275  }
276 
279  inline void terminate() {
280  if( my_initialized ) {
281  internal_terminate();
282  my_initialized = false;
283  }
284  }
285 
289  terminate();
290  }
291 
294  bool is_active() const { return my_initialized; }
295 
298 
299 #if __TBB_CPP11_RVALUE_REF_PRESENT
300  template<typename F>
301  void enqueue( F&& f ) {
302  enqueue_impl(std::forward<F>(f));
303  }
304 #else
305  template<typename F>
306  void enqueue( const F& f ) {
307  enqueue_impl(f);
308  }
309 #endif
310 
311 #if __TBB_TASK_PRIORITY
312  template<typename F>
315 #if __TBB_CPP11_RVALUE_REF_PRESENT
316  void enqueue( F&& f, priority_t p ) {
317 #if __TBB_PREVIEW_CRITICAL_TASKS
319  || p == internal::priority_critical, "Invalid priority level value");
320 #else
321  __TBB_ASSERT(p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value");
322 #endif
323  enqueue_impl(std::forward<F>(f), p);
324  }
325 #else
326  void enqueue( const F& f, priority_t p ) {
327 #if __TBB_PREVIEW_CRITICAL_TASKS
329  || p == internal::priority_critical, "Invalid priority level value");
330 #else
331  __TBB_ASSERT(p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value");
332 #endif
333  enqueue_impl(f,p);
334  }
335 #endif
336 #endif// __TBB_TASK_PRIORITY
337 
342  template<typename F>
345  }
346 
351  template<typename F>
354  }
355 
356 #if __TBB_EXTRA_DEBUG
357  void debug_wait_until_empty() {
361  initialize();
362  internal_wait();
363  }
364 #endif //__TBB_EXTRA_DEBUG
365 
368  inline static int current_thread_index() {
369  return internal_current_slot();
370  }
371 
373  inline int max_concurrency() const {
374  // Handle special cases inside the library
375  return (my_max_concurrency>1) ? my_max_concurrency : internal_max_concurrency(this);
376  }
377 };
378 
379 #if __TBB_TASK_ISOLATION
380 namespace this_task_arena {
383  template<typename F>
386  }
387 
390  template<typename F>
393  }
394 }
395 #endif /* __TBB_TASK_ISOLATION */
396 } // namespace interfaceX
397 
399 #if __TBB_TASK_ISOLATION
400 namespace this_task_arena {
401  using namespace interface7::this_task_arena;
402 }
403 #endif /* __TBB_TASK_ISOLATION */
404 
405 namespace this_task_arena {
407  inline int current_thread_index() {
409  return idx == -1 ? tbb::task_arena::not_initialized : idx;
410  }
411 
413  inline int max_concurrency() {
415  }
416 } // namespace this_task_arena
417 
421  , priority_t p
422 #endif
423  ) {
424 #if !__TBB_TASK_PRIORITY
425  intptr_t p = 0;
426 #endif
427  arena.initialize();
429  arena.internal_enqueue(t, p);
430 }
431 } // namespace tbb
432 
433 #endif /* __TBB_task_arena_H */
void enqueue_impl(__TBB_FORWARDING_REF(F) f, priority_t p=priority_t(0))
Definition: task_arena.h:193
static const int priority_critical
Definition: task.h:287
#define __TBB_override
Definition: tbb_stddef.h:240
internal::arena * my_arena
NULL if not currently initialized.
Definition: task_arena.h:102
#define __TBB_TASK_PRIORITY
Definition: tbb_config.h:575
#define __TBB_EXPORTED_METHOD
Definition: tbb_stddef.h:98
static internal::allocate_root_proxy allocate_root()
Returns proxy for overloaded new that allocates a root task.
Definition: task.h:633
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:267
task_arena(int max_concurrency_=automatic, unsigned reserved_for_masters=1)
Creates task_arena with certain concurrency limits.
Definition: task_arena.h:224
#define __TBB_EXPORTED_FUNC
void enqueue(F &&f, priority_t p)
Definition: task_arena.h:316
The graph class.
void __TBB_EXPORTED_FUNC isolate_within_arena(delegate_base &d, intptr_t reserved=0)
int max_concurrency()
Returns the maximal number of threads that can work inside the arena.
Definition: task_arena.h:413
unsigned my_master_slots
Reserved master slots.
Definition: task_arena.h:113
void operator()() const __TBB_override
Definition: task_arena.h:72
int max_concurrency() const
Returns the maximal number of threads that can work inside the arena.
Definition: task_arena.h:373
Release.
Definition: atomic.h:45
internal::return_type_or_void< F >::type execute(const F &f)
Definition: task_arena.h:352
task_arena(const task_arena &s)
Copies settings from another task_arena.
Definition: task_arena.h:230
atomic< T > & as_atomic(T &t)
Definition: atomic.h:543
internal::return_type_or_void< F >::type isolate(const F &f)
Definition: task_arena.h:391
static int __TBB_EXPORTED_FUNC internal_max_concurrency(const task_arena *)
Definition: arena.cpp:1042
priority_t
Definition: task.h:291
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
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 move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:305
#define __TBB_TASK_GROUP_CONTEXT
Definition: tbb_config.h:545
tbb::aligned_space< R > my_return_storage
Definition: task_arena.h:70
decltype(declval< F >()()) typedef type
Definition: task_arena.h:61
#define __TBB_FORWARDING_REF(A)
Definition: tbb_stddef.h:496
Used to form groups of tasks.
Definition: task.h:332
static void enqueue(task &t)
Enqueue task for starvation-resistant execution.
Definition: task.h:806
void initialize()
Forces allocation of the resources for the task_arena as specified in constructor arguments...
Definition: task_arena.h:248
T * begin() const
Pointer to beginning of array.
Definition: aligned_space.h:35
int current_thread_index()
Returns the index, aka slot number, of the calling thread in its current arena.
Definition: task_arena.h:407
void initialize(int max_concurrency_, unsigned reserved_for_masters=1)
Overrides concurrency level and forces initialization of internal representation. ...
Definition: task_arena.h:256
internal::return_type_or_void< F >::type execute(F &f)
Definition: task_arena.h:343
Base class for user-defined tasks.
Definition: task.h:589
Identifiers declared inside namespace internal should never be used directly by client code...
Definition: atomic.h:51
task_arena_base(int max_concurrency, unsigned reserved_for_masters)
Definition: task_arena.h:126
Base class for types that should not be assigned.
Definition: tbb_stddef.h:320
task_arena(attach)
Creates an instance of task_arena attached to the current arena of the thread.
Definition: task_arena.h:239
void const char const char int ITT_FORMAT __itt_group_sync p
intptr_t my_version_and_traits
Special settings.
Definition: task_arena.h:116
static int current_thread_index()
Definition: task_arena.h:368
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
int my_max_concurrency
Concurrency level for deferred initialization.
Definition: task_arena.h:110
Tag class used to indicate the "attaching" constructor.
Definition: task_arena.h:236

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.