Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
market.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2019 Intel Corporation
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 
17 #ifndef _TBB_market_H
18 #define _TBB_market_H
19 
20 #include "tbb/tbb_stddef.h"
21 
22 #include "scheduler_common.h"
23 #include "tbb/atomic.h"
24 #include "tbb/spin_rw_mutex.h"
25 #include "../rml/include/rml_tbb.h"
26 
27 #include "intrusive_list.h"
28 
29 #if defined(_MSC_VER) && defined(_Wp64)
30  // Workaround for overzealous compiler warnings in /Wp64 mode
31  #pragma warning (push)
32  #pragma warning (disable: 4244)
33 #endif
34 
35 namespace tbb {
36 
37 class task_group_context;
38 
39 namespace internal {
40 
41 //------------------------------------------------------------------------
42 // Class market
43 //------------------------------------------------------------------------
44 
45 class market : no_copy, rml::tbb_client {
46  friend class generic_scheduler;
47  friend class arena;
49  template<typename SchedulerTraits> friend class custom_scheduler;
51 private:
52  friend void ITT_DoUnsafeOneTimeInitialization ();
53 
56 
58  static market* theMarket;
59 
61 
63  static global_market_mutex_type theMarketMutex;
64 
67  arenas_list_mutex_type my_arenas_list_mutex;
68 
70  rml::tbb_server* my_server;
71 
73 
75 
77 
79 
82 
84 
86  atomic<unsigned> my_first_unused_worker_idx;
87 
90 
91 #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
92  int my_mandatory_num_requested;
94 #endif
95 
96 #if __TBB_TASK_PRIORITY
97 
102  intptr_t my_global_top_priority;
103 
105 
106  intptr_t my_global_bottom_priority;
107 
109 
111  uintptr_t my_global_reload_epoch;
112 
114  struct priority_level_info {
116  arena_list_type arenas;
117 
119 
120  arena *next_arena;
121 
123  int workers_requested;
124 
126  int workers_available;
127  }; // struct priority_level_info
128 
130  priority_level_info my_priority_levels[num_priority_levels];
131 
132 #else /* !__TBB_TASK_PRIORITY */
133 
135  arena_list_type my_arenas;
136 
138 
140 #endif /* !__TBB_TASK_PRIORITY */
141 
144 
146  unsigned my_ref_count;
147 
150 
153 
156 
158  static const unsigned skip_soft_limit_warning = ~0U;
159 
162 #if __TBB_COUNT_TASK_NODES
163 
165  atomic<intptr_t> my_task_node_count;
166 #endif /* __TBB_COUNT_TASK_NODES */
167 
169  market ( unsigned workers_soft_limit, unsigned workers_hard_limit, size_t stack_size );
170 
172  static market& global_market ( bool is_public, unsigned max_num_workers = 0, size_t stack_size = 0 );
173 
175  void destroy ();
176 
177 #if __TBB_TASK_PRIORITY
178  arena* arena_in_need ( arena* prev_arena );
180 
182  int update_workers_request();
183 
185 
187  void update_allotment ( intptr_t highest_affected_priority );
188 
190  void update_arena_top_priority ( arena& a, intptr_t newPriority );
191 
193  inline void update_global_top_priority ( intptr_t newPriority );
194 
196  inline void reset_global_priority ();
197 
198  inline void advance_global_reload_epoch () {
199  __TBB_store_with_release( my_global_reload_epoch, my_global_reload_epoch + 1 );
200  }
201 
202  void assert_market_valid () const {
203  __TBB_ASSERT( (my_priority_levels[my_global_top_priority].workers_requested > 0
204  && !my_priority_levels[my_global_top_priority].arenas.empty())
205  || (my_global_top_priority == my_global_bottom_priority &&
206  my_global_top_priority == normalized_normal_priority), NULL );
207  }
208 
209 #else /* !__TBB_TASK_PRIORITY */
210 
212 
215  if ( my_total_demand )
216  update_allotment( my_arenas, my_total_demand, (int)my_num_workers_soft_limit );
217  }
218 
219  // TODO: consider to rewrite the code with is_arena_in_list function
222  if(__TBB_load_with_acquire(my_total_demand) <= 0)
223  return NULL;
224  arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex, /*is_writer=*/false);
225  return arena_in_need(my_arenas, my_next_arena);
226  }
227  void assert_market_valid () const {}
228 #endif /* !__TBB_TASK_PRIORITY */
229 
231  // Helpers to unify code branches dependent on priority feature presence
232 
233  void insert_arena_into_list ( arena& a );
234 
235  void remove_arena_from_list ( arena& a );
236 
237  arena* arena_in_need ( arena_list_type &arenas, arena *hint );
238 
239  int update_allotment ( arena_list_type& arenas, int total_demand, int max_workers );
240 
241  bool is_arena_in_list( arena_list_type &arenas, arena *a );
242 
243 
245  // Implementation of rml::tbb_client interface methods
246 
247  version_type version () const __TBB_override { return 0; }
248 
250 
251  size_t min_stack_size () const __TBB_override { return worker_stack_size(); }
252 
253  policy_type policy () const __TBB_override { return throughput; }
254 
256 
257  void cleanup( job& j ) __TBB_override;
258 
260 
261  void process( job& j ) __TBB_override;
262 
263 public:
265 
267  static arena* create_arena ( int num_slots, int num_reserved_slots, size_t stack_size );
268 
270  void try_destroy_arena ( arena*, uintptr_t aba_epoch );
271 
273  void detach_arena ( arena& );
274 
276  bool release ( bool is_public, bool blocking_terminate );
277 
278 #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY
279  void enable_mandatory_concurrency_impl ( arena *a );
281 
283  void enable_mandatory_concurrency ( arena *a );
284 
286  void disable_mandatory_concurrency_impl(arena* a);
287 
289  void mandatory_concurrency_disable ( arena *a );
290 #endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */
291 
293 
294  void adjust_demand ( arena&, int delta );
295 
297  bool must_join_workers () const { return my_join_workers; }
298 
300  size_t worker_stack_size () const { return my_stack_size; }
301 
303  static void set_active_num_workers( unsigned w );
304 
306  static unsigned app_parallelism_limit();
307 
308 #if _WIN32||_WIN64
309  void register_master( ::rml::server::execution_resource_t& rsc_handle ) {
311  __TBB_ASSERT( my_server, "RML server not defined?" );
312  // the server may ignore registration and set master_exec_resource to NULL.
313  my_server->register_master( rsc_handle );
314  }
315 
317  void unregister_master( ::rml::server::execution_resource_t& rsc_handle ) const {
318  my_server->unregister_master( rsc_handle );
319  }
320 #endif /* WIN */
321 
322 #if __TBB_TASK_GROUP_CONTEXT
323 
328  template <typename T>
329  bool propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state );
330 #endif /* __TBB_TASK_GROUP_CONTEXT */
331 
332 #if __TBB_TASK_PRIORITY
333 
335  bool lower_arena_priority ( arena& a, intptr_t new_priority, uintptr_t old_reload_epoch );
336 
338 
344  bool update_arena_priority ( arena& a, intptr_t new_priority );
345 #endif /* __TBB_TASK_PRIORITY */
346 
347 #if __TBB_COUNT_TASK_NODES
348 
350  void update_task_node_count( intptr_t delta ) { my_task_node_count += delta; }
351 #endif /* __TBB_COUNT_TASK_NODES */
352 
353 #if __TBB_TASK_GROUP_CONTEXT
354  scheduler_list_type my_masters;
356 
358 
360  generic_scheduler* my_workers[1];
361 #endif /* __TBB_TASK_GROUP_CONTEXT */
362 
363  static unsigned max_num_workers() {
364  global_market_mutex_type::scoped_lock lock( theMarketMutex );
365  return theMarket? theMarket->my_num_workers_hard_limit : 0;
366  }
367 }; // class market
368 
369 } // namespace internal
370 } // namespace tbb
371 
372 #if defined(_MSC_VER) && defined(_Wp64)
373  // Workaround for overzealous compiler warnings in /Wp64 mode
374  #pragma warning (pop)
375 #endif // warning 4244 is back
376 
377 #endif /* _TBB_market_H */
void cleanup(job &j) __TBB_override
Definition: market.cpp:681
arena_list_type my_arenas
List of registered arenas.
Definition: market.h:135
arena * my_next_arena
The first arena to be checked when idle worker seeks for an arena to enter.
Definition: market.h:139
A scheduler with a customized evaluation loop.
market(unsigned workers_soft_limit, unsigned workers_hard_limit, size_t stack_size)
Constructor.
Definition: market.cpp:64
void assert_market_valid() const
Definition: market.h:227
void adjust_demand(arena &, int delta)
Request that arena&#39;s need in workers should be adjusted.
Definition: market.cpp:556
static unsigned max_num_workers()
Definition: market.h:363
void __TBB_store_with_release(volatile T &location, V value)
Definition: tbb_machine.h:716
bool my_join_workers
Shutdown mode.
Definition: market.h:155
bool must_join_workers() const
Used when RML asks for join mode during workers termination.
Definition: market.h:297
unsigned max_job_count() const __TBB_override
Definition: market.h:249
unsigned my_ref_count
Reference count controlling market object lifetime.
Definition: market.h:146
intrusive_list< arena > arena_list_type
Definition: market.h:54
scheduler_mutex_type global_market_mutex_type
Definition: market.h:60
void update_allotment()
Recalculates the number of workers assigned to each arena in the list.
Definition: market.h:214
job * create_one_job() __TBB_override
Definition: market.cpp:699
atomic< unsigned > my_first_unused_worker_idx
First unused index of worker.
Definition: market.h:86
rml::tbb_server * my_server
Pointer to the RML server object that services this TBB instance.
Definition: market.h:70
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:330
The graph class.
size_t min_stack_size() const __TBB_override
Definition: market.h:251
void process(job &j) __TBB_override
Definition: market.cpp:659
version_type version() const __TBB_override
Definition: market.h:247
arena * arena_in_need(arena *)
Returns next arena that needs more workers, or NULL.
Definition: market.h:221
unsigned my_public_ref_count
Count of master threads attached.
Definition: market.h:149
The scoped locking pattern.
Definition: spin_rw_mutex.h:86
size_t my_stack_size
Stack size of worker threads.
Definition: market.h:152
void try_destroy_arena(arena *, uintptr_t aba_epoch)
Removes the arena from the market&#39;s list.
Definition: market.cpp:332
int my_total_demand
Number of workers that were requested by all arenas.
Definition: market.h:89
void remove_arena_from_list(arena &a)
Definition: market.cpp:42
uintptr_t my_arenas_aba_epoch
ABA prevention marker to assign to newly created arenas.
Definition: market.h:143
T __TBB_load_with_acquire(const volatile T &location)
Definition: tbb_machine.h:712
void destroy()
Destroys and deallocates market object created by market::create()
Definition: market.cpp:165
unsigned my_num_workers_hard_limit
Maximal number of workers allowed for use by the underlying resource manager.
Definition: market.h:74
friend void ITT_DoUnsafeOneTimeInitialization()
int my_num_workers_requested
Number of workers currently requested from RML.
Definition: market.h:81
bool release(bool is_public, bool blocking_terminate)
Decrements market&#39;s refcount and destroys it in the end.
Definition: market.cpp:175
static global_market_mutex_type theMarketMutex
Mutex guarding creation/destruction of theMarket, insertions/deletions in my_arenas, and cancellation propagation.
Definition: market.h:63
Fast, unfair, spinning reader-writer lock with backoff and writer-preference.
Definition: spin_rw_mutex.h:38
static const unsigned skip_soft_limit_warning
The value indicating that the soft limit warning is unnecessary.
Definition: market.h:158
policy_type policy() const __TBB_override
Definition: market.h:253
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:96
size_t worker_stack_size() const
Returns the requested stack size of worker threads.
Definition: market.h:300
static market * theMarket
Currently active global market.
Definition: market.h:58
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:161
unsigned my_num_workers_soft_limit
Current application-imposed limit on the number of workers (see set_active_num_workers()) ...
Definition: market.h:78
#define __TBB_override
Definition: tbb_stddef.h:240
static void set_active_num_workers(unsigned w)
Set number of active workers.
Definition: market.cpp:235
void acknowledge_close_connection() __TBB_override
Definition: market.cpp:695
arenas_list_mutex_type my_arenas_list_mutex
Definition: market.h:67
__TBB_SCHEDULER_MUTEX_TYPE scheduler_mutex_type
Mutex type for global locks in the scheduler.
Used to form groups of tasks.
Definition: task.h:347
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
static unsigned app_parallelism_limit()
Reports active parallelism level according to user&#39;s settings.
Definition: tbb_main.cpp:513
void detach_arena(arena &)
Removes the arena from the market&#39;s list.
Definition: market.cpp:321
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
spin_rw_mutex arenas_list_mutex_type
Lightweight mutex guarding accounting operations with arenas list.
Definition: market.h:66
static arena * create_arena(int num_slots, int num_reserved_slots, size_t stack_size)
Creates an arena object.
Definition: market.cpp:307
bool is_arena_in_list(arena_list_type &arenas, arena *a)
Definition: market.cpp:423
void insert_arena_into_list(arena &a)
Definition: market.cpp:29
static const intptr_t num_priority_levels
Work stealing task scheduler.
Definition: scheduler.h:137
intrusive_list< generic_scheduler > scheduler_list_type
Definition: market.h:55

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.