task.cpp
Go to the documentation of this file.
/*
Copyright (c) 2005-2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Do not include task.h directly. Use scheduler_common.h instead
#include "scheduler_common.h"
#include "governor.h"
#include "scheduler.h"
#include "itt_notify.h"
#include "tbb/cache_aligned_allocator.h"
#include "tbb/partitioner.h"
#include <new>
namespace tbb {
namespace internal {
//------------------------------------------------------------------------
// Methods of allocate_root_proxy
//------------------------------------------------------------------------
task& allocate_root_proxy::allocate( size_t size ) {
internal::generic_scheduler* v = governor::local_scheduler_weak();
__TBB_ASSERT( v, "thread did not activate a task_scheduler_init object?" );
#if __TBB_TASK_GROUP_CONTEXT
task_prefix& p = v->my_innermost_running_task->prefix();
ITT_STACK_CREATE(p.context->itt_caller);
#endif
// New root task becomes part of the currently running task's cancellation context
return v->allocate_task( size, __TBB_CONTEXT_ARG(NULL, p.context) );
}
void allocate_root_proxy::free( task& task ) {
internal::generic_scheduler* v = governor::local_scheduler_weak();
__TBB_ASSERT( v, "thread does not have initialized task_scheduler_init object?" );
#if __TBB_TASK_GROUP_CONTEXT
// No need to do anything here as long as there is no context -> task connection
#endif /* __TBB_TASK_GROUP_CONTEXT */
v->free_task<local_task>( task );
}
#if __TBB_TASK_GROUP_CONTEXT
//------------------------------------------------------------------------
// Methods of allocate_root_with_context_proxy
//------------------------------------------------------------------------
task& allocate_root_with_context_proxy::allocate( size_t size ) const {
internal::generic_scheduler* s = governor::local_scheduler_weak();
__TBB_ASSERT( s, "Scheduler auto-initialization failed?" );
__TBB_ASSERT( &my_context, "allocate_root(context) argument is a dereferenced NULL pointer" );
task& t = s->allocate_task( size, NULL, &my_context );
// Supported usage model prohibits concurrent initial binding. Thus we do not
// need interlocked operations or fences to manipulate with my_context.my_kind
if ( __TBB_load_relaxed(my_context.my_kind) == task_group_context::binding_required ) {
// If we are in the outermost task dispatch loop of a master thread, then
// there is nothing to bind this context to, and we skip the binding part
// treating the context as isolated.
if ( s->master_outermost_level() )
__TBB_store_relaxed(my_context.my_kind, task_group_context::isolated);
else
my_context.bind_to( s );
}
#if __TBB_FP_CONTEXT
if ( __TBB_load_relaxed(my_context.my_kind) == task_group_context::isolated &&
!(my_context.my_version_and_traits & task_group_context::fp_settings) )
my_context.copy_fp_settings( *s->default_context() );
#endif
ITT_STACK_CREATE(my_context.itt_caller);
return t;
}
void allocate_root_with_context_proxy::free( task& task ) const {
internal::generic_scheduler* v = governor::local_scheduler_weak();
__TBB_ASSERT( v, "thread does not have initialized task_scheduler_init object?" );
// No need to do anything here as long as unbinding is performed by context destructor only.
v->free_task<local_task>( task );
}
#endif /* __TBB_TASK_GROUP_CONTEXT */
//------------------------------------------------------------------------
// Methods of allocate_continuation_proxy
//------------------------------------------------------------------------
task& allocate_continuation_proxy::allocate( size_t size ) const {
task* t = (task*)this;
assert_task_valid(t);
generic_scheduler* s = governor::local_scheduler_weak();
task* parent = t->parent();
t->prefix().parent = NULL;
return s->allocate_task( size, __TBB_CONTEXT_ARG(parent, t->prefix().context) );
}
void allocate_continuation_proxy::free( task& mytask ) const {
// Restore the parent as it was before the corresponding allocate was called.
((task*)this)->prefix().parent = mytask.parent();
governor::local_scheduler_weak()->free_task<local_task>(mytask);
}
//------------------------------------------------------------------------
// Methods of allocate_child_proxy
//------------------------------------------------------------------------
task& allocate_child_proxy::allocate( size_t size ) const {
task* t = (task*)this;
assert_task_valid(t);
generic_scheduler* s = governor::local_scheduler_weak();
return s->allocate_task( size, __TBB_CONTEXT_ARG(t, t->prefix().context) );
}
void allocate_child_proxy::free( task& mytask ) const {
governor::local_scheduler_weak()->free_task<local_task>(mytask);
}
//------------------------------------------------------------------------
// Methods of allocate_additional_child_of_proxy
//------------------------------------------------------------------------
task& allocate_additional_child_of_proxy::allocate( size_t size ) const {
parent.increment_ref_count();
generic_scheduler* s = governor::local_scheduler_weak();
return s->allocate_task( size, __TBB_CONTEXT_ARG(&parent, parent.prefix().context) );
}
void allocate_additional_child_of_proxy::free( task& task ) const {
// Undo the increment. We do not check the result of the fetch-and-decrement.
// We could consider be spawning the task if the fetch-and-decrement returns 1.
// But we do not know that was the programmer's intention.
// Furthermore, if it was the programmer's intention, the program has a fundamental
// race condition (that we warn about in Reference manual), because the
// reference count might have become zero before the corresponding call to
// allocate_additional_child_of_proxy::allocate.
parent.internal_decrement_ref_count();
governor::local_scheduler_weak()->free_task<local_task>(task);
}
//------------------------------------------------------------------------
// Support for auto_partitioner
//------------------------------------------------------------------------
size_t get_initial_auto_partitioner_divisor() {
const size_t X_FACTOR = 4;
return X_FACTOR * governor::local_scheduler()->max_threads_in_arena();
}
//------------------------------------------------------------------------
// Methods of affinity_partitioner_base_v3
//------------------------------------------------------------------------
void affinity_partitioner_base_v3::resize( unsigned factor ) {
// Check factor to avoid asking for number of workers while there might be no arena.
size_t new_size = factor ? factor*governor::local_scheduler()->max_threads_in_arena() : 0;
if( new_size!=my_size ) {
if( my_array ) {
NFS_Free( my_array );
// Following two assignments must be done here for sake of exception safety.
my_array = NULL;
my_size = 0;
}
if( new_size ) {
my_array = static_cast<affinity_id*>(NFS_Allocate(new_size,sizeof(affinity_id), NULL ));
memset( my_array, 0, sizeof(affinity_id)*new_size );
my_size = new_size;
}
}
}
} // namespace internal
using namespace tbb::internal;
//------------------------------------------------------------------------
// task
//------------------------------------------------------------------------
void task::internal_set_ref_count( int count ) {
__TBB_ASSERT( count>=0, "count must not be negative" );
task_prefix &p = prefix();
__TBB_ASSERT(p.ref_count==1 && p.state==allocated && self().parent()==this
|| !(p.extra_state & es_ref_count_active), "ref_count race detected");
ITT_NOTIFY(sync_releasing, &p.ref_count);
p.ref_count = count;
}
internal::reference_count task::internal_decrement_ref_count() {
ITT_NOTIFY( sync_releasing, &prefix().ref_count );
internal::reference_count k = __TBB_FetchAndDecrementWrelease( &prefix().ref_count );
__TBB_ASSERT( k>=1, "task's reference count underflowed" );
if( k==1 )
ITT_NOTIFY( sync_acquired, &prefix().ref_count );
return k-1;
}
task& task::self() {
generic_scheduler *v = governor::local_scheduler_weak();
v->assert_task_pool_valid();
__TBB_ASSERT( v->my_innermost_running_task, NULL );
return *v->my_innermost_running_task;
}
bool task::is_owned_by_current_thread() const {
return true;
}
void interface5::internal::task_base::destroy( task& victim ) {
// 1 may be a guard reference for wait_for_all, which was not reset because
// of concurrent_wait mode or because prepared root task was not actually used
// for spawning tasks (as in structured_task_group).
__TBB_ASSERT( (intptr_t)victim.prefix().ref_count <= 1, "Task being destroyed must not have children" );
__TBB_ASSERT( victim.state()==task::allocated, "illegal state for victim task" );
task* parent = victim.parent();
victim.~task();
if( parent ) {
__TBB_ASSERT( parent->state()!=task::freed && parent->state()!=task::ready,
"attempt to destroy child of running or corrupted parent?" );
// 'reexecute' and 'executing' are also signs of a race condition, since most tasks
// set their ref_count upon entry but "es_ref_count_active" should detect this
parent->internal_decrement_ref_count();
// Even if the last reference to *parent is removed, it should not be spawned (documented behavior).
}
governor::local_scheduler_weak()->free_task<no_cache>( victim );
}
void task::spawn_and_wait_for_all( task_list& list ) {
generic_scheduler* s = governor::local_scheduler();
task* t = list.first;
if( t ) {
if( &t->prefix().next!=list.next_ptr )
s->local_spawn( t->prefix().next, *list.next_ptr );
list.clear();
}
s->local_wait_for_all( *this, t );
}
void task::note_affinity( affinity_id ) {
}
#if __TBB_TASK_GROUP_CONTEXT
void task::change_group ( task_group_context& ctx ) {
prefix().context = &ctx;
internal::generic_scheduler* s = governor::local_scheduler_weak();
if ( __TBB_load_relaxed(ctx.my_kind) == task_group_context::binding_required ) {
// If we are in the outermost task dispatch loop of a master thread, then
// there is nothing to bind this context to, and we skip the binding part
// treating the context as isolated.
if ( s->master_outermost_level() )
__TBB_store_relaxed(ctx.my_kind, task_group_context::isolated);
else
ctx.bind_to( s );
}
#if __TBB_FP_CONTEXT
if ( __TBB_load_relaxed(ctx.my_kind) == task_group_context::isolated &&
!(ctx.my_version_and_traits & task_group_context::fp_settings) )
ctx.copy_fp_settings( *s->default_context() );
#endif
ITT_STACK_CREATE(ctx.itt_caller);
}
#endif /* __TBB_TASK_GROUP_CONTEXT */
} // namespace tbb
cache_aligned_allocator.h
partitioner.h
__TBB_FetchAndDecrementWrelease
#define __TBB_FetchAndDecrementWrelease(P)
Definition: tbb_machine.h:314
__TBB_ASSERT
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
governor.h
itt_notify.h
ITT_STACK_CREATE
#define ITT_STACK_CREATE(obj)
Definition: itt_notify.h:117
ITT_NOTIFY
#define ITT_NOTIFY(name, obj)
Definition: itt_notify.h:112
scheduler.h
scheduler_common.h
__TBB_CONTEXT_ARG
#define __TBB_CONTEXT_ARG(arg1, context)
Definition: scheduler_common.h:60
s
void const char const char int ITT_FORMAT __itt_group_sync s
Definition: ittnotify_static.h:91
new_size
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 new_size
Definition: ittnotify_static.h:163
task
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 * task
Definition: ittnotify_static.h:119
count
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 count
Definition: ittnotify_static.h:145
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 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
Definition: ittnotify_static.h:176
size
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 size
Definition: ittnotify_static.h:109
sync_releasing
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
Definition: ittnotify_static.h:104
p
void const char const char int ITT_FORMAT __itt_group_sync p
Definition: ittnotify_static.h:91
tbb::internal::NFS_Allocate
void *__TBB_EXPORTED_FUNC NFS_Allocate(size_t n_element, size_t element_size, void *hint)
Allocate memory on cache/sector line boundary.
Definition: cache_aligned_allocator.cpp:176
tbb::internal::NFS_Free
void __TBB_EXPORTED_FUNC NFS_Free(void *)
Free memory allocated by NFS_Allocate.
Definition: cache_aligned_allocator.cpp:198
tbb
The graph class.
Definition: serial/tbb/parallel_for.h:46
tbb::internal
Identifiers declared inside namespace internal should never be used directly by client code.
Definition: atomic.h:65
tbb::internal::__TBB_store_relaxed
void __TBB_store_relaxed(volatile T &location, V value)
Definition: tbb_machine.h:742
tbb::internal::reference_count
intptr_t reference_count
A reference count.
Definition: task.h:131
tbb::internal::assert_task_valid
void assert_task_valid(const task *)
Definition: scheduler_common.h:237
tbb::internal::affinity_id
unsigned short affinity_id
An id as used for specifying affinity.
Definition: task.h:139
tbb::internal::es_ref_count_active
@ es_ref_count_active
Set if ref_count might be changed by another thread. Used for debugging.
Definition: scheduler_common.h:176
tbb::internal::get_initial_auto_partitioner_divisor
size_t __TBB_EXPORTED_FUNC get_initial_auto_partitioner_divisor()
Definition: task.cpp:149
tbb::internal::__TBB_load_relaxed
T __TBB_load_relaxed(const volatile T &location)
Definition: tbb_machine.h:738
tbb::internal::no_cache
@ no_cache
Disable caching for a small task.
Definition: scheduler_common.h:198
tbb::internal::local_task
@ local_task
Task is known to have been allocated by this scheduler.
Definition: scheduler_common.h:190
internal
Definition: _flow_graph_async_msg_impl.h:24
tbb::internal::affinity_partitioner_base_v3::my_size
size_t my_size
Number of elements in my_array.
Definition: partitioner.h:87
tbb::internal::affinity_partitioner_base_v3::resize
void __TBB_EXPORTED_METHOD resize(unsigned factor)
Resize my_array.
Definition: task.cpp:157
tbb::internal::affinity_partitioner_base_v3::my_array
affinity_id * my_array
Array that remembers affinities of tree positions to affinity_id.
Definition: partitioner.h:85
tbb::internal::allocate_additional_child_of_proxy::free
void __TBB_EXPORTED_METHOD free(task &) const
Definition: task.cpp:134
tbb::internal::allocate_additional_child_of_proxy::allocate
task &__TBB_EXPORTED_METHOD allocate(size_t size) const
Definition: task.cpp:128
tbb::internal::allocate_additional_child_of_proxy::parent
task & parent
Definition: task.h:60
tbb::interface5::internal::task_base::destroy
static void __TBB_EXPORTED_FUNC destroy(task &victim)
Destroy a task.
Definition: task.cpp:212
tbb::internal::allocate_root_with_context_proxy::my_context
task_group_context & my_context
Definition: task.h:156
tbb::internal::allocate_root_with_context_proxy::free
void __TBB_EXPORTED_METHOD free(task &) const
tbb::internal::allocate_root_with_context_proxy::allocate
task &__TBB_EXPORTED_METHOD allocate(size_t size) const
tbb::internal::allocate_root_proxy::free
static void __TBB_EXPORTED_FUNC free(task &)
Definition: task.cpp:47
tbb::internal::allocate_root_proxy::allocate
static task &__TBB_EXPORTED_FUNC allocate(size_t size)
Definition: task.cpp:35
tbb::internal::allocate_continuation_proxy::allocate
task &__TBB_EXPORTED_METHOD allocate(size_t size) const
Definition: task.cpp:96
tbb::internal::allocate_continuation_proxy::free
void __TBB_EXPORTED_METHOD free(task &) const
Definition: task.cpp:105
tbb::internal::allocate_child_proxy::free
void __TBB_EXPORTED_METHOD free(task &) const
Definition: task.cpp:121
tbb::internal::allocate_child_proxy::allocate
task &__TBB_EXPORTED_METHOD allocate(size_t size) const
Definition: task.cpp:114
tbb::internal::task_prefix
Memory prefix to a task object.
Definition: task.h:203
tbb::internal::task_prefix::next
tbb::task * next
"next" field for list of task
Definition: task.h:297
tbb::internal::task_prefix::ref_count
__TBB_atomic reference_count ref_count
Reference count used for synchronization.
Definition: task.h:274
tbb::internal::task_prefix::context
task_group_context * context
Shared context that is used to communicate asynchronous state changes.
Definition: task.h:230
tbb::internal::task_prefix::parent
tbb::task * parent
The task whose reference count includes me.
Definition: task.h:267
tbb::task_group_context
Used to form groups of tasks.
Definition: task.h:358
tbb::task_group_context::my_kind
__TBB_atomic kind_type my_kind
Flavor of this context: bound or isolated.
Definition: task.h:405
tbb::task_group_context::fp_settings
@ fp_settings
Definition: task.h:385
tbb::task_group_context::isolated
@ isolated
Definition: task.h:378
tbb::task_group_context::copy_fp_settings
void copy_fp_settings(const task_group_context &src)
Copies FPU control setting from another context.
tbb::task_group_context::itt_caller
__itt_caller itt_caller
Used to set and maintain stack stitching point for Intel Performance Tools.
Definition: task.h:418
tbb::task_group_context::bind_to
void bind_to(internal::generic_scheduler *local_sched)
Registers this context with the local scheduler and binds it to its parent context.
tbb::task_group_context::my_version_and_traits
uintptr_t my_version_and_traits
Version for run-time checks and behavioral traits of the context.
Definition: task.h:446
tbb::task_group_context::binding_required
static const kind_type binding_required
Definition: task.h:589
tbb::task
Base class for user-defined tasks.
Definition: task.h:615
tbb::task::change_group
void __TBB_EXPORTED_METHOD change_group(task_group_context &ctx)
Moves this task from its current group into another one.
tbb::task::note_affinity
virtual void __TBB_EXPORTED_METHOD note_affinity(affinity_id id)
Invoked by scheduler to notify task that it ran on unexpected thread.
Definition: task.cpp:245
tbb::task::allocated
@ allocated
task object is freshly allocated or recycled.
Definition: task.h:643
tbb::task::ready
@ ready
task is in ready pool, or is going to be put there, or was just taken off.
Definition: task.h:641
tbb::task::freed
@ freed
task object is on free list, or is going to be put there, or was just taken off.
Definition: task.h:645
tbb::task::state
state_type state() const
Current execution state.
Definition: task.h:912
tbb::task::internal_decrement_ref_count
internal::reference_count __TBB_EXPORTED_METHOD internal_decrement_ref_count()
Decrement reference count and return its new value.
Definition: task.cpp:192
tbb::task::prefix
internal::task_prefix & prefix(internal::version_tag *=NULL) const
Get reference to corresponding task_prefix.
Definition: task.h:1002
tbb::task::self
static task &__TBB_EXPORTED_FUNC self()
The innermost task being executed or destroyed by the current thread at the moment.
Definition: task.cpp:201
tbb::task::spawn_and_wait_for_all
void spawn_and_wait_for_all(task &child)
Similar to spawn followed by wait_for_all, but more efficient.
Definition: task.h:800
tbb::task::is_owned_by_current_thread
bool __TBB_EXPORTED_METHOD is_owned_by_current_thread() const
Obsolete, and only retained for the sake of backward compatibility. Always returns true.
Definition: task.cpp:208
tbb::task::parent
task * parent() const
task on whose behalf this task is working, or NULL if this is a root.
Definition: task.h:865
tbb::task::~task
virtual ~task()
Destructor.
Definition: task.h:629
tbb::task::increment_ref_count
void increment_ref_count()
Atomically increment reference count.
Definition: task.h:771
tbb::task::affinity_id
internal::affinity_id affinity_id
An id as used for specifying affinity.
Definition: task.h:940
tbb::task::internal_set_ref_count
void __TBB_EXPORTED_METHOD internal_set_ref_count(int count)
Set reference count.
Definition: task.cpp:183
tbb::task_list
A list of children.
Definition: task.h:1074
tbb::task_list::next_ptr
task ** next_ptr
Definition: task.h:1077
tbb::task_list::first
task * first
Definition: task.h:1076
tbb::task_list::clear
void clear()
Clear the list.
Definition: task.h:1118
tbb::internal::governor::local_scheduler_weak
static generic_scheduler * local_scheduler_weak()
Definition: governor.h:134
tbb::internal::governor::local_scheduler
static generic_scheduler * local_scheduler()
Obtain the thread-local instance of the TBB scheduler.
Definition: governor.h:129
tbb::internal::scheduler_state::my_innermost_running_task
task * my_innermost_running_task
Innermost task whose task::execute() is running. A dummy task on the outermost level.
Definition: scheduler.h:88
tbb::internal::generic_scheduler
Work stealing task scheduler.
Definition: scheduler.h:140
tbb::internal::generic_scheduler::free_task
void free_task(task &t)
Put task on free list.
Definition: scheduler.h:730
tbb::internal::generic_scheduler::allocate_task
task & allocate_task(size_t number_of_bytes, __TBB_CONTEXT_ARG(task *parent, task_group_context *context))
Allocate task object, either from the heap or a free list.
Definition: scheduler.cpp:337
tbb::internal::generic_scheduler::assert_task_pool_valid
void assert_task_pool_valid() const
Definition: scheduler.h:398
tbb::internal::generic_scheduler::max_threads_in_arena
unsigned max_threads_in_arena()
Returns the concurrency limit of the current arena.
Definition: scheduler.h:677

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