Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
tbb::internal::market Class Reference

#include <market.h>

Inheritance diagram for tbb::internal::market:
Collaboration diagram for tbb::internal::market:

Public Member Functions

void try_destroy_arena (arena *, uintptr_t aba_epoch)
 Removes the arena from the market's list. More...
 
void detach_arena (arena &)
 Removes the arena from the market's list. More...
 
bool release (bool is_public, bool blocking_terminate)
 Decrements market's refcount and destroys it in the end. More...
 
void adjust_demand (arena &, int delta)
 Request that arena's need in workers should be adjusted. More...
 
bool must_join_workers () const
 Used when RML asks for join mode during workers termination. More...
 
size_t worker_stack_size () const
 Returns the requested stack size of worker threads. More...
 

Static Public Member Functions

static arenacreate_arena (int num_slots, int num_reserved_slots, size_t stack_size)
 Creates an arena object. More...
 
static void set_active_num_workers (unsigned w)
 Set number of active workers. More...
 
static unsigned app_parallelism_limit ()
 Reports active parallelism level according to user's settings. More...
 
static unsigned max_num_workers ()
 

Private Types

typedef intrusive_list< arenaarena_list_type
 
typedef intrusive_list< generic_schedulerscheduler_list_type
 
typedef scheduler_mutex_type global_market_mutex_type
 
typedef spin_rw_mutex arenas_list_mutex_type
 Lightweight mutex guarding accounting operations with arenas list. More...
 

Private Member Functions

 market (unsigned workers_soft_limit, unsigned workers_hard_limit, size_t stack_size)
 Constructor. More...
 
void destroy ()
 Destroys and deallocates market object created by market::create() More...
 
void update_allotment ()
 Recalculates the number of workers assigned to each arena in the list. More...
 
arenaarena_in_need (arena *)
 Returns next arena that needs more workers, or NULL. More...
 
void assert_market_valid () const
 
void insert_arena_into_list (arena &a)
 
void remove_arena_from_list (arena &a)
 
arenaarena_in_need (arena_list_type &arenas, arena *hint)
 
bool is_arena_in_list (arena_list_type &arenas, arena *a)
 
version_type version () const __TBB_override
 
unsigned max_job_count () const __TBB_override
 
size_t min_stack_size () const __TBB_override
 
policy_type policy () const __TBB_override
 
job * create_one_job () __TBB_override
 
void cleanup (job &j) __TBB_override
 
void acknowledge_close_connection () __TBB_override
 
void process (job &j) __TBB_override
 
- Private Member Functions inherited from tbb::internal::no_copy
 no_copy ()
 Allow default construction. More...
 

Static Private Member Functions

static marketglobal_market (bool is_public, unsigned max_num_workers=0, size_t stack_size=0)
 Factory method creating new market object. More...
 
static int update_allotment (arena_list_type &arenas, int total_demand, int max_workers)
 

Private Attributes

arenas_list_mutex_type my_arenas_list_mutex
 
rml::tbb_server * my_server
 Pointer to the RML server object that services this TBB instance. More...
 
unsigned my_num_workers_hard_limit
 Maximal number of workers allowed for use by the underlying resource manager. More...
 
unsigned my_num_workers_soft_limit
 Current application-imposed limit on the number of workers (see set_active_num_workers()) More...
 
int my_num_workers_requested
 Number of workers currently requested from RML. More...
 
atomic< unsigned > my_first_unused_worker_idx
 First unused index of worker. More...
 
int my_total_demand
 Number of workers that were requested by all arenas. More...
 
arena_list_type my_arenas
 List of registered arenas. More...
 
arenamy_next_arena
 The first arena to be checked when idle worker seeks for an arena to enter. More...
 
uintptr_t my_arenas_aba_epoch
 ABA prevention marker to assign to newly created arenas. More...
 
unsigned my_ref_count
 Reference count controlling market object lifetime. More...
 
unsigned my_public_ref_count
 Count of master threads attached. More...
 
size_t my_stack_size
 Stack size of worker threads. More...
 
bool my_join_workers
 Shutdown mode. More...
 
unsigned my_workers_soft_limit_to_report
 Either workers soft limit to be reported via runtime_warning() or skip_soft_limit_warning. More...
 

Static Private Attributes

static markettheMarket
 Currently active global market. More...
 
static global_market_mutex_type theMarketMutex
 Mutex guarding creation/destruction of theMarket, insertions/deletions in my_arenas, and cancellation propagation. More...
 
static const unsigned skip_soft_limit_warning = ~0U
 The value indicating that the soft limit warning is unnecessary. More...
 

Friends

class generic_scheduler
 
class arena
 
class tbb::interface7::internal::task_arena_base
 
template<typename SchedulerTraits >
class custom_scheduler
 
class tbb::task_group_context
 
void ITT_DoUnsafeOneTimeInitialization ()
 

Detailed Description

Definition at line 49 of file market.h.

Member Typedef Documentation

◆ arena_list_type

Definition at line 58 of file market.h.

◆ arenas_list_mutex_type

Lightweight mutex guarding accounting operations with arenas list.

Definition at line 70 of file market.h.

◆ global_market_mutex_type

◆ scheduler_list_type

Constructor & Destructor Documentation

◆ market()

tbb::internal::market::market ( unsigned  workers_soft_limit,
unsigned  workers_hard_limit,
size_t  stack_size 
)
private

Constructor.

Definition at line 68 of file market.cpp.

References __TBB_ASSERT, tbb::internal::governor::create_rml_server(), my_num_workers_soft_limit, and my_server.

Referenced by global_market().

69  : my_num_workers_hard_limit(workers_hard_limit)
70  , my_num_workers_soft_limit(workers_soft_limit)
71 #if __TBB_TASK_PRIORITY
72  , my_global_top_priority(normalized_normal_priority)
73  , my_global_bottom_priority(normalized_normal_priority)
74 #endif /* __TBB_TASK_PRIORITY */
75  , my_ref_count(1)
76  , my_stack_size(stack_size)
77  , my_workers_soft_limit_to_report(workers_soft_limit)
78 {
79 #if __TBB_TASK_PRIORITY
80  __TBB_ASSERT( my_global_reload_epoch == 0, NULL );
81  my_priority_levels[normalized_normal_priority].workers_available = my_num_workers_soft_limit;
82 #endif /* __TBB_TASK_PRIORITY */
83 
84  // Once created RML server will start initializing workers that will need
85  // global market instance to get worker stack size
87  __TBB_ASSERT( my_server, "Failed to create RML server" );
88 }
unsigned my_ref_count
Reference count controlling market object lifetime.
Definition: market.h:150
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
unsigned my_num_workers_hard_limit
Maximal number of workers allowed for use by the underlying resource manager.
Definition: market.h:78
rml::tbb_server * my_server
Pointer to the RML server object that services this TBB instance.
Definition: market.h:74
static rml::tbb_server * create_rml_server(rml::tbb_client &)
Definition: governor.cpp:96
size_t my_stack_size
Stack size of worker threads.
Definition: market.h:156
unsigned my_num_workers_soft_limit
Current application-imposed limit on the number of workers (see set_active_num_workers()) ...
Definition: market.h:82
unsigned my_workers_soft_limit_to_report
Either workers soft limit to be reported via runtime_warning() or skip_soft_limit_warning.
Definition: market.h:165
Here is the call graph for this function:
Here is the caller graph for this function:

Member Function Documentation

◆ acknowledge_close_connection()

void tbb::internal::market::acknowledge_close_connection ( )
private

Definition at line 756 of file market.cpp.

References destroy().

Referenced by policy().

756  {
757  destroy();
758 }
void destroy()
Destroys and deallocates market object created by market::create()
Definition: market.cpp:169
Here is the call graph for this function:
Here is the caller graph for this function:

◆ adjust_demand()

void tbb::internal::market::adjust_demand ( arena a,
int  delta 
)

Request that arena's need in workers should be adjusted.

Concurrent invocations are possible only on behalf of different arenas.

Definition at line 590 of file market.cpp.

References __TBB_ASSERT, assert_market_valid(), GATHER_STATISTIC, tbb::internal::governor::local_scheduler_if_initialized(), tbb::spin_rw_mutex_v3::lock(), tbb::internal::min(), my_arenas_list_mutex, tbb::internal::arena_base::my_market, tbb::internal::arena_base::my_num_workers_allotted, my_num_workers_requested, tbb::internal::arena_base::my_num_workers_requested, my_num_workers_soft_limit, my_server, my_total_demand, p, theMarket, tbb::spin_rw_mutex_v3::unlock(), and update_allotment().

Referenced by tbb::internal::arena::advertise_new_work(), is_arena_in_list(), tbb::internal::arena::is_out_of_work(), tbb::internal::generic_scheduler::nested_arena_entry(), tbb::internal::generic_scheduler::nested_arena_exit(), and policy().

590  {
591  __TBB_ASSERT( theMarket, "market instance was destroyed prematurely?" );
592  if ( !delta )
593  return;
595  int prev_req = a.my_num_workers_requested;
596  a.my_num_workers_requested += delta;
597  if ( a.my_num_workers_requested <= 0 ) {
598 #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
599  // must not recall worker from arena with mandatory parallelism
600  if ( a.my_market->my_mandatory_num_requested && a.my_concurrency_mode!=arena_base::cm_normal )
601  a.my_num_workers_allotted = 1;
602  else
603 #endif
604  a.my_num_workers_allotted = 0;
605  if ( prev_req <= 0 ) {
607  return;
608  }
609  delta = -prev_req;
610  }
611  else if ( prev_req < 0 ) {
612  delta = a.my_num_workers_requested;
613  }
614  my_total_demand += delta;
615 #if !__TBB_TASK_PRIORITY
617 #else /* !__TBB_TASK_PRIORITY */
618  intptr_t p = a.my_top_priority;
619  priority_level_info &pl = my_priority_levels[p];
620  pl.workers_requested += delta;
621  __TBB_ASSERT( pl.workers_requested >= 0, NULL );
622  if ( a.my_num_workers_requested <= 0 ) {
623  if ( a.my_top_priority != normalized_normal_priority ) {
624  GATHER_STATISTIC( ++governor::local_scheduler_if_initialized()->my_counters.arena_prio_resets );
625  update_arena_top_priority( a, normalized_normal_priority );
626  }
627  a.my_bottom_priority = normalized_normal_priority;
628  }
629  if ( p == my_global_top_priority ) {
630  if ( !pl.workers_requested ) {
631  while ( --p >= my_global_bottom_priority && !my_priority_levels[p].workers_requested )
632  continue;
633  if ( p < my_global_bottom_priority )
634  reset_global_priority();
635  else
636  update_global_top_priority(p);
637  }
638  update_allotment( my_global_top_priority );
639  }
640  else if ( p > my_global_top_priority ) {
641  __TBB_ASSERT( pl.workers_requested > 0, NULL );
642  // TODO: investigate if the following invariant is always valid
643  __TBB_ASSERT( a.my_num_workers_requested >= 0, NULL );
644  update_global_top_priority(p);
645  a.my_num_workers_allotted = min( (int)my_num_workers_soft_limit, a.my_num_workers_requested );
646 #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
647  // must not recall worker from arena with mandatory parallelism
648  if ( !a.my_num_workers_allotted && a.my_num_workers_requested
649  && a.my_market->my_mandatory_num_requested && a.my_concurrency_mode!=arena_base::cm_normal )
650  a.my_num_workers_allotted = 1;
651 #endif
652  my_priority_levels[p - 1].workers_available = my_num_workers_soft_limit - a.my_num_workers_allotted;
653  update_allotment( p - 1 );
654  }
655  else if ( p == my_global_bottom_priority ) {
656  if ( !pl.workers_requested ) {
657  while ( ++p <= my_global_top_priority && !my_priority_levels[p].workers_requested )
658  continue;
659  if ( p > my_global_top_priority )
660  reset_global_priority();
661  else
662  my_global_bottom_priority = p;
663  }
664  else
665  update_allotment( p );
666  }
667  else if ( p < my_global_bottom_priority ) {
668  int prev_bottom = my_global_bottom_priority;
669  my_global_bottom_priority = p;
670  update_allotment( prev_bottom );
671  }
672  else {
673  __TBB_ASSERT( my_global_bottom_priority < p && p < my_global_top_priority, NULL );
674  update_allotment( p );
675  }
676  __TBB_ASSERT( my_global_top_priority >= a.my_top_priority || a.my_num_workers_requested<=0, NULL );
678 #endif /* !__TBB_TASK_PRIORITY */
679  if ( delta > 0 ) {
680  // can't overflow soft_limit, but remember values request by arenas in
681  // my_total_demand to not prematurely release workers to RML
683  delta = my_num_workers_soft_limit - my_num_workers_requested;
684  } else {
685  // the number of workers should not be decreased below my_total_demand
688  }
689  my_num_workers_requested += delta;
691 
693  // Must be called outside of any locks
694  my_server->adjust_job_count_estimate( delta );
696 }
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
int my_num_workers_requested
Number of workers currently requested from RML.
Definition: market.h:85
T min(const T &val1, const T &val2)
Utility template function returning lesser of the two values.
Definition: tbb_misc.h:106
void update_allotment()
Recalculates the number of workers assigned to each arena in the list.
Definition: market.h:215
void const char const char int ITT_FORMAT __itt_group_sync p
static market * theMarket
Currently active global market.
Definition: market.h:62
rml::tbb_server * my_server
Pointer to the RML server object that services this TBB instance.
Definition: market.h:74
#define GATHER_STATISTIC(x)
void lock()
Acquire writer lock.
void unlock()
Release lock.
void assert_market_valid() const
Definition: market.h:228
static generic_scheduler * local_scheduler_if_initialized()
Definition: governor.h:136
arenas_list_mutex_type my_arenas_list_mutex
Definition: market.h:71
unsigned my_num_workers_soft_limit
Current application-imposed limit on the number of workers (see set_active_num_workers()) ...
Definition: market.h:82
int my_total_demand
Number of workers that were requested by all arenas.
Definition: market.h:93
Here is the call graph for this function:
Here is the caller graph for this function:

◆ app_parallelism_limit()

unsigned tbb::internal::market::app_parallelism_limit ( )
static

Reports active parallelism level according to user's settings.

Definition at line 492 of file tbb_main.cpp.

References tbb::internal::allowed_parallelism_control::active_value_if_present().

Referenced by tbb::internal::calc_workers_soft_limit(), global_market(), and worker_stack_size().

492  {
494 }
static allowed_parallelism_control allowed_parallelism_ctl
Definition: tbb_main.cpp:487
Here is the call graph for this function:
Here is the caller graph for this function:

◆ arena_in_need() [1/2]

arena* tbb::internal::market::arena_in_need ( arena )
inlineprivate

Returns next arena that needs more workers, or NULL.

Definition at line 222 of file market.h.

References tbb::internal::__TBB_load_with_acquire(), and lock.

Referenced by assert_market_valid(), is_arena_in_list(), and process().

222  {
224  return NULL;
225  arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex, /*is_writer=*/false);
227  }
T __TBB_load_with_acquire(const volatile T &location)
Definition: tbb_machine.h:716
arena * arena_in_need(arena *)
Returns next arena that needs more workers, or NULL.
Definition: market.h:222
arena_list_type my_arenas
List of registered arenas.
Definition: market.h:139
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
arena * my_next_arena
The first arena to be checked when idle worker seeks for an arena to enter.
Definition: market.h:143
arenas_list_mutex_type my_arenas_list_mutex
Definition: market.h:71
int my_total_demand
Number of workers that were requested by all arenas.
Definition: market.h:93
Here is the call graph for this function:
Here is the caller graph for this function:

◆ arena_in_need() [2/2]

arena * tbb::internal::market::arena_in_need ( arena_list_type arenas,
arena hint 
)
private

This method must be invoked under my_arenas_list_mutex.

Definition at line 363 of file market.cpp.

References __TBB_ASSERT, tbb::internal::intrusive_list_base< List, T >::begin(), tbb::internal::intrusive_list_base< List, T >::empty(), tbb::internal::intrusive_list_base< List, T >::end(), tbb::internal::arena_base::my_num_workers_allotted, tbb::internal::arena_base::my_references, tbb::internal::arena::num_workers_active(), and tbb::internal::arena::ref_worker.

363  {
364  if ( arenas.empty() )
365  return NULL;
366  arena_list_type::iterator it = hint;
367  __TBB_ASSERT( it != arenas.end(), NULL );
368  do {
369  arena& a = *it;
370  if ( ++it == arenas.end() )
371  it = arenas.begin();
372  if( a.num_workers_active() < a.my_num_workers_allotted
373 #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
374  && !a.recall_by_mandatory_request()
375 #endif
376  ) {
377  a.my_references += arena::ref_worker;
378  return &a;
379  }
380  } while ( it != hint );
381  return NULL;
382 }
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
friend class arena
Definition: market.h:51
static const unsigned ref_worker
Definition: arena.h:231
Here is the call graph for this function:

◆ assert_market_valid()

void tbb::internal::market::assert_market_valid ( ) const
inlineprivate

Definition at line 228 of file market.h.

References arena_in_need(), insert_arena_into_list(), is_arena_in_list(), remove_arena_from_list(), and update_allotment().

Referenced by adjust_demand(), create_one_job(), is_arena_in_list(), and try_destroy_arena().

228 {}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cleanup()

void tbb::internal::market::cleanup ( job &  j)
private

Definition at line 742 of file market.cpp.

References __TBB_ASSERT, tbb::internal::governor::assume_scheduler(), tbb::internal::generic_scheduler::cleanup_worker(), tbb::internal::generic_scheduler::is_worker(), tbb::internal::governor::local_scheduler_if_initialized(), s, and theMarket.

Referenced by policy().

742  {
743  __TBB_ASSERT( theMarket != this, NULL );
744  generic_scheduler& s = static_cast<generic_scheduler&>(j);
746  __TBB_ASSERT( !mine || mine->is_worker(), NULL );
747  if( mine!=&s ) {
749  generic_scheduler::cleanup_worker( &s, mine!=NULL );
751  } else {
753  }
754 }
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
static market * theMarket
Currently active global market.
Definition: market.h:62
static void assume_scheduler(generic_scheduler *s)
Temporarily set TLS slot to the given scheduler.
Definition: governor.cpp:120
static generic_scheduler * local_scheduler_if_initialized()
Definition: governor.h:136
void const char const char int ITT_FORMAT __itt_group_sync s
static void cleanup_worker(void *arg, bool worker)
Perform necessary cleanup when a worker thread finishes.
Definition: scheduler.cpp:1294
friend class generic_scheduler
Definition: market.h:50
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_arena()

arena * tbb::internal::market::create_arena ( int  num_slots,
int  num_reserved_slots,
size_t  stack_size 
)
static

Creates an arena object.

If necessary, also creates global market instance, and boosts its ref count. Each call to create_arena() must be matched by the call to arena::free_arena().

Definition at line 300 of file market.cpp.

References __TBB_ASSERT, tbb::internal::arena::allocate_arena(), global_market(), insert_arena_into_list(), lock, and my_arenas_list_mutex.

Referenced by tbb::internal::governor::init_scheduler(), tbb::interface7::internal::task_arena_base::internal_initialize(), and policy().

300  {
301  __TBB_ASSERT( num_slots > 0, NULL );
302  __TBB_ASSERT( num_reserved_slots <= num_slots, NULL );
303  // Add public market reference for master thread/task_arena (that adds an internal reference in exchange).
304  market &m = global_market( /*is_public=*/true, num_slots-num_reserved_slots, stack_size );
305 
306  arena& a = arena::allocate_arena( m, num_slots, num_reserved_slots );
307  // Add newly created arena into the existing market's list.
308  arenas_list_mutex_type::scoped_lock lock(m.my_arenas_list_mutex);
309  m.insert_arena_into_list(a);
310  return &a;
311 }
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
market(unsigned workers_soft_limit, unsigned workers_hard_limit, size_t stack_size)
Constructor.
Definition: market.cpp:68
friend class arena
Definition: market.h:51
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
static arena & allocate_arena(market &, unsigned num_slots, unsigned num_reserved_slots)
Allocate an instance of arena.
Definition: arena.cpp:242
static market & global_market(bool is_public, unsigned max_num_workers=0, size_t stack_size=0)
Factory method creating new market object.
Definition: market.cpp:100
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_one_job()

rml::job * tbb::internal::market::create_one_job ( )
private

Definition at line 760 of file market.cpp.

References __TBB_ASSERT, __TBB_ASSERT_EX, _T, tbb::internal::as_atomic(), assert_market_valid(), tbb::internal::generic_scheduler::create_worker(), GATHER_STATISTIC, insert_arena_into_list(), ITT_THREAD_SET_NAME, tbb::internal::governor::local_scheduler_if_initialized(), lock, tbb::internal::max(), my_arenas_list_mutex, my_first_unused_worker_idx, my_num_workers_hard_limit, tbb::internal::arena_base::my_num_workers_requested, p, tbb::release, remove_arena_from_list(), s, and update_allotment().

Referenced by policy().

760  {
761  unsigned index = ++my_first_unused_worker_idx;
762  __TBB_ASSERT( index > 0, NULL );
763  ITT_THREAD_SET_NAME(_T("TBB Worker Thread"));
764  // index serves as a hint decreasing conflicts between workers when they migrate between arenas
766 #if __TBB_TASK_GROUP_CONTEXT
767  __TBB_ASSERT( index <= my_num_workers_hard_limit, NULL );
768  __TBB_ASSERT( !my_workers[index - 1], NULL );
769  my_workers[index - 1] = s;
770 #endif /* __TBB_TASK_GROUP_CONTEXT */
771  return s;
772 }
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
unsigned my_num_workers_hard_limit
Maximal number of workers allowed for use by the underlying resource manager.
Definition: market.h:78
#define ITT_THREAD_SET_NAME(name)
Definition: itt_notify.h:121
#define _T(string_literal)
Standard Windows style macro to markup the string literals.
Definition: itt_notify.h:66
void const char const char int ITT_FORMAT __itt_group_sync s
atomic< unsigned > my_first_unused_worker_idx
First unused index of worker.
Definition: market.h:90
static generic_scheduler * create_worker(market &m, size_t index)
Initialize a scheduler for a worker thread.
Definition: scheduler.cpp:1239
friend class generic_scheduler
Definition: market.h:50
Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy()

void tbb::internal::market::destroy ( )
private

Destroys and deallocates market object created by market::create()

Definition at line 169 of file market.cpp.

References tbb::internal::NFS_Free(), tbb::internal::__TBB_InitOnce::remove_ref(), and tbb::internal::runtime_warning().

Referenced by acknowledge_close_connection().

169  {
170 #if __TBB_COUNT_TASK_NODES
171  if ( my_task_node_count )
172  runtime_warning( "Leaked %ld task objects\n", (long)my_task_node_count );
173 #endif /* __TBB_COUNT_TASK_NODES */
174  this->market::~market(); // qualified to suppress warning
175  NFS_Free( this );
177 }
void __TBB_EXPORTED_FUNC runtime_warning(const char *format,...)
Report a runtime warning.
void __TBB_EXPORTED_FUNC NFS_Free(void *)
Free memory allocated by NFS_Allocate.
static void remove_ref()
Remove reference to resources. If last reference removed, release the resources.
Definition: tbb_main.cpp:125
Here is the call graph for this function:
Here is the caller graph for this function:

◆ detach_arena()

void tbb::internal::market::detach_arena ( arena a)

Removes the arena from the market's list.

This method must be invoked under my_arenas_list_mutex.

Definition at line 314 of file market.cpp.

References __TBB_ASSERT, tbb::internal::arena_base::my_aba_epoch, my_arenas_aba_epoch, tbb::internal::arena_slot_line1::my_scheduler, tbb::internal::arena::my_slots, remove_arena_from_list(), and theMarket.

Referenced by policy(), and try_destroy_arena().

314  {
315  __TBB_ASSERT( theMarket == this, "Global market instance was destroyed prematurely?" );
316  __TBB_ASSERT( !a.my_slots[0].my_scheduler, NULL );
318  if ( a.my_aba_epoch == my_arenas_aba_epoch )
320 }
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void remove_arena_from_list(arena &a)
Definition: market.cpp:46
uintptr_t my_arenas_aba_epoch
ABA prevention marker to assign to newly created arenas.
Definition: market.h:147
static market * theMarket
Currently active global market.
Definition: market.h:62
Here is the call graph for this function:
Here is the caller graph for this function:

◆ global_market()

market & tbb::internal::market::global_market ( bool  is_public,
unsigned  max_num_workers = 0,
size_t  stack_size = 0 
)
staticprivate

Factory method creating new market object.

Definition at line 100 of file market.cpp.

References __TBB_ASSERT, __TBB_offsetof, tbb::interface9::global_control::active_value(), tbb::internal::__TBB_InitOnce::add_ref(), app_parallelism_limit(), tbb::internal::as_atomic(), tbb::internal::calc_workers_soft_limit(), tbb::internal::governor::default_num_threads(), lock, market(), tbb::internal::max(), my_num_workers_hard_limit, my_public_ref_count, my_ref_count, my_server, my_stack_size, my_workers_soft_limit_to_report, tbb::internal::NFS_Allocate(), tbb::internal::runtime_warning(), set_active_num_workers(), size, skip_soft_limit_warning, theMarket, theMarketMutex, tbb::interface9::global_control::thread_stack_size, and tbb::internal::governor::UsePrivateRML.

Referenced by create_arena(), tbb::internal::generic_scheduler::create_master(), tbb::interface7::internal::task_arena_base::internal_attach(), and tbb::interface7::internal::task_arena_base::internal_initialize().

100  {
101  global_market_mutex_type::scoped_lock lock( theMarketMutex );
102  market *m = theMarket;
103  if( m ) {
104  ++m->my_ref_count;
105  const unsigned old_public_count = is_public? m->my_public_ref_count++ : /*any non-zero value*/1;
106  lock.release();
107  if( old_public_count==0 )
108  set_active_num_workers( calc_workers_soft_limit(workers_requested, m->my_num_workers_hard_limit) );
109 
110  // do not warn if default number of workers is requested
111  if( workers_requested != governor::default_num_threads()-1 ) {
112  __TBB_ASSERT( skip_soft_limit_warning > workers_requested,
113  "skip_soft_limit_warning must be larger than any valid workers_requested" );
114  unsigned soft_limit_to_report = m->my_workers_soft_limit_to_report;
115  if( soft_limit_to_report < workers_requested ) {
116  runtime_warning( "The number of workers is currently limited to %u. "
117  "The request for %u workers is ignored. Further requests for more workers "
118  "will be silently ignored until the limit changes.\n",
119  soft_limit_to_report, workers_requested );
120  // The race is possible when multiple threads report warnings.
121  // We are OK with that, as there are just multiple warnings.
122  internal::as_atomic(m->my_workers_soft_limit_to_report).
123  compare_and_swap(skip_soft_limit_warning, soft_limit_to_report);
124  }
125 
126  }
127  if( m->my_stack_size < stack_size )
128  runtime_warning( "Thread stack size has been already set to %u. "
129  "The request for larger stack (%u) cannot be satisfied.\n",
130  m->my_stack_size, stack_size );
131  }
132  else {
133  // TODO: A lot is done under theMarketMutex locked. Can anything be moved out?
134  if( stack_size == 0 )
136  // Expecting that 4P is suitable for most applications.
137  // Limit to 2P for large thread number.
138  // TODO: ask RML for max concurrency and possibly correct hard_limit
139  const unsigned factor = governor::default_num_threads()<=128? 4 : 2;
140  // The requested number of threads is intentionally not considered in
141  // computation of the hard limit, in order to separate responsibilities
142  // and avoid complicated interactions between global_control and task_scheduler_init.
143  // The market guarantees that at least 256 threads might be created.
144  const unsigned workers_hard_limit = max(max(factor*governor::default_num_threads(), 256u), app_parallelism_limit());
145  const unsigned workers_soft_limit = calc_workers_soft_limit(workers_requested, workers_hard_limit);
146  // Create the global market instance
147  size_t size = sizeof(market);
148 #if __TBB_TASK_GROUP_CONTEXT
149  __TBB_ASSERT( __TBB_offsetof(market, my_workers) + sizeof(generic_scheduler*) == sizeof(market),
150  "my_workers must be the last data field of the market class");
151  size += sizeof(generic_scheduler*) * (workers_hard_limit - 1);
152 #endif /* __TBB_TASK_GROUP_CONTEXT */
154  void* storage = NFS_Allocate(1, size, NULL);
155  memset( storage, 0, size );
156  // Initialize and publish global market
157  m = new (storage) market( workers_soft_limit, workers_hard_limit, stack_size );
158  if( is_public )
159  m->my_public_ref_count = 1;
160  theMarket = m;
161  // This check relies on the fact that for shared RML default_concurrency==max_concurrency
162  if ( !governor::UsePrivateRML && m->my_server->default_concurrency() < workers_soft_limit )
163  runtime_warning( "RML might limit the number of workers to %u while %u is requested.\n"
164  , m->my_server->default_concurrency(), workers_soft_limit );
165  }
166  return *m;
167 }
void __TBB_EXPORTED_FUNC runtime_warning(const char *format,...)
Report a runtime warning.
void *__TBB_EXPORTED_FUNC NFS_Allocate(size_t n_element, size_t element_size, void *hint)
Allocate memory on cache/sector line boundary.
unsigned my_ref_count
Reference count controlling market object lifetime.
Definition: market.h:150
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
static const unsigned skip_soft_limit_warning
The value indicating that the soft limit warning is unnecessary.
Definition: market.h:162
market(unsigned workers_soft_limit, unsigned workers_hard_limit, size_t stack_size)
Constructor.
Definition: market.cpp:68
static unsigned calc_workers_soft_limit(unsigned workers_soft_limit, unsigned workers_hard_limit)
Definition: market.cpp:90
#define __TBB_offsetof(class_name, member_name)
Extended variant of the standard offsetof macro.
Definition: tbb_stddef.h:270
static size_t active_value(parameter p)
static void add_ref()
Add reference to resources. If first reference added, acquire the resources.
Definition: tbb_main.cpp:120
T max(const T &val1, const T &val2)
Utility template function returning greater of the two values.
Definition: tbb_misc.h:115
static market * theMarket
Currently active global market.
Definition: market.h:62
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
static unsigned app_parallelism_limit()
Reports active parallelism level according to user&#39;s settings.
Definition: tbb_main.cpp:492
static unsigned default_num_threads()
Definition: governor.h:85
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
static global_market_mutex_type theMarketMutex
Mutex guarding creation/destruction of theMarket, insertions/deletions in my_arenas, and cancellation propagation.
Definition: market.h:67
atomic< T > & as_atomic(T &t)
Definition: atomic.h:547
static void set_active_num_workers(unsigned w)
Set number of active workers.
Definition: market.cpp:221
static bool UsePrivateRML
Definition: governor.h:65
friend class generic_scheduler
Definition: market.h:50
Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_arena_into_list()

void tbb::internal::market::insert_arena_into_list ( arena a)
private

Definition at line 33 of file market.cpp.

References tbb::internal::intrusive_list_base< List, T >::begin(), my_arenas, my_next_arena, tbb::internal::intrusive_list_base< List, T >::push_front(), and tbb::internal::intrusive_list_base< List, T >::size().

Referenced by assert_market_valid(), create_arena(), and create_one_job().

33  {
34 #if __TBB_TASK_PRIORITY
35  arena_list_type &arenas = my_priority_levels[a.my_top_priority].arenas;
36  arena *&next = my_priority_levels[a.my_top_priority].next_arena;
37 #else /* !__TBB_TASK_PRIORITY */
38  arena_list_type &arenas = my_arenas;
39  arena *&next = my_next_arena;
40 #endif /* !__TBB_TASK_PRIORITY */
41  arenas.push_front( a );
42  if ( arenas.size() == 1 )
43  next = &*arenas.begin();
44 }
intrusive_list< arena > arena_list_type
Definition: market.h:58
arena_list_type my_arenas
List of registered arenas.
Definition: market.h:139
friend class arena
Definition: market.h:51
arena * my_next_arena
The first arena to be checked when idle worker seeks for an arena to enter.
Definition: market.h:143
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_arena_in_list()

bool tbb::internal::market::is_arena_in_list ( arena_list_type arenas,
arena a 
)
private

This method must be invoked under my_arenas_list_mutex.

Definition at line 417 of file market.cpp.

References __TBB_ASSERT, __TBB_ASSERT_EX, adjust_demand(), arena_in_need(), tbb::internal::as_atomic(), assert_market_valid(), tbb::internal::intrusive_list_base< List, T >::begin(), tbb::internal::intrusive_list_base< List, T >::end(), GATHER_STATISTIC, tbb::internal::governor::local_scheduler_if_initialized(), lock, my_arenas_list_mutex, tbb::internal::arena_base::my_max_num_workers, tbb::internal::arena_base::my_num_workers_allotted, tbb::internal::arena_base::my_num_workers_requested, my_num_workers_soft_limit, my_server, my_total_demand, p, and update_allotment().

Referenced by assert_market_valid().

417  {
418  if ( a ) {
419  for ( arena_list_type::iterator it = arenas.begin(); it != arenas.end(); ++it )
420  if ( a == &*it )
421  return true;
422  }
423  return false;
424 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ max_job_count()

unsigned tbb::internal::market::max_job_count ( ) const
inlineprivate

Definition at line 250 of file market.h.

References my_num_workers_hard_limit.

250 { return my_num_workers_hard_limit; }
unsigned my_num_workers_hard_limit
Maximal number of workers allowed for use by the underlying resource manager.
Definition: market.h:78

◆ max_num_workers()

static unsigned tbb::internal::market::max_num_workers ( )
inlinestatic

Definition at line 361 of file market.h.

References lock, and my_num_workers_hard_limit.

Referenced by tbb::internal::allowed_parallelism_control::active_value().

361  {
362  global_market_mutex_type::scoped_lock lock( theMarketMutex );
364  }
unsigned my_num_workers_hard_limit
Maximal number of workers allowed for use by the underlying resource manager.
Definition: market.h:78
static market * theMarket
Currently active global market.
Definition: market.h:62
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
static global_market_mutex_type theMarketMutex
Mutex guarding creation/destruction of theMarket, insertions/deletions in my_arenas, and cancellation propagation.
Definition: market.h:67
Here is the caller graph for this function:

◆ min_stack_size()

size_t tbb::internal::market::min_stack_size ( ) const
inlineprivate

Definition at line 252 of file market.h.

References worker_stack_size().

252 { return worker_stack_size(); }
size_t worker_stack_size() const
Returns the requested stack size of worker threads.
Definition: market.h:298
Here is the call graph for this function:

◆ must_join_workers()

bool tbb::internal::market::must_join_workers ( ) const
inline

Used when RML asks for join mode during workers termination.

Definition at line 295 of file market.h.

References my_join_workers.

295 { return my_join_workers; }
bool my_join_workers
Shutdown mode.
Definition: market.h:159

◆ policy()

policy_type tbb::internal::market::policy ( ) const
inlineprivate

Definition at line 254 of file market.h.

References __TBB_override, acknowledge_close_connection(), adjust_demand(), cleanup(), create_arena(), create_one_job(), detach_arena(), process(), release(), and try_destroy_arena().

254 { return throughput; }
Here is the call graph for this function:

◆ process()

void tbb::internal::market::process ( job &  j)
private

Definition at line 698 of file market.cpp.

References __TBB_ASSERT, __TBB_Yield, arena_in_need(), tbb::internal::intrusive_list_base< List, T >::empty(), GATHER_STATISTIC, tbb::internal::governor::is_set(), tbb::internal::scheduler_state::my_arena, my_arenas, tbb::internal::arena::process(), and s.

Referenced by policy().

698  {
699  generic_scheduler& s = static_cast<generic_scheduler&>(j);
700  // s.my_arena can be dead. Don't access it until arena_in_need is called
701  arena *a = s.my_arena;
702  __TBB_ASSERT( governor::is_set(&s), NULL );
703  enum {
704  query_interval = 1000,
705  first_interval = 1
706  };
707  for(int i = first_interval; ; i--) {
708  while ( (a = arena_in_need(a)) )
709  {
710  a->process(s);
711  a = NULL; // To avoid double checks in arena_in_need
712  i = first_interval;
713  }
714  // Workers leave market because there is no arena in need. It can happen earlier than
715  // adjust_job_count_estimate() decreases my_slack and RML can put this thread to sleep.
716  // It might result in a busy-loop checking for my_slack<0 and calling this method instantly.
717  // first_interval>0 and the yield refines this spinning.
718  if( i > 0 )
719  __TBB_Yield();
720  else
721 #if !__TBB_SLEEP_PERMISSION
722  break;
723 #else
724  { // i == 0
725 #if __TBB_TASK_PRIORITY
726  arena_list_type &al = my_priority_levels[my_global_top_priority].arenas;
727 #else /* __TBB_TASK_PRIORITY */
729 #endif /* __TBB_TASK_PRIORITY */
730  if( al.empty() ) // races if any are innocent TODO: replace by an RML query interface
731  break; // no arenas left, perhaps going to shut down
732  if( the_global_observer_list.ask_permission_to_leave() )
733  break; // go sleep
734  __TBB_Yield();
735  i = query_interval;
736  }
737 #endif// !__TBB_SLEEP_PERMISSION
738  }
739  GATHER_STATISTIC( ++s.my_counters.market_roundtrips );
740 }
intrusive_list< arena > arena_list_type
Definition: market.h:58
arena * arena_in_need(arena *)
Returns next arena that needs more workers, or NULL.
Definition: market.h:222
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
arena_list_type my_arenas
List of registered arenas.
Definition: market.h:139
#define __TBB_Yield()
Definition: ibm_aix51.h:48
friend class arena
Definition: market.h:51
#define GATHER_STATISTIC(x)
void const char const char int ITT_FORMAT __itt_group_sync s
static bool is_set(generic_scheduler *s)
Used to check validity of the local scheduler TLS contents.
Definition: governor.cpp:124
friend class generic_scheduler
Definition: market.h:50
Here is the call graph for this function:
Here is the caller graph for this function:

◆ release()

bool tbb::internal::market::release ( bool  is_public,
bool  blocking_terminate 
)

Decrements market's refcount and destroys it in the end.

Definition at line 179 of file market.cpp.

References __TBB_ASSERT, tbb::internal::__TBB_load_with_acquire(), __TBB_Yield, lock, my_join_workers, my_public_ref_count, my_ref_count, my_server, theMarket, and theMarketMutex.

Referenced by tbb::internal::generic_scheduler::cleanup_master(), tbb::internal::generic_scheduler::create_master(), tbb::internal::arena::free_arena(), tbb::interface7::internal::task_arena_base::internal_initialize(), tbb::interface7::internal::task_arena_base::internal_terminate(), policy(), and set_active_num_workers().

179  {
180  __TBB_ASSERT( theMarket == this, "Global market instance was destroyed prematurely?" );
181  bool do_release = false;
182  {
183  global_market_mutex_type::scoped_lock lock( theMarketMutex );
184  if ( blocking_terminate ) {
185  __TBB_ASSERT( is_public, "Only an object with a public reference can request the blocking terminate" );
186  while ( my_public_ref_count == 1 && my_ref_count > 1 ) {
187  lock.release();
188  // To guarantee that request_close_connection() is called by the last master, we need to wait till all
189  // references are released. Re-read my_public_ref_count to limit waiting if new masters are created.
190  // Theoretically, new private references to the market can be added during waiting making it potentially
191  // endless.
192  // TODO: revise why the weak scheduler needs market's pointer and try to remove this wait.
193  // Note that the market should know about its schedulers for cancelation/exception/priority propagation,
194  // see e.g. task_group_context::cancel_group_execution()
196  __TBB_Yield();
197  lock.acquire( theMarketMutex );
198  }
199  }
200  if ( is_public ) {
201  __TBB_ASSERT( theMarket == this, "Global market instance was destroyed prematurely?" );
204  }
205  if ( --my_ref_count == 0 ) {
207  do_release = true;
208  theMarket = NULL;
209  }
210  }
211  if( do_release ) {
212  __TBB_ASSERT( !__TBB_load_with_acquire(my_public_ref_count), "No public references remain if we remove the market." );
213  // inform RML that blocking termination is required
214  my_join_workers = blocking_terminate;
215  my_server->request_close_connection();
216  return blocking_terminate;
217  }
218  return false;
219 }
unsigned my_ref_count
Reference count controlling market object lifetime.
Definition: market.h:150
T __TBB_load_with_acquire(const volatile T &location)
Definition: tbb_machine.h:716
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
bool my_join_workers
Shutdown mode.
Definition: market.h:159
#define __TBB_Yield()
Definition: ibm_aix51.h:48
static market * theMarket
Currently active global market.
Definition: market.h:62
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
rml::tbb_server * my_server
Pointer to the RML server object that services this TBB instance.
Definition: market.h:74
unsigned my_public_ref_count
Count of master threads attached.
Definition: market.h:153
static global_market_mutex_type theMarketMutex
Mutex guarding creation/destruction of theMarket, insertions/deletions in my_arenas, and cancellation propagation.
Definition: market.h:67
Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_arena_from_list()

void tbb::internal::market::remove_arena_from_list ( arena a)
private

Definition at line 46 of file market.cpp.

References __TBB_ASSERT, tbb::internal::intrusive_list_base< List, T >::begin(), tbb::internal::intrusive_list_base< List, T >::end(), my_arenas, my_next_arena, tbb::internal::intrusive_list_base< List, T >::remove(), and tbb::internal::intrusive_list_base< List, T >::size().

Referenced by assert_market_valid(), create_one_job(), and detach_arena().

46  {
47 #if __TBB_TASK_PRIORITY
48  arena_list_type &arenas = my_priority_levels[a.my_top_priority].arenas;
49  arena *&next = my_priority_levels[a.my_top_priority].next_arena;
50 #else /* !__TBB_TASK_PRIORITY */
51  arena_list_type &arenas = my_arenas;
52  arena *&next = my_next_arena;
53 #endif /* !__TBB_TASK_PRIORITY */
54  arena_list_type::iterator it = next;
55  __TBB_ASSERT( it != arenas.end(), NULL );
56  if ( next == &a ) {
57  if ( ++it == arenas.end() && arenas.size() > 1 )
58  it = arenas.begin();
59  next = &*it;
60  }
61  arenas.remove( a );
62 }
intrusive_list< arena > arena_list_type
Definition: market.h:58
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
arena_list_type my_arenas
List of registered arenas.
Definition: market.h:139
friend class arena
Definition: market.h:51
arena * my_next_arena
The first arena to be checked when idle worker seeks for an arena to enter.
Definition: market.h:143
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_active_num_workers()

void tbb::internal::market::set_active_num_workers ( unsigned  w)
static

Set number of active workers.

Definition at line 221 of file market.cpp.

References __TBB_ASSERT, tbb::internal::intrusive_list_base< List, T >::begin(), tbb::internal::intrusive_list_base< List, T >::end(), lock, tbb::internal::min(), my_arenas, my_arenas_list_mutex, my_num_workers_hard_limit, my_num_workers_requested, my_num_workers_soft_limit, my_ref_count, my_server, my_total_demand, my_workers_soft_limit_to_report, p, release(), theMarket, theMarketMutex, and update_allotment().

Referenced by tbb::internal::allowed_parallelism_control::apply_active(), global_market(), and worker_stack_size().

221  {
222  int old_requested=0, requested=0;
223  bool need_mandatory = false;
224  market *m;
225 
226  {
227  global_market_mutex_type::scoped_lock lock( theMarketMutex );
228  if ( !theMarket )
229  return; // actual value will be used at market creation
230  m = theMarket;
231  ++m->my_ref_count;
232  }
233  // have my_ref_count for market, use it safely
234  {
235  arenas_list_mutex_type::scoped_lock lock( m->my_arenas_list_mutex );
236  __TBB_ASSERT(soft_limit <= m->my_num_workers_hard_limit, NULL);
237  m->my_num_workers_soft_limit = soft_limit;
238  // report only once after new soft limit value is set
239  m->my_workers_soft_limit_to_report = soft_limit;
240 
241 #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
242  // updates soft_limit to zero must be postponed
243  // while mandatory parallelism is enabled
244  if( !(m->my_mandatory_num_requested && !soft_limit) )
245 #endif
246  {
247  const int demand =
248 #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
249  m->my_mandatory_num_requested? 0 :
250 #endif
251  m->my_total_demand;
252  requested = min(demand, (int)soft_limit);
253  old_requested = m->my_num_workers_requested;
254  m->my_num_workers_requested = requested;
255 #if __TBB_TASK_PRIORITY
256  m->my_priority_levels[m->my_global_top_priority].workers_available = soft_limit;
257  m->update_allotment( m->my_global_top_priority );
258 #else
259  m->update_allotment();
260 #endif
261  }
262 #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
263  if( !m->my_mandatory_num_requested && !soft_limit ) {
264  // enable mandatory concurrency, if enqueued tasks are found
265  // and zero soft_limit requested
266 #if __TBB_TASK_PRIORITY
267  for( int p = m->my_global_top_priority; p >= m->my_global_bottom_priority; --p ) {
268  priority_level_info &pl = m->my_priority_levels[p];
269  arena_list_type &arenas = pl.arenas;
270 #else
271  const int p = 0;
272  arena_list_type &arenas = m->my_arenas;
273 #endif /* __TBB_TASK_PRIORITY */
274  for( arena_list_type::iterator it = arenas.begin(); it != arenas.end(); ++it ) {
275  if( !it->my_task_stream.empty(p) ) {
276  // switch local_mandatory to global_mandatory unconditionally
277  if( m->mandatory_concurrency_enable_impl( &*it ) )
278  need_mandatory = true;
279  }
280  }
281 #if __TBB_TASK_PRIORITY
282  }
283 #endif /* __TBB_TASK_PRIORITY */
284  }
285 #endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */
286  }
287  // adjust_job_count_estimate must be called outside of any locks
288  int delta = requested - old_requested;
289  if( need_mandatory ) ++delta;
290  if( delta!=0 )
291  m->my_server->adjust_job_count_estimate( delta );
292  // release internal market reference to match ++m->my_ref_count above
293  m->release( /*is_public=*/false, /*blocking_terminate=*/false );
294 }
unsigned my_ref_count
Reference count controlling market object lifetime.
Definition: market.h:150
intrusive_list< arena > arena_list_type
Definition: market.h:58
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
market(unsigned workers_soft_limit, unsigned workers_hard_limit, size_t stack_size)
Constructor.
Definition: market.cpp:68
unsigned my_num_workers_hard_limit
Maximal number of workers allowed for use by the underlying resource manager.
Definition: market.h:78
T min(const T &val1, const T &val2)
Utility template function returning lesser of the two values.
Definition: tbb_misc.h:106
void const char const char int ITT_FORMAT __itt_group_sync p
static market * theMarket
Currently active global market.
Definition: market.h:62
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
static global_market_mutex_type theMarketMutex
Mutex guarding creation/destruction of theMarket, insertions/deletions in my_arenas, and cancellation propagation.
Definition: market.h:67
Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_destroy_arena()

void tbb::internal::market::try_destroy_arena ( arena a,
uintptr_t  aba_epoch 
)

Removes the arena from the market's list.

Definition at line 322 of file market.cpp.

References __TBB_ASSERT, assert_market_valid(), tbb::internal::intrusive_list_base< List, T >::begin(), detach_arena(), tbb::internal::intrusive_list_base< List, T >::end(), tbb::internal::arena::free_arena(), tbb::spin_rw_mutex_v3::lock(), my_arenas, my_arenas_list_mutex, tbb::internal::arena_base::my_max_num_workers, tbb::internal::arena_base::my_num_workers_allotted, tbb::internal::arena_base::my_num_workers_requested, tbb::internal::arena_base::my_pool_state, my_ref_count, tbb::internal::arena_base::my_references, tbb::internal::num_priority_levels, p, tbb::internal::arena::SNAPSHOT_EMPTY, theMarket, and tbb::spin_rw_mutex_v3::unlock().

Referenced by tbb::internal::arena::on_thread_leaving(), and policy().

322  {
323  bool locked = true;
324  __TBB_ASSERT( a, NULL );
325  // we hold reference to the market, so it cannot be destroyed at any moment here
326  __TBB_ASSERT( this == theMarket, NULL );
327  __TBB_ASSERT( my_ref_count!=0, NULL );
330 #if __TBB_TASK_PRIORITY
331  // scan all priority levels, not only in [my_global_bottom_priority;my_global_top_priority]
332  // range, because arena to be destroyed can have no outstanding request for workers
333  for ( int p = num_priority_levels-1; p >= 0; --p ) {
334  priority_level_info &pl = my_priority_levels[p];
335  arena_list_type &my_arenas = pl.arenas;
336 #endif /* __TBB_TASK_PRIORITY */
337  arena_list_type::iterator it = my_arenas.begin();
338  for ( ; it != my_arenas.end(); ++it ) {
339  if ( a == &*it ) {
340  if ( it->my_aba_epoch == aba_epoch ) {
341  // Arena is alive
342  if ( !a->my_num_workers_requested && !a->my_references ) {
343  __TBB_ASSERT( !a->my_num_workers_allotted && (a->my_pool_state == arena::SNAPSHOT_EMPTY || !a->my_max_num_workers), "Inconsistent arena state" );
344  // Arena is abandoned. Destroy it.
345  detach_arena( *a );
347  locked = false;
348  a->free_arena();
349  }
350  }
351  if (locked)
353  return;
354  }
355  }
356 #if __TBB_TASK_PRIORITY
357  }
358 #endif /* __TBB_TASK_PRIORITY */
360 }
unsigned my_ref_count
Reference count controlling market object lifetime.
Definition: market.h:150
intrusive_list< arena > arena_list_type
Definition: market.h:58
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void detach_arena(arena &)
Removes the arena from the market&#39;s list.
Definition: market.cpp:314
static const pool_state_t SNAPSHOT_EMPTY
No tasks to steal since last snapshot was taken.
Definition: arena.h:221
arena_list_type my_arenas
List of registered arenas.
Definition: market.h:139
void const char const char int ITT_FORMAT __itt_group_sync p
static market * theMarket
Currently active global market.
Definition: market.h:62
static const intptr_t num_priority_levels
void lock()
Acquire writer lock.
void unlock()
Release lock.
void assert_market_valid() const
Definition: market.h:228
arenas_list_mutex_type my_arenas_list_mutex
Definition: market.h:71
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_allotment() [1/2]

void tbb::internal::market::update_allotment ( )
inlineprivate

Recalculates the number of workers assigned to each arena in the list.

The actual number of workers servicing a particular arena may temporarily deviate from the calculated value.

Definition at line 215 of file market.h.

Referenced by adjust_demand(), assert_market_valid(), create_one_job(), is_arena_in_list(), and set_active_num_workers().

215  {
216  if ( my_total_demand )
218  }
arena_list_type my_arenas
List of registered arenas.
Definition: market.h:139
void update_allotment()
Recalculates the number of workers assigned to each arena in the list.
Definition: market.h:215
unsigned my_num_workers_soft_limit
Current application-imposed limit on the number of workers (see set_active_num_workers()) ...
Definition: market.h:82
int my_total_demand
Number of workers that were requested by all arenas.
Definition: market.h:93
Here is the caller graph for this function:

◆ update_allotment() [2/2]

int tbb::internal::market::update_allotment ( arena_list_type arenas,
int  total_demand,
int  max_workers 
)
staticprivate

Definition at line 384 of file market.cpp.

References __TBB_ASSERT, tbb::internal::intrusive_list_base< List, T >::begin(), tbb::internal::intrusive_list_base< List, T >::end(), tbb::internal::min(), tbb::internal::arena_base::my_max_num_workers, tbb::internal::arena_base::my_num_workers_allotted, and tbb::internal::arena_base::my_num_workers_requested.

384  {
385  __TBB_ASSERT( workers_demand, NULL );
386  max_workers = min(workers_demand, max_workers);
387  int carry = 0;
388  int assigned = 0;
389  arena_list_type::iterator it = arenas.begin();
390  for ( ; it != arenas.end(); ++it ) {
391  arena& a = *it;
392  if ( a.my_num_workers_requested <= 0 ) {
393  __TBB_ASSERT( !a.my_num_workers_allotted, NULL );
394  continue;
395  }
396  int tmp = a.my_num_workers_requested * max_workers + carry;
397  int allotted = tmp / workers_demand;
398  carry = tmp % workers_demand;
399  // a.my_num_workers_requested may temporarily exceed a.my_max_num_workers
400  allotted = min( allotted, (int)a.my_max_num_workers );
401 #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
402  if ( !allotted && a.must_have_concurrency() )
403  allotted = 1;
404 #endif
405  a.my_num_workers_allotted = allotted;
406  assigned += allotted;
407  }
408 #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
409  __TBB_ASSERT( assigned <= workers_demand, NULL ); // weaker assertion due to enforced allotment
410 #else
411  __TBB_ASSERT( assigned <= max_workers, NULL );
412 #endif
413  return assigned;
414 }
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
T min(const T &val1, const T &val2)
Utility template function returning lesser of the two values.
Definition: tbb_misc.h:106
friend class arena
Definition: market.h:51
Here is the call graph for this function:

◆ version()

version_type tbb::internal::market::version ( ) const
inlineprivate

Definition at line 248 of file market.h.

248 { return 0; }

◆ worker_stack_size()

size_t tbb::internal::market::worker_stack_size ( ) const
inline

Returns the requested stack size of worker threads.

Definition at line 298 of file market.h.

References __TBB_ASSERT, app_parallelism_limit(), my_stack_size, and set_active_num_workers().

Referenced by tbb::internal::generic_scheduler::init_stack_info(), and min_stack_size().

298 { return my_stack_size; }
size_t my_stack_size
Stack size of worker threads.
Definition: market.h:156
Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ arena

friend class arena
friend

Definition at line 51 of file market.h.

◆ custom_scheduler

template<typename SchedulerTraits >
friend class custom_scheduler
friend

Definition at line 53 of file market.h.

◆ generic_scheduler

friend class generic_scheduler
friend

Definition at line 50 of file market.h.

◆ ITT_DoUnsafeOneTimeInitialization

void ITT_DoUnsafeOneTimeInitialization ( )
friend

◆ tbb::interface7::internal::task_arena_base

Definition at line 52 of file market.h.

◆ tbb::task_group_context

friend class tbb::task_group_context
friend

Definition at line 54 of file market.h.

Member Data Documentation

◆ my_arenas

arena_list_type tbb::internal::market::my_arenas
private

List of registered arenas.

Definition at line 139 of file market.h.

Referenced by insert_arena_into_list(), process(), remove_arena_from_list(), set_active_num_workers(), and try_destroy_arena().

◆ my_arenas_aba_epoch

uintptr_t tbb::internal::market::my_arenas_aba_epoch
private

ABA prevention marker to assign to newly created arenas.

Definition at line 147 of file market.h.

Referenced by tbb::internal::arena::arena(), and detach_arena().

◆ my_arenas_list_mutex

arenas_list_mutex_type tbb::internal::market::my_arenas_list_mutex
private

◆ my_first_unused_worker_idx

atomic<unsigned> tbb::internal::market::my_first_unused_worker_idx
private

First unused index of worker.

Used to assign indices to the new workers coming from RML, and busy part of my_workers array.

Definition at line 90 of file market.h.

Referenced by create_one_job().

◆ my_join_workers

bool tbb::internal::market::my_join_workers
private

Shutdown mode.

Definition at line 159 of file market.h.

Referenced by must_join_workers(), and release().

◆ my_next_arena

arena* tbb::internal::market::my_next_arena
private

The first arena to be checked when idle worker seeks for an arena to enter.

The check happens in round-robin fashion.

Definition at line 143 of file market.h.

Referenced by insert_arena_into_list(), and remove_arena_from_list().

◆ my_num_workers_hard_limit

unsigned tbb::internal::market::my_num_workers_hard_limit
private

Maximal number of workers allowed for use by the underlying resource manager.

It can't be changed after market creation.

Definition at line 78 of file market.h.

Referenced by create_one_job(), global_market(), max_job_count(), max_num_workers(), and set_active_num_workers().

◆ my_num_workers_requested

int tbb::internal::market::my_num_workers_requested
private

Number of workers currently requested from RML.

Definition at line 85 of file market.h.

Referenced by adjust_demand(), and set_active_num_workers().

◆ my_num_workers_soft_limit

unsigned tbb::internal::market::my_num_workers_soft_limit
private

Current application-imposed limit on the number of workers (see set_active_num_workers())

It can't be more than my_num_workers_hard_limit.

Definition at line 82 of file market.h.

Referenced by adjust_demand(), tbb::internal::arena::advertise_new_work(), is_arena_in_list(), market(), tbb::internal::arena::on_thread_leaving(), and set_active_num_workers().

◆ my_public_ref_count

unsigned tbb::internal::market::my_public_ref_count
private

Count of master threads attached.

Definition at line 153 of file market.h.

Referenced by global_market(), and release().

◆ my_ref_count

unsigned tbb::internal::market::my_ref_count
private

Reference count controlling market object lifetime.

Definition at line 150 of file market.h.

Referenced by global_market(), release(), set_active_num_workers(), and try_destroy_arena().

◆ my_server

rml::tbb_server* tbb::internal::market::my_server
private

Pointer to the RML server object that services this TBB instance.

Definition at line 74 of file market.h.

Referenced by adjust_demand(), global_market(), is_arena_in_list(), market(), release(), and set_active_num_workers().

◆ my_stack_size

size_t tbb::internal::market::my_stack_size
private

Stack size of worker threads.

Definition at line 156 of file market.h.

Referenced by global_market(), and worker_stack_size().

◆ my_total_demand

int tbb::internal::market::my_total_demand
private

Number of workers that were requested by all arenas.

Definition at line 93 of file market.h.

Referenced by adjust_demand(), is_arena_in_list(), and set_active_num_workers().

◆ my_workers_soft_limit_to_report

unsigned tbb::internal::market::my_workers_soft_limit_to_report
private

Either workers soft limit to be reported via runtime_warning() or skip_soft_limit_warning.

Definition at line 165 of file market.h.

Referenced by global_market(), and set_active_num_workers().

◆ skip_soft_limit_warning

const unsigned tbb::internal::market::skip_soft_limit_warning = ~0U
staticprivate

The value indicating that the soft limit warning is unnecessary.

Definition at line 162 of file market.h.

Referenced by global_market().

◆ theMarket

market * tbb::internal::market::theMarket
staticprivate

Currently active global market.

Definition at line 62 of file market.h.

Referenced by adjust_demand(), cleanup(), detach_arena(), global_market(), release(), set_active_num_workers(), and try_destroy_arena().

◆ theMarketMutex

market::global_market_mutex_type tbb::internal::market::theMarketMutex
staticprivate

Mutex guarding creation/destruction of theMarket, insertions/deletions in my_arenas, and cancellation propagation.

Definition at line 67 of file market.h.

Referenced by global_market(), release(), and set_active_num_workers().


The documentation for this class was generated from the following files:

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.