arena.h
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.
*/
#ifndef _TBB_arena_H
#define _TBB_arena_H
#include "tbb/tbb_stddef.h"
#include "tbb/atomic.h"
#include "tbb/tbb_machine.h"
#include "scheduler_common.h"
#include "intrusive_list.h"
#if __TBB_PREVIEW_CRITICAL_TASKS && __TBB_CPF_BUILD
#include "task_stream_extended.h"
#else
#include "task_stream.h"
#endif
#include "../rml/include/rml_tbb.h"
#include "mailbox.h"
#include "observer_proxy.h"
#include "market.h"
#include "governor.h"
#include "concurrent_monitor.h"
#if __TBB_PREVIEW_RESUMABLE_TASKS
#include "tbb/spin_mutex.h"
#endif
namespace tbb {
class task_group_context;
class allocate_root_with_context_proxy;
namespace internal {
#if __TBB_NUMA_SUPPORT
class numa_binding_observer;
#endif /*__TBB_NUMA_SUPPORT*/
#if __TBB_PREVIEW_RESUMABLE_TASKS
class arena_co_cache {
generic_scheduler** my_co_scheduler_cache;
unsigned my_head;
unsigned my_max_index;
tbb::spin_mutex my_co_cache_mutex;
unsigned next_index() {
return ( my_head == my_max_index ) ? 0 : my_head + 1;
}
unsigned prev_index() {
return ( my_head == 0 ) ? my_max_index : my_head - 1;
}
bool internal_empty() {
return my_co_scheduler_cache[prev_index()] == NULL;
}
void internal_scheduler_cleanup(generic_scheduler* to_cleanup) {
to_cleanup->my_arena_slot = NULL;
// Needed by cleanup_worker function, as well as arena slot clearing
governor::assume_scheduler(to_cleanup);
generic_scheduler::cleanup_worker(to_cleanup, true);
}
public:
void init(unsigned cache_capacity) {
size_t alloc_size = cache_capacity * sizeof(generic_scheduler*);
my_co_scheduler_cache = (generic_scheduler**)NFS_Allocate(1, alloc_size, NULL);
memset( my_co_scheduler_cache, 0, alloc_size );
my_head = 0;
my_max_index = cache_capacity - 1;
}
void cleanup() {
generic_scheduler* current = governor::local_scheduler_if_initialized();
while (generic_scheduler* to_cleanup = pop()) {
internal_scheduler_cleanup(to_cleanup);
}
governor::assume_scheduler(current);
NFS_Free(my_co_scheduler_cache);
}
void push(generic_scheduler* s) {
generic_scheduler* to_cleanup = NULL;
{
tbb::spin_mutex::scoped_lock lock(my_co_cache_mutex);
// Check if we are replacing some existing buffer entrance
if (my_co_scheduler_cache[my_head] != NULL) {
to_cleanup = my_co_scheduler_cache[my_head];
}
// Store the cached value
my_co_scheduler_cache[my_head] = s;
// Move head index to the next slot
my_head = next_index();
}
// Cleanup replaced buffer if any
if (to_cleanup) {
generic_scheduler* current = governor::local_scheduler_if_initialized();
internal_scheduler_cleanup(to_cleanup);
governor::assume_scheduler(current);
}
}
generic_scheduler* pop() {
tbb::spin_mutex::scoped_lock lock(my_co_cache_mutex);
// No cached coroutine
if (internal_empty()) return NULL;
// Move head index to the currently available value
my_head = prev_index();
// Retrieve the value from the buffer
generic_scheduler* to_return = my_co_scheduler_cache[my_head];
// Clear the previous entrance value
my_co_scheduler_cache[my_head] = NULL;
return to_return;
}
};
#endif // __TBB_PREVIEW_RESUMABLE_TASKS
struct arena_base : padded<intrusive_list_node> {
unsigned my_num_workers_allotted; // heavy use in stealing loop
atomic<unsigned> my_references; // heavy use in stealing loop
#if __TBB_TASK_PRIORITY
volatile intptr_t my_top_priority; // heavy use in stealing loop
#endif /* !__TBB_TASK_PRIORITY */
atomic<unsigned> my_limit; // heavy use in stealing loop
#if __TBB_PREVIEW_CRITICAL_TASKS && __TBB_CPF_BUILD
task_stream<num_priority_levels, front_accessor> my_task_stream; // heavy use in stealing loop
#else
task_stream<num_priority_levels> my_task_stream; // heavy use in stealing loop
#endif
#if __TBB_PREVIEW_CRITICAL_TASKS
// used on the hot path of the task dispatch loop
task_stream<1, back_nonnull_accessor> my_critical_task_stream;
#endif
unsigned my_max_num_workers;
int my_num_workers_requested;
tbb::atomic<uintptr_t> my_pool_state;
#if __TBB_ARENA_OBSERVER
observer_list my_observers;
#endif
#if __TBB_NUMA_SUPPORT
numa_binding_observer* my_numa_binding_observer;
#endif /*__TBB_NUMA_SUPPORT*/
#if __TBB_TASK_PRIORITY
intptr_t my_bottom_priority;
uintptr_t my_reload_epoch;
task* my_orphaned_tasks;
tbb::atomic<uintptr_t> my_abandonment_epoch;
tbb::atomic<intptr_t> my_skipped_fifo_priority;
#endif /* !__TBB_TASK_PRIORITY */
// Below are rarely modified members
market* my_market;
uintptr_t my_aba_epoch;
#if !__TBB_FP_CONTEXT
cpu_ctl_env my_cpu_ctl_env;
#endif
#if __TBB_TASK_GROUP_CONTEXT
task_group_context* my_default_ctx;
#endif /* __TBB_TASK_GROUP_CONTEXT */
unsigned my_num_slots;
unsigned my_num_reserved_slots;
#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
// arena needs an extra worker despite the arena limit
bool my_local_concurrency_mode;
// arena needs an extra worker despite a global limit
bool my_global_concurrency_mode;
#endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */
concurrent_monitor my_exit_monitors;
#if __TBB_PREVIEW_RESUMABLE_TASKS
arena_co_cache my_co_cache;
#endif
#if TBB_USE_ASSERT
uintptr_t my_guard;
#endif /* TBB_USE_ASSERT */
}; // struct arena_base
class arena: public padded<arena_base>
{
void restore_priority_if_need();
public:
typedef padded<arena_base> base_type;
enum new_work_type {
work_spawned,
wakeup,
work_enqueued
};
arena ( market&, unsigned max_num_workers, unsigned num_reserved_slots );
static arena& allocate_arena( market&, unsigned num_slots, unsigned num_reserved_slots );
static int unsigned num_arena_slots ( unsigned num_slots ) {
return max(2u, num_slots);
}
static int allocation_size ( unsigned num_slots ) {
return sizeof(base_type) + num_slots * (sizeof(mail_outbox) + sizeof(arena_slot));
}
mail_outbox& mailbox( affinity_id id ) {
__TBB_ASSERT( 0<id, "affinity id must be positive integer" );
__TBB_ASSERT( id <= my_num_slots, "affinity id out of bounds" );
return ((mail_outbox*)this)[-(int)id];
}
void free_arena ();
typedef uintptr_t pool_state_t;
static const pool_state_t SNAPSHOT_EMPTY = 0;
static const pool_state_t SNAPSHOT_FULL = pool_state_t(-1);
static const unsigned ref_external_bits = 12; // up to 4095 external and 1M workers
static const unsigned ref_external = 1;
static const unsigned ref_worker = 1<<ref_external_bits;
static bool is_busy_or_empty( pool_state_t s ) { return s < SNAPSHOT_FULL; }
unsigned num_workers_active() const {
return my_references >> ref_external_bits;
}
bool is_recall_requested() const {
return num_workers_active() > my_num_workers_allotted;
}
template<arena::new_work_type work_type> void advertise_new_work();
bool is_out_of_work();
void enqueue_task( task&, intptr_t, FastRandom & );
void process( generic_scheduler& );
template<unsigned ref_param>
inline void on_thread_leaving ( );
#if __TBB_STATISTICS
void dump_arena_statistics ();
#endif /* __TBB_STATISTICS */
#if __TBB_TASK_PRIORITY
inline bool may_have_tasks ( generic_scheduler*, bool& tasks_present, bool& dequeuing_possible );
void orphan_offloaded_tasks ( generic_scheduler& s );
#endif /* __TBB_TASK_PRIORITY */
#if __TBB_COUNT_TASK_NODES
intptr_t workers_task_node_count();
#endif
bool has_enqueued_tasks();
static const size_t out_of_arena = ~size_t(0);
template <bool as_worker>
size_t occupy_free_slot( generic_scheduler& s );
size_t occupy_free_slot_in_range( generic_scheduler& s, size_t lower, size_t upper );
arena_slot my_slots[1];
}; // class arena
template<unsigned ref_param>
inline void arena::on_thread_leaving ( ) {
//
// Implementation of arena destruction synchronization logic contained various
// bugs/flaws at the different stages of its evolution, so below is a detailed
// description of the issues taken into consideration in the framework of the
// current design.
//
// In case of using fire-and-forget tasks (scheduled via task::enqueue())
// master thread is allowed to leave its arena before all its work is executed,
// and market may temporarily revoke all workers from this arena. Since revoked
// workers never attempt to reset arena state to EMPTY and cancel its request
// to RML for threads, the arena object is destroyed only when both the last
// thread is leaving it and arena's state is EMPTY (that is its master thread
// left and it does not contain any work).
// Thus resetting arena to EMPTY state (as earlier TBB versions did) should not
// be done here (or anywhere else in the master thread to that matter); doing so
// can result either in arena's premature destruction (at least without
// additional costly checks in workers) or in unnecessary arena state changes
// (and ensuing workers migration).
//
// A worker that checks for work presence and transitions arena to the EMPTY
// state (in snapshot taking procedure arena::is_out_of_work()) updates
// arena::my_pool_state first and only then arena::my_num_workers_requested.
// So the check for work absence must be done against the latter field.
//
// In a time window between decrementing the active threads count and checking
// if there is an outstanding request for workers. New worker thread may arrive,
// finish remaining work, set arena state to empty, and leave decrementing its
// refcount and destroying. Then the current thread will destroy the arena
// the second time. To preclude it a local copy of the outstanding request
// value can be stored before decrementing active threads count.
//
// But this technique may cause two other problem. When the stored request is
// zero, it is possible that arena still has threads and they can generate new
// tasks and thus re-establish non-zero requests. Then all the threads can be
// revoked (as described above) leaving this thread the last one, and causing
// it to destroy non-empty arena.
//
// The other problem takes place when the stored request is non-zero. Another
// thread may complete the work, set arena state to empty, and leave without
// arena destruction before this thread decrements the refcount. This thread
// cannot destroy the arena either. Thus the arena may be "orphaned".
//
// In both cases we cannot dereference arena pointer after the refcount is
// decremented, as our arena may already be destroyed.
//
// If this is the master thread, the market is protected by refcount to it.
// In case of workers market's liveness is ensured by the RML connection
// rundown protocol, according to which the client (i.e. the market) lives
// until RML server notifies it about connection termination, and this
// notification is fired only after all workers return into RML.
//
// Thus if we decremented refcount to zero we ask the market to check arena
// state (including the fact if it is alive) under the lock.
//
uintptr_t aba_epoch = my_aba_epoch;
market* m = my_market;
__TBB_ASSERT(my_references >= ref_param, "broken arena reference counter");
#if __TBB_STATISTICS_EARLY_DUMP
// While still holding a reference to the arena, compute how many external references are left.
// If just one, dump statistics.
if ( modulo_power_of_two(my_references,ref_worker)==ref_param ) // may only be true with ref_external
GATHER_STATISTIC( dump_arena_statistics() );
#endif
#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
// When there is no workers someone must free arena, as
// without workers, no one calls is_out_of_work().
// Skip workerless arenas because they have no demand for workers.
// TODO: consider more strict conditions for the cleanup,
// because it can create the demand of workers,
// but the arena can be already empty (and so ready for destroying)
// TODO: Fix the race: while we check soft limit and it might be changed.
if( ref_param==ref_external && my_num_slots != my_num_reserved_slots
&& 0 == m->my_num_workers_soft_limit && !my_global_concurrency_mode ) {
bool is_out = false;
for (int i=0; i<num_priority_levels; i++) {
is_out = is_out_of_work();
if (is_out)
break;
}
// We expect, that in worst case it's enough to have num_priority_levels-1
// calls to restore priorities and yet another is_out_of_work() to conform
// that no work was found. But as market::set_active_num_workers() can be called
// concurrently, can't guarantee last is_out_of_work() return true.
}
#endif
if ( (my_references -= ref_param ) == 0 )
m->try_destroy_arena( this, aba_epoch );
}
template<arena::new_work_type work_type> void arena::advertise_new_work() {
if( work_type == work_enqueued ) {
#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
if ( as_atomic(my_market->my_num_workers_soft_limit) == 0 && as_atomic(my_global_concurrency_mode) == false )
my_market->enable_mandatory_concurrency(this);
if ( my_max_num_workers == 0 && my_num_reserved_slots == 1 ) {
__TBB_ASSERT(!my_local_concurrency_mode, NULL);
my_local_concurrency_mode = true;
my_pool_state = SNAPSHOT_FULL;
my_max_num_workers = 1;
my_market->adjust_demand(*this, my_max_num_workers);
return;
}
#endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */
// Local memory fence here and below is required to avoid missed wakeups; see the comment below.
// Starvation resistant tasks require concurrency, so missed wakeups are unacceptable.
atomic_fence();
}
else if( work_type == wakeup ) {
__TBB_ASSERT(my_max_num_workers!=0, "Unexpected worker wakeup request");
atomic_fence();
}
// Double-check idiom that, in case of spawning, is deliberately sloppy about memory fences.
// Technically, to avoid missed wakeups, there should be a full memory fence between the point we
// released the task pool (i.e. spawned task) and read the arena's state. However, adding such a
// fence might hurt overall performance more than it helps, because the fence would be executed
// on every task pool release, even when stealing does not occur. Since TBB allows parallelism,
// but never promises parallelism, the missed wakeup is not a correctness problem.
pool_state_t snapshot = my_pool_state;
if( is_busy_or_empty(snapshot) ) {
// Attempt to mark as full. The compare_and_swap below is a little unusual because the
// result is compared to a value that can be different than the comparand argument.
if( my_pool_state.compare_and_swap( SNAPSHOT_FULL, snapshot )==SNAPSHOT_EMPTY ) {
if( snapshot!=SNAPSHOT_EMPTY ) {
// This thread read "busy" into snapshot, and then another thread transitioned
// my_pool_state to "empty" in the meantime, which caused the compare_and_swap above
// to fail. Attempt to transition my_pool_state from "empty" to "full".
if( my_pool_state.compare_and_swap( SNAPSHOT_FULL, SNAPSHOT_EMPTY )!=SNAPSHOT_EMPTY ) {
// Some other thread transitioned my_pool_state from "empty", and hence became
// responsible for waking up workers.
return;
}
}
// This thread transitioned pool from empty to full state, and thus is responsible for
// telling the market that there is work to do.
#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
if( work_type == work_spawned ) {
if( my_local_concurrency_mode ) {
__TBB_ASSERT(my_max_num_workers==1, "");
__TBB_ASSERT(!governor::local_scheduler()->is_worker(), "");
// There was deliberate oversubscription on 1 core for sake of starvation-resistant tasks.
// Now a single active thread (must be the master) supposedly starts a new parallel region
// with relaxed sequential semantics, and oversubscription should be avoided.
// Demand for workers has been decreased to 0 during SNAPSHOT_EMPTY, so just keep it.
my_max_num_workers = 0;
my_local_concurrency_mode = false;
return;
}
if ( as_atomic(my_global_concurrency_mode) == true )
my_market->mandatory_concurrency_disable( this );
}
#endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */
// TODO: investigate adjusting of arena's demand by a single worker.
my_market->adjust_demand( *this, my_max_num_workers );
}
}
}
} // namespace internal
} // namespace tbb
#endif /* _TBB_arena_H */
atomic.h
spin_mutex.h
tbb_machine.h
tbb_stddef.h
__TBB_ASSERT
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
concurrent_monitor.h
governor.h
intrusive_list.h
mailbox.h
market.h
observer_proxy.h
scheduler_common.h
task_stream.h
task_stream_extended.h
GATHER_STATISTIC
#define GATHER_STATISTIC(x)
Definition: tbb_statistics.h:232
s
void const char const char int ITT_FORMAT __itt_group_sync s
Definition: ittnotify_static.h:91
lock
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 * lock
Definition: ittnotify_static.h:121
int
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_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id __itt_relation __itt_id ITT_FORMAT p const wchar_t int ITT_FORMAT __itt_group_mark d int
Definition: ittnotify_static.h:217
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::atomic_fence
void atomic_fence()
Sequentially consistent full memory fence.
Definition: tbb_machine.h:342
tbb::internal::affinity_id
unsigned short affinity_id
An id as used for specifying affinity.
Definition: task.h:139
tbb::internal::max
T max(const T &val1, const T &val2)
Utility template function returning greater of the two values.
Definition: tbb_misc.h:119
tbb::internal::as_atomic
atomic< T > & as_atomic(T &t)
Definition: atomic.h:572
tbb::internal::num_priority_levels
static const intptr_t num_priority_levels
Definition: scheduler_common.h:129
tbb::internal::modulo_power_of_two
argument_integer_type modulo_power_of_two(argument_integer_type arg, divisor_integer_type divisor)
A function to compute arg modulo divisor where divisor is a power of 2.
Definition: tbb_stddef.h:382
internal
Definition: _flow_graph_async_msg_impl.h:24
tbb::internal::cpu_ctl_env
Definition: gcc_ia32_common.h:70
tbb::spin_mutex
A lock that occupies a single byte.
Definition: spin_mutex.h:39
tbb::spin_mutex::scoped_lock
Represents acquisition of a mutex.
Definition: spin_mutex.h:53
tbb::task_group_context
Used to form groups of tasks.
Definition: task.h:358
tbb::task
Base class for user-defined tasks.
Definition: task.h:615
tbb::internal::padded
Pads type T to fill out to a multiple of cache line size.
Definition: tbb_stddef.h:261
tbb::internal::arena_base
The structure of an arena, except the array of slots.
Definition: arena.h:145
tbb::internal::arena_base::my_limit
atomic< unsigned > my_limit
The maximal number of currently busy slots.
Definition: arena.h:161
tbb::internal::arena_base::my_num_reserved_slots
unsigned my_num_reserved_slots
The number of reserved slots (can be occupied only by masters).
Definition: arena.h:253
tbb::internal::arena_base::my_aba_epoch
uintptr_t my_aba_epoch
ABA prevention marker.
Definition: arena.h:235
tbb::internal::arena_base::my_exit_monitors
concurrent_monitor my_exit_monitors
Waiting object for master threads that cannot join the arena.
Definition: arena.h:263
tbb::internal::arena_base::my_task_stream
task_stream< num_priority_levels > my_task_stream
Task pool for the tasks scheduled via task::enqueue() method.
Definition: arena.h:172
tbb::internal::arena_base::my_pool_state
tbb::atomic< uintptr_t > my_pool_state
Current task pool state and estimate of available tasks amount.
Definition: arena.h:195
tbb::internal::arena_base::my_num_workers_allotted
unsigned my_num_workers_allotted
The number of workers that have been marked out by the resource manager to service the arena.
Definition: arena.h:147
tbb::internal::arena_base::my_num_slots
unsigned my_num_slots
The number of slots in the arena.
Definition: arena.h:250
tbb::internal::arena_base::my_max_num_workers
unsigned my_max_num_workers
The number of workers requested by the master thread owning the arena.
Definition: arena.h:185
tbb::internal::arena_base::my_num_workers_requested
int my_num_workers_requested
The number of workers that are currently requested from the resource manager.
Definition: arena.h:188
tbb::internal::arena_base::my_market
market * my_market
The market that owns this arena.
Definition: arena.h:232
tbb::internal::arena_base::my_cpu_ctl_env
cpu_ctl_env my_cpu_ctl_env
FPU control settings of arena's master thread captured at the moment of arena instantiation.
Definition: arena.h:239
tbb::internal::arena_base::my_references
atomic< unsigned > my_references
Reference counter for the arena.
Definition: arena.h:153
tbb::internal::arena
Definition: arena.h:277
tbb::internal::arena::SNAPSHOT_EMPTY
static const pool_state_t SNAPSHOT_EMPTY
No tasks to steal since last snapshot was taken.
Definition: arena.h:318
tbb::internal::arena::occupy_free_slot_in_range
size_t occupy_free_slot_in_range(generic_scheduler &s, size_t lower, size_t upper)
Tries to occupy a slot in the specified range.
Definition: arena.cpp:115
tbb::internal::arena::ref_external
static const unsigned ref_external
Reference increment values for externals and workers.
Definition: arena.h:327
tbb::internal::arena::num_workers_active
unsigned num_workers_active() const
The number of workers active in the arena.
Definition: arena.h:334
tbb::internal::arena::new_work_type
new_work_type
Types of work advertised by advertise_new_work()
Definition: arena.h:284
tbb::internal::arena::work_spawned
@ work_spawned
Definition: arena.h:285
tbb::internal::arena::work_enqueued
@ work_enqueued
Definition: arena.h:287
tbb::internal::arena::wakeup
@ wakeup
Definition: arena.h:286
tbb::internal::arena::occupy_free_slot
size_t occupy_free_slot(generic_scheduler &s)
Tries to occupy a slot in the arena. On success, returns the slot index; if no slot is available,...
Definition: arena.cpp:130
tbb::internal::arena::free_arena
void free_arena()
Completes arena shutdown, destructs and deallocates it.
Definition: arena.cpp:296
tbb::internal::arena::num_arena_slots
static int unsigned num_arena_slots(unsigned num_slots)
Definition: arena.h:296
tbb::internal::arena::enqueue_task
void enqueue_task(task &, intptr_t, FastRandom &)
enqueue a task into starvation-resistance queue
Definition: arena.cpp:597
tbb::internal::arena::is_busy_or_empty
static bool is_busy_or_empty(pool_state_t s)
No tasks to steal or snapshot is being taken.
Definition: arena.h:331
tbb::internal::arena::my_slots
arena_slot my_slots[1]
Definition: arena.h:390
tbb::internal::arena::ref_external_bits
static const unsigned ref_external_bits
The number of least significant bits for external references.
Definition: arena.h:324
tbb::internal::arena::mailbox
mail_outbox & mailbox(affinity_id id)
Get reference to mailbox corresponding to given affinity_id.
Definition: arena.h:305
tbb::internal::arena::SNAPSHOT_FULL
static const pool_state_t SNAPSHOT_FULL
At least one task has been offered for stealing since the last snapshot started.
Definition: arena.h:321
tbb::internal::arena::is_recall_requested
bool is_recall_requested() const
Check if the recall is requested by the market.
Definition: arena.h:339
tbb::internal::arena::restore_priority_if_need
void restore_priority_if_need()
If enqueued tasks found, restore arena priority and task presence status.
Definition: arena.cpp:434
tbb::internal::arena::allocation_size
static int allocation_size(unsigned num_slots)
Definition: arena.h:300
tbb::internal::arena::is_out_of_work
bool is_out_of_work()
Check if there is job anywhere in arena.
Definition: arena.cpp:454
tbb::internal::arena::out_of_arena
static const size_t out_of_arena
Definition: arena.h:382
tbb::internal::arena::pool_state_t
uintptr_t pool_state_t
Definition: arena.h:315
tbb::internal::arena::arena
arena(market &, unsigned max_num_workers, unsigned num_reserved_slots)
Constructor.
Definition: arena.cpp:226
tbb::internal::arena::base_type
padded< arena_base > base_type
Definition: arena.h:281
tbb::internal::arena::has_enqueued_tasks
bool has_enqueued_tasks()
Check for the presence of enqueued tasks at all priority levels.
Definition: arena.cpp:426
tbb::internal::arena::advertise_new_work
void advertise_new_work()
If necessary, raise a flag that there is new job in arena.
Definition: arena.h:484
tbb::internal::arena::allocate_arena
static arena & allocate_arena(market &, unsigned num_slots, unsigned num_reserved_slots)
Allocate an instance of arena.
Definition: arena.cpp:285
tbb::internal::arena::on_thread_leaving
void on_thread_leaving()
Notification that worker or master leaves its arena.
Definition: arena.h:394
tbb::internal::arena::ref_worker
static const unsigned ref_worker
Definition: arena.h:328
tbb::internal::arena::process
void process(generic_scheduler &)
Registers the worker with the arena and enters TBB scheduler dispatch loop.
Definition: arena.cpp:146
tbb::internal::concurrent_monitor
concurrent_monitor
Definition: concurrent_monitor.h:93
tbb::internal::governor::local_scheduler_if_initialized
static generic_scheduler * local_scheduler_if_initialized()
Definition: governor.h:139
tbb::internal::governor::assume_scheduler
static void assume_scheduler(generic_scheduler *s)
Temporarily set TLS slot to the given scheduler.
Definition: governor.cpp:116
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::mail_outbox
Class representing where mail is put.
Definition: mailbox.h:99
tbb::internal::market
Definition: market.h:45
tbb::internal::market::try_destroy_arena
void try_destroy_arena(arena *, uintptr_t aba_epoch)
Removes the arena from the market's list.
Definition: market.cpp:333
tbb::internal::market::my_num_workers_soft_limit
unsigned my_num_workers_soft_limit
Current application-imposed limit on the number of workers (see set_active_num_workers())
Definition: market.h:78
tbb::internal::generic_scheduler
Work stealing task scheduler.
Definition: scheduler.h:140
tbb::internal::generic_scheduler::cleanup_worker
static void cleanup_worker(void *arg, bool worker)
Perform necessary cleanup when a worker thread finishes.
Definition: scheduler.cpp:1331
tbb::internal::arena_slot
Definition: scheduler_common.h:377
tbb::internal::task_stream
The container for "fairness-oriented" aka "enqueued" tasks.
Definition: task_stream.h:69
tbb::internal::FastRandom
A fast random number generator.
Definition: tbb_misc.h:135

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.