21 #ifndef _TBB_scheduler_H 22 #define _TBB_scheduler_H 29 #include "../rml/include/rml_tbb.h" 33 #if __TBB_SURVIVE_THREAD_SWITCH 40 template<
typename SchedulerTraits>
class custom_scheduler;
46 #define EmptyTaskPool ((task**)0) 47 #define LockedTaskPool ((task**)~(intptr_t)0) 58 #if __TBB_PREVIEW_CRITICAL_TASKS 59 bool has_taken_critical_task : 1;
97 #if __TBB_SCHEDULER_OBSERVER 98 observer_proxy* my_last_global_observer;
102 #if __TBB_ARENA_OBSERVER 103 observer_proxy* my_last_local_observer;
106 #if __TBB_TASK_PRIORITY 110 volatile intptr_t *my_ref_top_priority;
113 volatile uintptr_t *my_ref_reload_epoch;
134 #if __TBB_PREVIEW_CRITICAL_TASKS 135 return (t.
prefix().extra_state & 0x7)>=0x1;
137 return (t.
prefix().extra_state & 0x0F)>=0x1;
144 uintptr_t my_rsb_stealing_threshold;
148 static const size_t null_arena_index = ~size_t(0);
150 inline bool is_task_pool_published ()
const;
152 inline bool is_local_task_pool_quiescent ()
const;
154 inline bool is_quiescent_local_task_pool_empty ()
const;
156 inline bool is_quiescent_local_task_pool_reset ()
const;
167 #if __TBB_HOARD_NONLOCAL_TASKS 168 task* my_nonlocal_free_list;
186 #if __TBB_COUNT_TASK_NODES 187 intptr_t my_task_node_count;
192 void init_stack_info ();
199 return my_stealing_threshold < (uintptr_t)&anchor && (uintptr_t)
__TBB_get_bsp() < my_rsb_stealing_threshold;
201 return my_stealing_threshold < (uintptr_t)&anchor;
207 void publish_task_pool();
211 void leave_task_pool();
215 inline void reset_task_pool_and_leave ();
223 void unlock_task_pool(
arena_slot* victim_arena_slot,
task** victim_task_pool )
const;
228 void acquire_task_pool()
const;
233 void release_task_pool()
const;
237 task* prepare_for_spawning(
task* t );
240 inline void commit_spawned_tasks(
size_t new_tail );
244 inline void commit_relocated_tasks(
size_t new_tail );
258 #if __TBB_TASK_ISOLATION 261 task* get_task(
size_t T );
283 #if __TBB_PREVIEW_CRITICAL_TASKS 289 bool handled_as_critical(
task& t );
294 static const size_t min_task_pool_size = 64;
299 size_t prepare_task_pool(
size_t n );
305 bool cleanup_master(
bool blocking_terminate );
311 static void cleanup_worker(
void* arg,
bool worker );
318 #if TBB_USE_ASSERT > 1 321 void assert_task_pool_valid()
const;
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();
337 void local_spawn(
task* first,
task*& next );
338 void local_spawn_root_and_wait(
task* first,
task*& next );
342 void free_scheduler();
346 task& allocate_task(
size_t number_of_bytes,
351 template<free_task_h
int h>
352 void free_task(
task& t );
355 inline void deallocate_task(
task& t );
358 inline bool is_worker()
const;
361 inline bool outermost_level()
const;
367 inline bool master_outermost_level ()
const;
370 inline bool worker_outermost_level ()
const;
373 unsigned max_threads_in_arena();
375 #if __TBB_COUNT_TASK_NODES 376 intptr_t get_task_node_count(
bool count_arena_workers =
false );
394 void free_nonlocal_small_task(
task& t );
396 #if __TBB_TASK_GROUP_CONTEXT 422 uintptr_t my_context_state_propagation_epoch;
430 #if __TBB_TASK_PRIORITY 431 inline intptr_t effective_reference_priority ()
const;
436 task* my_offloaded_tasks;
439 task** my_offloaded_task_list_tail_link;
442 uintptr_t my_local_reload_epoch;
445 volatile bool my_pool_reshuffling_pending;
462 inline void offload_task (
task& t, intptr_t task_priority );
467 void cleanup_local_context_list ();
471 template <
typename T>
480 __TBB_ASSERT(is_alive(ctx),
"referenced task_group_context was destroyed");
481 static const char *msg =
"task_group_context is invalid";
490 #if __TBB_TASK_PRIORITY 494 #if TBB_USE_ASSERT > 1 506 ::rml::server::execution_resource_t master_exec_resource;
510 #if __TBB_TASK_GROUP_CONTEXT 516 #if __TBB_SURVIVE_THREAD_SWITCH 527 cilk_state_t my_cilk_state;
535 mutable statistics_counters my_counters;
557 task** tp = my_arena_slot->task_pool;
562 __TBB_ASSERT( is_local_task_pool_quiescent(),
"Task pool is not quiescent" );
567 __TBB_ASSERT( is_local_task_pool_quiescent(),
"Task pool is not quiescent" );
572 return my_properties.outermost;
576 return !is_worker() && outermost_level();
580 return is_worker() && outermost_level();
583 #if __TBB_TASK_GROUP_CONTEXT 585 return my_dummy_task->
prefix().context;
591 my_inbox.attach( my_arena->mailbox(
id) );
601 return my_arena->my_num_slots;
613 #if __TBB_COUNT_TASK_NODES 614 --my_task_node_count;
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);
633 __TBB_ASSERT ( new_tail <= my_arena_slot->my_task_pool_size,
"task deque end was overwritten" );
643 "Task pool must be locked when calling commit_relocated_tasks()" );
651 template<free_task_h
int h
int>
653 #if __TBB_HOARD_NONLOCAL_TASKS 671 p.
next = my_free_list;
673 }
else if( !(h&local_task) && p.
origin && uintptr_t(p.
origin) < uintptr_t(4096) ) {
676 }
else if( !(h&local_task) && p.
origin ) {
678 #if __TBB_HOARD_NONLOCAL_TASKS 680 p.
next = my_nonlocal_free_list;
681 my_nonlocal_free_list = &t;
684 free_nonlocal_small_task(t);
691 #if __TBB_TASK_PRIORITY 692 inline intptr_t generic_scheduler::effective_reference_priority ()
const {
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
704 ) ? *my_ref_top_priority : my_arena->my_top_priority;
707 inline void generic_scheduler::offload_task (
task& t, intptr_t ) {
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 );
714 t.
prefix().next_offloaded = my_offloaded_tasks;
715 my_offloaded_tasks = &t;
719 #if __TBB_PREVIEW_CRITICAL_TASKS 720 class critical_task_count_guard : internal::no_copy {
723 : my_properties(properties),
724 my_original_critical_task_state(properties.has_taken_critical_task) {
727 ~critical_task_count_guard() {
728 my_properties.has_taken_critical_task = my_original_critical_task_state;
732 bool my_original_critical_task_state;
736 #if __TBB_FP_CONTEXT || __TBB_TASK_GROUP_CONTEXT 741 template <
bool report_tasks>
743 #if __TBB_TASK_GROUP_CONTEXT 752 #if __TBB_TASK_GROUP_CONTEXT 758 curr_cpu_ctl_env = guard_cpu_ctl_env;
763 if ( curr_cpu_ctl_env != guard_cpu_ctl_env )
766 #if __TBB_TASK_GROUP_CONTEXT 767 if (report_tasks && curr_ctx)
772 generic_scheduler::assert_context_valid(ctx);
776 #if __TBB_TASK_GROUP_CONTEXT 777 if(ctx != curr_ctx) {
780 if ( ctl != curr_cpu_ctl_env ) {
781 curr_cpu_ctl_env = ctl;
785 #if __TBB_TASK_GROUP_CONTEXT 799 void restore_default() {
801 if ( curr_cpu_ctl_env != guard_cpu_ctl_env ) {
803 curr_cpu_ctl_env = guard_cpu_ctl_env;
task * my_dummy_task
Fake root task created by slave threads.
__TBB_atomic kind_type my_kind
Flavor of this context: bound or isolated.
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 *))
#define __TBB_CONTEXT_ARG(arg1, context)
unsigned max_threads_in_arena()
Returns the concurrency limit of the current arena.
T punned_cast(U *ptr)
Cast between unrelated pointer types.
arena * my_arena
The arena that I own (if master) or am servicing at the moment (if worker)
unsigned short affinity_id
An id as used for specifying affinity.
Work stealing task scheduler.
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.
bool can_steal()
Returns true if stealing is allowed.
static task * plugged_return_list()
Special value used to mark my_return_list as not taking any more entries.
Disable caching for a small task.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Task is known to have been allocated by this scheduler.
#define __TBB_ISOLATION_EXPR(isolation)
#define ITT_TASK_BEGIN(type, name, id)
internal::generic_scheduler * my_owner
Scheduler instance that registered this context in its thread specific list.
bool is_worker() const
True if running on a worker thread, false otherwise.
tbb::task * next
"next" field for list of task
auto first(Container &c) -> decltype(begin(c))
FastRandom my_random
Random number generator used for picking a random victim from which to steal.
void suppress_unused_warning(const T1 &)
Utility template function to prevent "unused" warnings by various compilers.
bool is_task_pool_published() const
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.
internal::context_list_node_t my_node
Used to form the thread specific list of contexts without additional memory allocation.
__TBB_atomic reference_count ref_count
Reference count used for synchronization.
void free_task(task &t)
Put task on free list.
task_group_context * my_parent
Pointer to the context of the parent cancellation group. NULL for isolated contexts.
bool is_quiescent_local_task_pool_reset() const
void deallocate_task(task &t)
Return task object to the memory allocator.
bool outermost
Indicates that a scheduler is on outermost level.
uintptr_t my_stealing_threshold
Position in the call stack specifying its maximal filling when stealing is still allowed.
intptr_t isolation_tag
A tag for task isolation.
internal::task_prefix & prefix(internal::version_tag *=NULL) const
Get reference to corresponding task_prefix.
scheduler * owner
Obsolete. The scheduler that owns the task.
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)
size_t my_arena_index
Index of the arena slot the scheduler occupies now, or occupied last time.
__TBB_atomic intptr_t my_small_task_count
Number of small tasks that have been allocated by this scheduler.
arena_slot * my_arena_slot
Pointer to the slot in the arena we own at the moment.
Class representing source of mail.
#define __TBB_ISOLATION_ARG(arg1, isolation)
uintptr_t my_cancellation_requested
Specifies whether cancellation was requested for this task group.
task * my_free_list
Free list of small tasks that can be reused.
void __TBB_store_relaxed(volatile T &location, V value)
market * my_market
The market I am in.
task is in ready pool, or is going to be put there, or was just taken off.
bool is_local_task_pool_quiescent() const
task is running, and will be destroyed after method execute() completes.
state_type state() const
Current execution state.
unsigned char extra_state
Miscellaneous state that is not directly visible to users, stored as a byte for compactness.
bool master_outermost_level() const
True if the scheduler is on the outermost dispatch level in a master thread.
unsigned char state
A task::state_type, stored as a byte for compactness.
affinity_id my_affinity_id
The mailbox id assigned to this scheduler.
#define GATHER_STATISTIC(x)
void commit_spawned_tasks(size_t new_tail)
Makes newly spawned tasks visible to thieves.
void attach_mailbox(affinity_id id)
unsigned char
Reserved bits.
uintptr_t my_state
Internal state (combination of state flags, currently only may_have_children).
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.
void poison_pointer(T *__TBB_atomic &)
#define __TBB_store_release
Used to form groups of tasks.
int depth
Obsolete. Used to be scheduling depth before TBB 2.2.
A scheduler with a customized evaluation loop.
uintptr_t my_version_and_traits
Version for run-time checks and behavioral traits of the context.
static const kind_type dying
#define ITT_NOTIFY(name, obj)
const size_t NFS_MaxLineSize
Compile-time constant that is upper bound on cache line/sector size.
#define __TBB_CONTEXT_ARG1(context)
bool is_quiescent_local_task_pool_empty() const
T __TBB_load_relaxed(const volatile T &location)
long my_ref_count
Reference count for scheduler.
bool my_auto_initialized
True if *this was created by automatic TBB initialization.
internal::string_index my_name
Decription of algorithm for scheduler based instrumentation.
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.
void * __TBB_get_bsp()
Retrieves the current RSE backing store pointer. IA64 specific.
Base class for user-defined tasks.
intptr_t reference_count
A reference count.
void commit_relocated_tasks(size_t new_tail)
Makes relocated tasks visible to thieves and releases the local task pool.
scheduler * origin
The scheduler that allocated the task, or NULL if the task is big.
static bool is_version_3_task(task &t)
bool worker_outermost_level() const
True if the scheduler is on the outermost dispatch level in a worker thread.
void reset_task_pool_and_leave()
Resets head and tail indices to 0, and leaves task pool.
A lock that occupies a single byte.
task object is on free list, or is going to be put there, or was just taken off.
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.
static bool is_proxy(const task &t)
True if t is a task_proxy.
Bitwise-OR of local_task and small_task.
intptr_t my_priority
Priority level of the task group (in normalized representation)
void __TBB_store_with_release(volatile T &location, V value)
scheduler_properties my_properties
void assert_task_pool_valid() const
bool outermost_level() const
True if the scheduler is on the outermost dispatch level.
task object is freshly allocated or recycled.
A fast random number generator.
Bit-field representing properties of a sheduler.