Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
scheduler.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_scheduler_H
22 #define _TBB_scheduler_H
23 
24 #include "scheduler_common.h"
25 #include "tbb/spin_mutex.h"
26 #include "mailbox.h"
27 #include "tbb_misc.h" // for FastRandom
28 #include "itt_notify.h"
29 #include "../rml/include/rml_tbb.h"
30 
31 #include "intrusive_list.h"
32 
33 #if __TBB_SURVIVE_THREAD_SWITCH
34 #include "cilk-tbb-interop.h"
35 #endif /* __TBB_SURVIVE_THREAD_SWITCH */
36 
37 namespace tbb {
38 namespace internal {
39 
40 template<typename SchedulerTraits> class custom_scheduler;
41 
42 //------------------------------------------------------------------------
43 // generic_scheduler
44 //------------------------------------------------------------------------
45 
46 #define EmptyTaskPool ((task**)0)
47 #define LockedTaskPool ((task**)~(intptr_t)0)
48 
51  static const bool worker = false;
52  static const bool master = true;
54  bool type : 1;
56 
57  bool outermost : 1;
58 #if __TBB_PREVIEW_CRITICAL_TASKS
59  bool has_taken_critical_task : 1;
61 
63  unsigned char : 5;
64 #else
65  unsigned char : 6;
67 #endif /* __TBB_PREVIEW_CRITICAL_TASKS */
68 };
69 
72  size_t my_arena_index; // TODO: make it unsigned and pair with my_affinity_id to fit into cache line
73 
76 
79 
82 
83 
85 
87 
94 
96 
97 #if __TBB_SCHEDULER_OBSERVER
98  observer_proxy* my_last_global_observer;
100 #endif
101 
102 #if __TBB_ARENA_OBSERVER
103  observer_proxy* my_last_local_observer;
105 #endif
106 #if __TBB_TASK_PRIORITY
107 
110  volatile intptr_t *my_ref_top_priority;
111 
113  volatile uintptr_t *my_ref_reload_epoch;
114 #endif /* __TBB_TASK_PRIORITY */
115 };
116 
118 
125  , public ::rml::job
126  , public intrusive_list_node
127  , public scheduler_state {
128 public: // almost every class in TBB uses generic_scheduler
129 
131  static const size_t quick_task_size = 256-task_prefix_reservation_size;
132 
133  static bool is_version_3_task( task& t ) {
134 #if __TBB_PREVIEW_CRITICAL_TASKS
135  return (t.prefix().extra_state & 0x7)>=0x1;
136 #else
137  return (t.prefix().extra_state & 0x0F)>=0x1;
138 #endif
139  }
140 
143 #if __TBB_ipf
144  uintptr_t my_rsb_stealing_threshold;
146 #endif
147 
148  static const size_t null_arena_index = ~size_t(0);
149 
150  inline bool is_task_pool_published () const;
151 
152  inline bool is_local_task_pool_quiescent () const;
153 
154  inline bool is_quiescent_local_task_pool_empty () const;
155 
156  inline bool is_quiescent_local_task_pool_reset () const;
157 
160 
163 
166 
167 #if __TBB_HOARD_NONLOCAL_TASKS
168  task* my_nonlocal_free_list;
170 #endif
171 
174 
176 
178 
179  inline void attach_mailbox( affinity_id id );
180 
181  /* A couple of bools can be located here because space is otherwise just padding after my_affinity_id. */
182 
185 
186 #if __TBB_COUNT_TASK_NODES
187  intptr_t my_task_node_count;
189 #endif /* __TBB_COUNT_TASK_NODES */
190 
192  void init_stack_info ();
193 
195  bool can_steal () {
196  int anchor;
197  // TODO IDEA: Add performance warning?
198 #if __TBB_ipf
199  return my_stealing_threshold < (uintptr_t)&anchor && (uintptr_t)__TBB_get_bsp() < my_rsb_stealing_threshold;
200 #else
201  return my_stealing_threshold < (uintptr_t)&anchor;
202 #endif
203  }
204 
206 
207  void publish_task_pool();
208 
210 
211  void leave_task_pool();
212 
214 
215  inline void reset_task_pool_and_leave ();
216 
218 
219  task** lock_task_pool( arena_slot* victim_arena_slot ) const;
220 
222 
223  void unlock_task_pool( arena_slot* victim_arena_slot, task** victim_task_pool ) const;
224 
226 
228  void acquire_task_pool() const;
229 
231 
233  void release_task_pool() const;
234 
236 
237  task* prepare_for_spawning( task* t );
238 
240  inline void commit_spawned_tasks( size_t new_tail );
241 
243 
244  inline void commit_relocated_tasks( size_t new_tail );
245 
247 
250  task* get_task( __TBB_ISOLATION_EXPR( isolation_tag isolation ) );
251 
253 
258 #if __TBB_TASK_ISOLATION
259  task* get_task( size_t T, isolation_tag isolation, bool& tasks_omitted );
260 #else
261  task* get_task( size_t T );
262 #endif /* __TBB_TASK_ISOLATION */
263 
270  task* get_mailbox_task( __TBB_ISOLATION_EXPR( isolation_tag isolation ) );
271 
273  static bool is_proxy( const task& t ) {
274  return t.prefix().extra_state==es_task_proxy;
275  }
276 
278  task* steal_task( __TBB_ISOLATION_EXPR(isolation_tag isolation) );
279 
281  task* steal_task_from( __TBB_ISOLATION_ARG( arena_slot& victim_arena_slot, isolation_tag isolation ) );
282 
283 #if __TBB_PREVIEW_CRITICAL_TASKS
284  task* get_critical_task( __TBB_ISOLATION_EXPR(isolation_tag isolation) );
286 
289  bool handled_as_critical( task& t );
290 #endif
291 
294  static const size_t min_task_pool_size = 64;
295 
297 
299  size_t prepare_task_pool( size_t n );
300 
302  static generic_scheduler* create_master( arena* a );
303 
305  bool cleanup_master( bool blocking_terminate );
306 
308  static generic_scheduler* create_worker( market& m, size_t index );
309 
311  static void cleanup_worker( void* arg, bool worker );
312 
313 protected:
314  template<typename SchedulerTraits> friend class custom_scheduler;
316 
317 public:
318 #if TBB_USE_ASSERT > 1
319 
321  void assert_task_pool_valid() const;
322 #else
323  void assert_task_pool_valid() const {}
324 #endif /* TBB_USE_ASSERT <= 1 */
325 
326  void attach_arena( arena*, size_t index, bool is_master );
327  void nested_arena_entry( arena*, size_t );
328  void nested_arena_exit();
329  void wait_until_empty();
330 
331  void spawn( task& first, task*& next ) __TBB_override;
332 
333  void spawn_root_and_wait( task& first, task*& next ) __TBB_override;
334 
335  void enqueue( task&, void* reserved ) __TBB_override;
336 
337  void local_spawn( task* first, task*& next );
338  void local_spawn_root_and_wait( task* first, task*& next );
339  virtual void local_wait_for_all( task& parent, task* child ) = 0;
340 
342  void free_scheduler();
343 
345 
346  task& allocate_task( size_t number_of_bytes,
347  __TBB_CONTEXT_ARG(task* parent, task_group_context* context) );
348 
350 
351  template<free_task_hint h>
352  void free_task( task& t );
353 
355  inline void deallocate_task( task& t );
356 
358  inline bool is_worker() const;
359 
361  inline bool outermost_level() const;
362 
364 
367  inline bool master_outermost_level () const;
368 
370  inline bool worker_outermost_level () const;
371 
373  unsigned max_threads_in_arena();
374 
375 #if __TBB_COUNT_TASK_NODES
376  intptr_t get_task_node_count( bool count_arena_workers = false );
377 #endif /* __TBB_COUNT_TASK_NODES */
378 
380  static task* plugged_return_list() {return (task*)(intptr_t)(-1);}
381 
384 
386  // TODO IDEA: see if putting my_return_list on separate cache line improves performance
388 
390 
391  virtual task* receive_or_steal_task( __TBB_ISOLATION_ARG( __TBB_atomic reference_count& completion_ref_count, isolation_tag isolation ) ) = 0;
392 
394  void free_nonlocal_small_task( task& t );
395 
396 #if __TBB_TASK_GROUP_CONTEXT
397 
403  inline task_group_context* default_context ();
404 
406  char _padding1[NFS_MaxLineSize - sizeof(context_list_node_t)];
407 
409  context_list_node_t my_context_list_head;
410 
412  // TODO: check whether it can be deadly preempted and replace by spinning/sleeping mutex
413  spin_mutex my_context_list_mutex;
414 
416 
422  uintptr_t my_context_state_propagation_epoch;
423 
425 
428  tbb::atomic<uintptr_t> my_local_ctx_list_update;
429 
430 #if __TBB_TASK_PRIORITY
431  inline intptr_t effective_reference_priority () const;
433 
434  // TODO: move into slots and fix is_out_of_work
436  task* my_offloaded_tasks;
437 
439  task** my_offloaded_task_list_tail_link;
440 
442  uintptr_t my_local_reload_epoch;
443 
445  volatile bool my_pool_reshuffling_pending;
446 
448 
449  task* reload_tasks( __TBB_ISOLATION_EXPR( isolation_tag isolation ) );
450 
451  task* reload_tasks( task*& offloaded_tasks, task**& offloaded_task_list_link, __TBB_ISOLATION_ARG( intptr_t top_priority, isolation_tag isolation ) );
452 
454 
455  task* winnow_task_pool ( __TBB_ISOLATION_EXPR( isolation_tag isolation ) );
456 
458 
459  task *get_task_and_activate_task_pool( size_t H0 , __TBB_ISOLATION_ARG( size_t T0, isolation_tag isolation ) );
460 
462  inline void offload_task ( task& t, intptr_t task_priority );
463 #endif /* __TBB_TASK_PRIORITY */
464 
466 
467  void cleanup_local_context_list ();
468 
471  template <typename T>
472  void propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state );
473 
474  // check consistency
475  static void assert_context_valid(const task_group_context *tgc) {
477 #if TBB_USE_ASSERT
478  __TBB_ASSERT(tgc, NULL);
479  uintptr_t ctx = tgc->my_version_and_traits;
480  __TBB_ASSERT(is_alive(ctx), "referenced task_group_context was destroyed");
481  static const char *msg = "task_group_context is invalid";
482  __TBB_ASSERT(!(ctx&~(3|(7<<task_group_context::traits_offset))), msg); // the value fits known values of versions and traits
487  __TBB_ASSERT(tgc->my_owner, msg);
488  __TBB_ASSERT(tgc->my_node.my_next && tgc->my_node.my_prev, msg);
489  }
490 #if __TBB_TASK_PRIORITY
491  assert_priority_valid(tgc->my_priority);
492 #endif
493  if(tgc->my_parent)
494 #if TBB_USE_ASSERT > 1
495  assert_context_valid(tgc->my_parent);
496 #else
497  __TBB_ASSERT(is_alive(tgc->my_parent->my_version_and_traits), msg);
498 #endif
499 #endif
500  }
501 #endif /* __TBB_TASK_GROUP_CONTEXT */
502 
503 #if _WIN32||_WIN64
504 private:
506  ::rml::server::execution_resource_t master_exec_resource;
507 public:
508 #endif /* _WIN32||_WIN64 */
509 
510 #if __TBB_TASK_GROUP_CONTEXT
511 
513  tbb::atomic<uintptr_t> my_nonlocal_ctx_list_update;
514 #endif /* __TBB_TASK_GROUP_CONTEXT */
515 
516 #if __TBB_SURVIVE_THREAD_SWITCH
517  __cilk_tbb_unwatch_thunk my_cilk_unwatch_thunk;
518 #if TBB_USE_ASSERT
519 
521  enum cilk_state_t {
522  cs_none=0xF000, // Start at nonzero value so that we can detect use of zeroed memory.
523  cs_running,
524  cs_limbo,
525  cs_freed
526  };
527  cilk_state_t my_cilk_state;
528 #endif /* TBB_USE_ASSERT */
529 #endif /* __TBB_SURVIVE_THREAD_SWITCH */
530 
531 #if __TBB_STATISTICS
532 
535  mutable statistics_counters my_counters;
536 #endif /* __TBB_STATISTICS */
537 
538 }; // class generic_scheduler
539 
540 
541 } // namespace internal
542 } // namespace tbb
543 
544 #include "arena.h"
545 #include "governor.h"
546 
547 namespace tbb {
548 namespace internal {
549 
551  __TBB_ASSERT(my_arena_slot, 0);
552  return my_arena_slot->task_pool != EmptyTaskPool;
553 }
554 
556  __TBB_ASSERT(my_arena_slot, 0);
557  task** tp = my_arena_slot->task_pool;
558  return tp == EmptyTaskPool || tp == LockedTaskPool;
559 }
560 
562  __TBB_ASSERT( is_local_task_pool_quiescent(), "Task pool is not quiescent" );
563  return __TBB_load_relaxed(my_arena_slot->head) == __TBB_load_relaxed(my_arena_slot->tail);
564 }
565 
567  __TBB_ASSERT( is_local_task_pool_quiescent(), "Task pool is not quiescent" );
568  return __TBB_load_relaxed(my_arena_slot->head) == 0 && __TBB_load_relaxed(my_arena_slot->tail) == 0;
569 }
570 
572  return my_properties.outermost;
573 }
574 
576  return !is_worker() && outermost_level();
577 }
578 
580  return is_worker() && outermost_level();
581 }
582 
583 #if __TBB_TASK_GROUP_CONTEXT
584 inline task_group_context* generic_scheduler::default_context () {
585  return my_dummy_task->prefix().context;
586 }
587 #endif /* __TBB_TASK_GROUP_CONTEXT */
588 
590  __TBB_ASSERT(id>0,NULL);
591  my_inbox.attach( my_arena->mailbox(id) );
592  my_affinity_id = id;
593 }
594 
595 inline bool generic_scheduler::is_worker() const {
596  return my_properties.type == scheduler_properties::worker;
597 }
598 
600  __TBB_ASSERT(my_arena, NULL);
601  return my_arena->my_num_slots;
602 }
603 
606 #if TBB_USE_ASSERT
607  task_prefix& p = t.prefix();
608  p.state = 0xFF;
609  p.extra_state = 0xFF;
610  poison_pointer(p.next);
611 #endif /* TBB_USE_ASSERT */
613 #if __TBB_COUNT_TASK_NODES
614  --my_task_node_count;
615 #endif /* __TBB_COUNT_TASK_NODES */
616 }
617 
618 #if __TBB_COUNT_TASK_NODES
619 inline intptr_t generic_scheduler::get_task_node_count( bool count_arena_workers ) {
620  return my_task_node_count + (count_arena_workers? my_arena->workers_task_node_count(): 0);
621 }
622 #endif /* __TBB_COUNT_TASK_NODES */
623 
625  __TBB_ASSERT( my_arena_slot->task_pool == LockedTaskPool, "Task pool must be locked when resetting task pool" );
626  __TBB_store_relaxed( my_arena_slot->tail, 0 );
627  __TBB_store_relaxed( my_arena_slot->head, 0 );
628  leave_task_pool();
629 }
630 
631 //TODO: move to arena_slot
632 inline void generic_scheduler::commit_spawned_tasks( size_t new_tail ) {
633  __TBB_ASSERT ( new_tail <= my_arena_slot->my_task_pool_size, "task deque end was overwritten" );
634  // emit "task was released" signal
635  ITT_NOTIFY(sync_releasing, (void*)((uintptr_t)my_arena_slot+sizeof(uintptr_t)));
636  // Release fence is necessary to make sure that previously stored task pointers
637  // are visible to thieves.
638  __TBB_store_with_release( my_arena_slot->tail, new_tail );
639 }
640 
642  __TBB_ASSERT( is_local_task_pool_quiescent(),
643  "Task pool must be locked when calling commit_relocated_tasks()" );
644  __TBB_store_relaxed( my_arena_slot->head, 0 );
645  // Tail is updated last to minimize probability of a thread making arena
646  // snapshot being misguided into thinking that this task pool is empty.
647  __TBB_store_release( my_arena_slot->tail, new_tail );
648  release_task_pool();
649 }
650 
651 template<free_task_hint hint>
653 #if __TBB_HOARD_NONLOCAL_TASKS
654  static const int h = hint&(~local_task);
655 #else
656  static const free_task_hint h = hint;
657 #endif
658  GATHER_STATISTIC(--my_counters.active_tasks);
659  task_prefix& p = t.prefix();
660  // Verify that optimization hints are correct.
661  __TBB_ASSERT( h!=small_local_task || p.origin==this, NULL );
662  __TBB_ASSERT( !(h&small_task) || p.origin, NULL );
663  __TBB_ASSERT( !(h&local_task) || (!p.origin || uintptr_t(p.origin) > uintptr_t(4096)), "local_task means allocated");
664  poison_value(p.depth);
667  __TBB_ASSERT( 1L<<t.state() & (1L<<task::executing|1L<<task::allocated), NULL );
668  p.state = task::freed;
669  if( h==small_local_task || p.origin==this ) {
670  GATHER_STATISTIC(++my_counters.free_list_length);
671  p.next = my_free_list;
672  my_free_list = &t;
673  } else if( !(h&local_task) && p.origin && uintptr_t(p.origin) < uintptr_t(4096) ) {
674  // a special value reserved for future use, do nothing since
675  // origin is not pointing to a scheduler instance
676  } else if( !(h&local_task) && p.origin ) {
677  GATHER_STATISTIC(++my_counters.free_list_length);
678 #if __TBB_HOARD_NONLOCAL_TASKS
679  if( !(h&no_cache) ) {
680  p.next = my_nonlocal_free_list;
681  my_nonlocal_free_list = &t;
682  } else
683 #endif
684  free_nonlocal_small_task(t);
685  } else {
686  GATHER_STATISTIC(--my_counters.big_tasks);
687  deallocate_task(t);
688  }
689 }
690 
691 #if __TBB_TASK_PRIORITY
692 inline intptr_t generic_scheduler::effective_reference_priority () const {
693  // Workers on the outermost dispatch level (i.e. with empty stack) use market's
694  // priority as a reference point (to speedup discovering process level priority
695  // changes). But when there are enough workers to service (even if only partially)
696  // a lower priority arena, they should use arena's priority as a reference, lest
697  // be trapped in a futile spinning (because market's priority would prohibit
698  // executing ANY tasks in this arena).
699  return !worker_outermost_level() ||
700  (my_arena->my_num_workers_allotted < my_arena->num_workers_active()
701 #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
702  && my_arena->my_concurrency_mode!=arena_base::cm_enforced_global
703 #endif
704  ) ? *my_ref_top_priority : my_arena->my_top_priority;
705 }
706 
707 inline void generic_scheduler::offload_task ( task& t, intptr_t /*priority*/ ) {
708  GATHER_STATISTIC( ++my_counters.prio_tasks_offloaded );
709  __TBB_ASSERT( !is_proxy(t), "The proxy task cannot be offloaded" );
710  __TBB_ASSERT( my_offloaded_task_list_tail_link && !*my_offloaded_task_list_tail_link, NULL );
711 #if TBB_USE_ASSERT
712  t.prefix().state = task::ready;
713 #endif /* TBB_USE_ASSERT */
714  t.prefix().next_offloaded = my_offloaded_tasks;
715  my_offloaded_tasks = &t;
716 }
717 #endif /* __TBB_TASK_PRIORITY */
718 
719 #if __TBB_PREVIEW_CRITICAL_TASKS
720 class critical_task_count_guard : internal::no_copy {
721 public:
722  critical_task_count_guard(scheduler_properties& properties, task& t)
723  : my_properties(properties),
724  my_original_critical_task_state(properties.has_taken_critical_task) {
725  my_properties.has_taken_critical_task |= internal::is_critical(t);
726  }
727  ~critical_task_count_guard() {
728  my_properties.has_taken_critical_task = my_original_critical_task_state;
729  }
730 private:
731  scheduler_properties& my_properties;
732  bool my_original_critical_task_state;
733 };
734 #endif /* __TBB_PREVIEW_CRITICAL_TASKS */
735 
736 #if __TBB_FP_CONTEXT || __TBB_TASK_GROUP_CONTEXT
737 
741 template <bool report_tasks>
742 class context_guard_helper {
743 #if __TBB_TASK_GROUP_CONTEXT
744  const task_group_context *curr_ctx;
745 #endif
746 #if __TBB_FP_CONTEXT
747  cpu_ctl_env guard_cpu_ctl_env;
748  cpu_ctl_env curr_cpu_ctl_env;
749 #endif
750 public:
752 #if __TBB_TASK_GROUP_CONTEXT
753  : curr_ctx(NULL)
754 #endif
755  {
756 #if __TBB_FP_CONTEXT
757  guard_cpu_ctl_env.get_env();
758  curr_cpu_ctl_env = guard_cpu_ctl_env;
759 #endif
760  }
762 #if __TBB_FP_CONTEXT
763  if ( curr_cpu_ctl_env != guard_cpu_ctl_env )
764  guard_cpu_ctl_env.set_env();
765 #endif
766 #if __TBB_TASK_GROUP_CONTEXT
767  if (report_tasks && curr_ctx)
768  ITT_TASK_END;
769 #endif
770  }
771  void set_ctx( const task_group_context *ctx ) {
772  generic_scheduler::assert_context_valid(ctx);
773 #if __TBB_FP_CONTEXT
774  const cpu_ctl_env &ctl = *punned_cast<cpu_ctl_env*>(&ctx->my_cpu_ctl_env);
775 #endif
776 #if __TBB_TASK_GROUP_CONTEXT
777  if(ctx != curr_ctx) {
778 #endif
779 #if __TBB_FP_CONTEXT
780  if ( ctl != curr_cpu_ctl_env ) {
781  curr_cpu_ctl_env = ctl;
782  curr_cpu_ctl_env.set_env();
783  }
784 #endif
785 #if __TBB_TASK_GROUP_CONTEXT
786  // if task group context was active, report end of current execution frame.
787  if (report_tasks) {
788  if (curr_ctx)
789  ITT_TASK_END;
790  // reporting begin of new task group context execution frame.
791  // using address of task group context object to group tasks (parent).
792  // id of task execution frame is NULL and reserved for future use.
793  ITT_TASK_BEGIN(ctx,ctx->my_name,NULL);
794  curr_ctx = ctx;
795  }
796  }
797 #endif
798  }
799  void restore_default() {
800 #if __TBB_FP_CONTEXT
801  if ( curr_cpu_ctl_env != guard_cpu_ctl_env ) {
802  guard_cpu_ctl_env.set_env();
803  curr_cpu_ctl_env = guard_cpu_ctl_env;
804  }
805 #endif
806  }
807 };
808 #else
809 template <bool T>
812  void restore_default() {}
813 };
814 #endif /* __TBB_FP_CONTEXT */
815 
816 } // namespace internal
817 } // namespace tbb
818 
819 #endif /* _TBB_scheduler_H */
task * my_dummy_task
Fake root task created by slave threads.
Definition: scheduler.h:173
__TBB_atomic kind_type my_kind
Flavor of this context: bound or isolated.
Definition: task.h:382
#define __TBB_override
Definition: tbb_stddef.h:244
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 h
void set_ctx(__TBB_CONTEXT_ARG1(task_group_context *))
Definition: scheduler.h:811
#define __TBB_CONTEXT_ARG(arg1, context)
unsigned max_threads_in_arena()
Returns the concurrency limit of the current arena.
Definition: scheduler.h:599
#define LockedTaskPool
Definition: scheduler.h:47
T punned_cast(U *ptr)
Cast between unrelated pointer types.
Definition: tbb_stddef.h:318
#define EmptyTaskPool
Definition: scheduler.h:46
arena * my_arena
The arena that I own (if master) or am servicing at the moment (if worker)
Definition: scheduler.h:78
unsigned short affinity_id
An id as used for specifying affinity.
Definition: task.h:124
Work stealing task scheduler.
Definition: scheduler.h:124
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 id
Memory prefix to a task object.
Definition: task.h:188
bool can_steal()
Returns true if stealing is allowed.
Definition: scheduler.h:195
static task * plugged_return_list()
Special value used to mark my_return_list as not taking any more entries.
Definition: scheduler.h:380
Disable caching for a small task.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
Task is known to have been allocated by this scheduler.
#define __TBB_ISOLATION_EXPR(isolation)
#define ITT_TASK_BEGIN(type, name, id)
Definition: itt_notify.h:129
internal::generic_scheduler * my_owner
Scheduler instance that registered this context in its thread specific list.
Definition: task.h:429
bool is_worker() const
True if running on a worker thread, false otherwise.
Definition: scheduler.h:595
tbb::task * next
"next" field for list of task
Definition: task.h:275
auto first(Container &c) -> decltype(begin(c))
FastRandom my_random
Random number generator used for picking a random victim from which to steal.
Definition: scheduler.h:162
void suppress_unused_warning(const T1 &)
Utility template function to prevent "unused" warnings by various compilers.
Definition: tbb_stddef.h:381
Task is known to be a small task.
Data structure to be inherited by the types that can form intrusive lists.
task * my_innermost_running_task
Innermost task whose task::execute() is running. A dummy task on the outermost level.
Definition: scheduler.h:81
internal::context_list_node_t my_node
Used to form the thread specific list of contexts without additional memory allocation.
Definition: task.h:392
__TBB_atomic reference_count ref_count
Reference count used for synchronization.
Definition: task.h:252
void free_task(task &t)
Put task on free list.
Definition: scheduler.h:652
task_group_context * my_parent
Pointer to the context of the parent cancellation group. NULL for isolated contexts.
Definition: task.h:387
bool is_quiescent_local_task_pool_reset() const
Definition: scheduler.h:566
void deallocate_task(task &t)
Return task object to the memory allocator.
Definition: scheduler.h:605
bool outermost
Indicates that a scheduler is on outermost level.
Definition: scheduler.h:57
uintptr_t my_stealing_threshold
Position in the call stack specifying its maximal filling when stealing is still allowed.
Definition: scheduler.h:142
Tag for v3 task_proxy.
intptr_t isolation_tag
A tag for task isolation.
Definition: task.h:128
internal::task_prefix & prefix(internal::version_tag *=NULL) const
Get reference to corresponding task_prefix.
Definition: task.h:941
scheduler * owner
Obsolete. The scheduler that owns the task.
Definition: task.h:232
void const char const char int ITT_FORMAT __itt_group_sync p
free_task_hint
Optimization hint to free_task that enables it omit unnecessary tests and code.
bool is_critical(task &t)
Definition: task.h:953
size_t my_arena_index
Index of the arena slot the scheduler occupies now, or occupied last time.
Definition: scheduler.h:72
__TBB_atomic intptr_t my_small_task_count
Number of small tasks that have been allocated by this scheduler.
Definition: scheduler.h:383
#define poison_value(g)
arena_slot * my_arena_slot
Pointer to the slot in the arena we own at the moment.
Definition: scheduler.h:75
Class representing source of mail.
Definition: mailbox.h:189
#define __TBB_ISOLATION_ARG(arg1, isolation)
uintptr_t my_cancellation_requested
Specifies whether cancellation was requested for this task group.
Definition: task.h:417
task * my_free_list
Free list of small tasks that can be reused.
Definition: scheduler.h:165
void __TBB_store_relaxed(volatile T &location, V value)
Definition: tbb_machine.h:746
market * my_market
The market I am in.
Definition: scheduler.h:159
task is in ready pool, or is going to be put there, or was just taken off.
Definition: task.h:618
bool is_local_task_pool_quiescent() const
Definition: scheduler.h:555
task is running, and will be destroyed after method execute() completes.
Definition: task.h:614
state_type state() const
Current execution state.
Definition: task.h:859
unsigned char extra_state
Miscellaneous state that is not directly visible to users, stored as a byte for compactness.
Definition: task.h:270
bool master_outermost_level() const
True if the scheduler is on the outermost dispatch level in a master thread.
Definition: scheduler.h:575
The graph class.
unsigned char state
A task::state_type, stored as a byte for compactness.
Definition: task.h:261
affinity_id my_affinity_id
The mailbox id assigned to this scheduler.
Definition: scheduler.h:93
#define GATHER_STATISTIC(x)
void commit_spawned_tasks(size_t new_tail)
Makes newly spawned tasks visible to thieves.
Definition: scheduler.h:632
void attach_mailbox(affinity_id id)
Definition: scheduler.h:589
unsigned char
Reserved bits.
Definition: scheduler.h:66
uintptr_t my_state
Internal state (combination of state flags, currently only may_have_children).
Definition: task.h:432
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 parent
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 sync_releasing
bool type
Indicates that a scheduler acts as a master or a worker.
Definition: scheduler.h:54
void poison_pointer(T *__TBB_atomic &)
Definition: tbb_stddef.h:309
#define __TBB_store_release
Definition: tbb_machine.h:864
Used to form groups of tasks.
Definition: task.h:335
int depth
Obsolete. Used to be scheduling depth before TBB 2.2.
Definition: task.h:257
A scheduler with a customized evaluation loop.
uintptr_t my_version_and_traits
Version for run-time checks and behavioral traits of the context.
Definition: task.h:423
static const kind_type dying
Definition: task.h:569
#define ITT_NOTIFY(name, obj)
Definition: itt_notify.h:120
const size_t NFS_MaxLineSize
Compile-time constant that is upper bound on cache line/sector size.
Definition: tbb_stddef.h:220
#define __TBB_CONTEXT_ARG1(context)
bool is_quiescent_local_task_pool_empty() const
Definition: scheduler.h:561
T __TBB_load_relaxed(const volatile T &location)
Definition: tbb_machine.h:742
long my_ref_count
Reference count for scheduler.
Definition: scheduler.h:177
bool my_auto_initialized
True if *this was created by automatic TBB initialization.
Definition: scheduler.h:184
#define __TBB_atomic
Definition: tbb_stddef.h:241
internal::string_index my_name
Decription of algorithm for scheduler based instrumentation.
Definition: task.h:440
void __TBB_EXPORTED_FUNC NFS_Free(void *)
Free memory allocated by NFS_Allocate.
task * my_return_list
List of small tasks that have been returned to this scheduler by other schedulers.
Definition: scheduler.h:387
void * __TBB_get_bsp()
Retrieves the current RSE backing store pointer. IA64 specific.
#define ITT_TASK_END
Definition: itt_notify.h:130
Base class for user-defined tasks.
Definition: task.h:592
intptr_t reference_count
A reference count.
Definition: task.h:121
void commit_relocated_tasks(size_t new_tail)
Makes relocated tasks visible to thieves and releases the local task pool.
Definition: scheduler.h:641
scheduler * origin
The scheduler that allocated the task, or NULL if the task is big.
Definition: task.h:224
static bool is_version_3_task(task &t)
Definition: scheduler.h:133
bool worker_outermost_level() const
True if the scheduler is on the outermost dispatch level in a worker thread.
Definition: scheduler.h:579
void reset_task_pool_and_leave()
Resets head and tail indices to 0, and leaves task pool.
Definition: scheduler.h:624
A lock that occupies a single byte.
Definition: spin_mutex.h:40
task object is on free list, or is going to be put there, or was just taken off.
Definition: task.h:622
const size_t task_prefix_reservation_size
Number of bytes reserved for a task prefix.
internal::cpu_ctl_env_space my_cpu_ctl_env
Space for platform-specific FPU settings.
Definition: task.h:413
static bool is_proxy(const task &t)
True if t is a task_proxy.
Definition: scheduler.h:273
Bitwise-OR of local_task and small_task.
intptr_t my_priority
Priority level of the task group (in normalized representation)
Definition: task.h:436
void __TBB_store_with_release(volatile T &location, V value)
Definition: tbb_machine.h:720
scheduler_properties my_properties
Definition: scheduler.h:95
bool outermost_level() const
True if the scheduler is on the outermost dispatch level.
Definition: scheduler.h:571
task object is freshly allocated or recycled.
Definition: task.h:620
A fast random number generator.
Definition: tbb_misc.h:131
Bit-field representing properties of a sheduler.
Definition: scheduler.h:50

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.