17 #ifndef _TBB_scheduler_H 18 #define _TBB_scheduler_H 25 #include "../rml/include/rml_tbb.h" 29 #if __TBB_SURVIVE_THREAD_SWITCH 36 template<
typename SchedulerTraits>
class custom_scheduler;
42 #define EmptyTaskPool ((task**)0) 43 #define LockedTaskPool ((task**)~(intptr_t)0) 54 #if __TBB_PREVIEW_CRITICAL_TASKS 55 bool has_taken_critical_task : 1;
93 #if __TBB_SCHEDULER_OBSERVER 94 observer_proxy* my_last_global_observer;
98 #if __TBB_ARENA_OBSERVER 99 observer_proxy* my_last_local_observer;
102 #if __TBB_TASK_PRIORITY 106 volatile intptr_t *my_ref_top_priority;
109 volatile uintptr_t *my_ref_reload_epoch;
130 #if __TBB_PREVIEW_CRITICAL_TASKS 131 return (t.
prefix().extra_state & 0x7)>=0x1;
133 return (t.
prefix().extra_state & 0x0F)>=0x1;
140 uintptr_t my_rsb_stealing_threshold;
144 static const size_t null_arena_index = ~size_t(0);
146 inline bool is_task_pool_published ()
const;
148 inline bool is_local_task_pool_quiescent ()
const;
150 inline bool is_quiescent_local_task_pool_empty ()
const;
152 inline bool is_quiescent_local_task_pool_reset ()
const;
163 #if __TBB_HOARD_NONLOCAL_TASKS 164 task* my_nonlocal_free_list;
182 #if __TBB_COUNT_TASK_NODES 183 intptr_t my_task_node_count;
188 void init_stack_info ();
195 return my_stealing_threshold < (uintptr_t)&anchor && (uintptr_t)
__TBB_get_bsp() < my_rsb_stealing_threshold;
197 return my_stealing_threshold < (uintptr_t)&anchor;
203 void publish_task_pool();
207 void leave_task_pool();
211 inline void reset_task_pool_and_leave ();
219 void unlock_task_pool(
arena_slot* victim_arena_slot,
task** victim_task_pool )
const;
224 void acquire_task_pool()
const;
229 void release_task_pool()
const;
233 task* prepare_for_spawning(
task* t );
236 inline void commit_spawned_tasks(
size_t new_tail );
240 inline void commit_relocated_tasks(
size_t new_tail );
254 #if __TBB_TASK_ISOLATION 257 task* get_task(
size_t T );
279 #if __TBB_PREVIEW_CRITICAL_TASKS 285 bool handled_as_critical(
task& t );
290 static const size_t min_task_pool_size = 64;
295 size_t prepare_task_pool(
size_t n );
301 bool cleanup_master(
bool blocking_terminate );
307 static void cleanup_worker(
void* arg,
bool worker );
314 #if TBB_USE_ASSERT > 1 317 void assert_task_pool_valid()
const;
322 void attach_arena(
arena*,
size_t index,
bool is_master );
323 void nested_arena_entry(
arena*,
size_t );
324 void nested_arena_exit();
325 void wait_until_empty();
333 void local_spawn(
task* first,
task*& next );
334 void local_spawn_root_and_wait(
task* first,
task*& next );
338 void free_scheduler();
342 task& allocate_task(
size_t number_of_bytes,
347 template<free_task_h
int h>
348 void free_task(
task& t );
351 inline void deallocate_task(
task& t );
354 inline bool is_worker()
const;
357 inline bool outermost_level()
const;
363 inline bool master_outermost_level ()
const;
366 inline bool worker_outermost_level ()
const;
369 unsigned max_threads_in_arena();
371 #if __TBB_COUNT_TASK_NODES 372 intptr_t get_task_node_count(
bool count_arena_workers =
false );
390 void free_nonlocal_small_task(
task& t );
392 #if __TBB_TASK_GROUP_CONTEXT 418 uintptr_t my_context_state_propagation_epoch;
426 #if __TBB_TASK_PRIORITY 427 inline intptr_t effective_reference_priority ()
const;
432 task* my_offloaded_tasks;
435 task** my_offloaded_task_list_tail_link;
438 uintptr_t my_local_reload_epoch;
441 volatile bool my_pool_reshuffling_pending;
458 inline void offload_task (
task& t, intptr_t task_priority );
463 void cleanup_local_context_list ();
467 template <
typename T>
476 __TBB_ASSERT(is_alive(ctx),
"referenced task_group_context was destroyed");
477 static const char *msg =
"task_group_context is invalid";
486 #if __TBB_TASK_PRIORITY 490 #if TBB_USE_ASSERT > 1 502 ::rml::server::execution_resource_t master_exec_resource;
506 #if __TBB_TASK_GROUP_CONTEXT 512 #if __TBB_SURVIVE_THREAD_SWITCH 523 cilk_state_t my_cilk_state;
531 mutable statistics_counters my_counters;
553 task** tp = my_arena_slot->task_pool;
558 __TBB_ASSERT( is_local_task_pool_quiescent(),
"Task pool is not quiescent" );
563 __TBB_ASSERT( is_local_task_pool_quiescent(),
"Task pool is not quiescent" );
568 return my_properties.outermost;
572 return !is_worker() && outermost_level();
576 return is_worker() && outermost_level();
579 #if __TBB_TASK_GROUP_CONTEXT 581 return my_dummy_task->
prefix().context;
587 my_inbox.attach( my_arena->mailbox(
id) );
597 return my_arena->my_num_slots;
609 #if __TBB_COUNT_TASK_NODES 610 --my_task_node_count;
614 #if __TBB_COUNT_TASK_NODES 615 inline intptr_t generic_scheduler::get_task_node_count(
bool count_arena_workers ) {
616 return my_task_node_count + (count_arena_workers? my_arena->workers_task_node_count(): 0);
629 __TBB_ASSERT ( new_tail <= my_arena_slot->my_task_pool_size,
"task deque end was overwritten" );
639 "Task pool must be locked when calling commit_relocated_tasks()" );
647 template<free_task_h
int h
int>
649 #if __TBB_HOARD_NONLOCAL_TASKS 667 p.
next = my_free_list;
669 }
else if( !(h&local_task) && p.
origin && uintptr_t(p.
origin) < uintptr_t(4096) ) {
672 }
else if( !(h&local_task) && p.
origin ) {
674 #if __TBB_HOARD_NONLOCAL_TASKS 676 p.
next = my_nonlocal_free_list;
677 my_nonlocal_free_list = &t;
680 free_nonlocal_small_task(t);
687 #if __TBB_TASK_PRIORITY 688 inline intptr_t generic_scheduler::effective_reference_priority ()
const {
695 return !worker_outermost_level() ||
696 (my_arena->my_num_workers_allotted < my_arena->num_workers_active()
697 #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY 698 && my_arena->my_concurrency_mode!=arena_base::cm_enforced_global
700 ) ? *my_ref_top_priority : my_arena->my_top_priority;
703 inline void generic_scheduler::offload_task (
task& t, intptr_t ) {
705 __TBB_ASSERT( !is_proxy(t),
"The proxy task cannot be offloaded" );
706 __TBB_ASSERT( my_offloaded_task_list_tail_link && !*my_offloaded_task_list_tail_link, NULL );
710 t.
prefix().next_offloaded = my_offloaded_tasks;
711 my_offloaded_tasks = &t;
715 #if __TBB_PREVIEW_CRITICAL_TASKS 716 class critical_task_count_guard : internal::no_copy {
719 : my_properties(properties),
720 my_original_critical_task_state(properties.has_taken_critical_task) {
723 ~critical_task_count_guard() {
724 my_properties.has_taken_critical_task = my_original_critical_task_state;
728 bool my_original_critical_task_state;
732 #if __TBB_FP_CONTEXT || __TBB_TASK_GROUP_CONTEXT 737 template <
bool report_tasks>
739 #if __TBB_TASK_GROUP_CONTEXT 748 #if __TBB_TASK_GROUP_CONTEXT 754 curr_cpu_ctl_env = guard_cpu_ctl_env;
759 if ( curr_cpu_ctl_env != guard_cpu_ctl_env )
762 #if __TBB_TASK_GROUP_CONTEXT 763 if (report_tasks && curr_ctx)
768 generic_scheduler::assert_context_valid(ctx);
772 #if __TBB_TASK_GROUP_CONTEXT 773 if(ctx != curr_ctx) {
776 if ( ctl != curr_cpu_ctl_env ) {
777 curr_cpu_ctl_env = ctl;
781 #if __TBB_TASK_GROUP_CONTEXT 795 void restore_default() {
797 if ( curr_cpu_ctl_env != guard_cpu_ctl_env ) {
799 curr_cpu_ctl_env = guard_cpu_ctl_env;
market * my_market
The market I am in.
bool outermost
Indicates that a scheduler is on outermost level.
internal::context_list_node_t my_node
Used to form the thread specific list of contexts without additional memory allocation.
scheduler_properties my_properties
Class representing source of mail.
int depth
Obsolete. Used to be scheduling depth before TBB 2.2.
T __TBB_load_relaxed(const volatile T &location)
#define __TBB_store_release
tbb::task * next
"next" field for list of task
task * my_dummy_task
Fake root task created by slave threads.
internal::task_prefix & prefix(internal::version_tag *=NULL) const
Get reference to corresponding task_prefix.
bool is_quiescent_local_task_pool_empty() const
void __TBB_store_relaxed(volatile T &location, V value)
#define __TBB_ISOLATION_EXPR(isolation)
void commit_spawned_tasks(size_t new_tail)
Makes newly spawned tasks visible to thieves.
intptr_t reference_count
A reference count.
task object is freshly allocated or recycled.
free_task_hint
Optimization hint to free_task that enables it omit unnecessary tests and code.
Bitwise-OR of local_task and small_task.
void free_task(task &t)
Put task on free list.
void deallocate_task(task &t)
Return task object to the memory allocator.
bool is_task_pool_published() const
bool worker_outermost_level() const
True if the scheduler is on the outermost dispatch level in a worker thread.
long my_ref_count
Reference count for scheduler.
void reset_task_pool_and_leave()
Resets head and tail indices to 0, and leaves task pool.
#define GATHER_STATISTIC(x)
static bool is_proxy(const task &t)
True if t is a task_proxy.
bool master_outermost_level() const
True if the scheduler is on the outermost dispatch level in a master thread.
void poison_pointer(T *__TBB_atomic &)
const size_t task_prefix_reservation_size
Number of bytes reserved for a task prefix.
static task * plugged_return_list()
Special value used to mark my_return_list as not taking any more entries.
auto first(Container &c) -> decltype(begin(c))
static bool is_version_3_task(task &t)
bool outermost_level() const
True if the scheduler is on the outermost dispatch level.
Data structure to be inherited by the types that can form intrusive lists.
task is running, and will be destroyed after method execute() completes.
A scheduler with a customized evaluation loop.
void * __TBB_get_bsp()
Retrieves the current RSE backing store pointer. IA64 specific.
bool type
Indicates that a scheduler acts as a master or a worker.
task_group_context * my_parent
Pointer to the context of the parent cancellation group. NULL for isolated contexts.
Disable caching for a small task.
void __TBB_EXPORTED_FUNC NFS_Free(void *)
Free memory allocated by NFS_Allocate.
unsigned short affinity_id
An id as used for specifying affinity.
void suppress_unused_warning(const T1 &)
Utility template function to prevent "unused" warnings by various compilers.
Task is known to be a small task.
internal::string_index my_name
Description of algorithm for scheduler based instrumentation.
scheduler * owner
Obsolete. The scheduler that owns the task.
#define ITT_TASK_BEGIN(type, name, id)
internal::generic_scheduler * my_owner
Scheduler instance that registered this context in its thread specific list.
T punned_cast(U *ptr)
Cast between unrelated pointer types.
Task is known to have been allocated by this scheduler.
affinity_id my_affinity_id
The mailbox id assigned to this 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 ITT_FORMAT lu const __itt_domain __itt_id __itt_id parent
__TBB_atomic kind_type my_kind
Flavor of this context: bound or isolated.
task * my_return_list
List of small tasks that have been returned to this scheduler by other schedulers.
bool is_worker() const
True if running on a worker thread, false otherwise.
void set_ctx(__TBB_CONTEXT_ARG1(task_group_context *))
Memory prefix to a task object.
internal::cpu_ctl_env_space my_cpu_ctl_env
Space for platform-specific FPU settings.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
FastRandom my_random
Random number generator used for picking a random victim from which to steal.
uintptr_t my_cancellation_requested
Specifies whether cancellation was requested for this task group.
state_type state() const
Current execution state.
uintptr_t my_stealing_threshold
Position in the call stack specifying its maximal filling when stealing is still allowed.
#define __TBB_CONTEXT_ARG(arg1, context)
__TBB_atomic reference_count ref_count
Reference count used for synchronization.
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
unsigned char extra_state
Miscellaneous state that is not directly visible to users, stored as a byte for compactness.
void __TBB_store_with_release(volatile T &location, V value)
arena * my_arena
The arena that I own (if master) or am servicing at the moment (if worker)
unsigned char state
A task::state_type, stored as a byte for compactness.
Used to form groups of tasks.
A fast random number generator.
uintptr_t my_version_and_traits
Version for run-time checks and behavioral traits of the context.
Bit-field representing properties of a sheduler.
task is in ready pool, or is going to be put there, or was just taken off.
bool my_auto_initialized
True if *this was created by automatic TBB initialization.
#define __TBB_CONTEXT_ARG1(context)
task object is on free list, or is going to be put there, or was just taken off.
#define ITT_NOTIFY(name, obj)
intptr_t my_priority
Priority level of the task group (in normalized representation)
bool is_critical(task &t)
static const kind_type dying
intptr_t isolation_tag
A tag for task isolation.
Base class for user-defined tasks.
Work stealing task scheduler.
arena_slot * my_arena_slot
Pointer to the slot in the arena we own at the moment.
bool can_steal()
Returns true if stealing is allowed.
task * my_free_list
Free list of small tasks that can be reused.
unsigned max_threads_in_arena()
Returns the concurrency limit of the current arena.
#define __TBB_ISOLATION_ARG(arg1, isolation)
A lock that occupies a single byte.
size_t my_arena_index
Index of the arena slot the scheduler occupies now, or occupied last time.
bool is_local_task_pool_quiescent() const
void commit_relocated_tasks(size_t new_tail)
Makes relocated tasks visible to thieves and releases the local task pool.
__TBB_atomic intptr_t my_small_task_count
Number of small tasks that have been allocated by this scheduler.
void const char const char int ITT_FORMAT __itt_group_sync p
task * my_innermost_running_task
Innermost task whose task::execute() is running. A dummy task on the outermost level.
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
unsigned char
Reserved bits.
bool is_quiescent_local_task_pool_reset() const
const size_t NFS_MaxLineSize
Compile-time constant that is upper bound on cache line/sector size.
scheduler * origin
The scheduler that allocated the task, or NULL if the task is big.
uintptr_t my_state
Internal state (combination of state flags, currently only may_have_children).
void attach_mailbox(affinity_id id)
void assert_task_pool_valid() const
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