40 #if __TBB_SURVIVE_THREAD_SWITCH 44 #define CILKLIB_NAME "cilkrts20.dll" 46 #define CILKLIB_NAME "libcilkrts.so" 58 static atomic<do_once_state> cilkrts_load_state;
60 bool initialize_cilk_interop() {
78 handle_perror(status,
"TBB failed to initialize task scheduler TLS\n");
88 runtime_warning(
"TBB is unloaded while tbb::task_scheduler_init object is alive?" );
92 runtime_warning(
"failed to destroy task scheduler TLS: %s", strerror(status));
97 rml::tbb_server* server = NULL;
100 if( status != ::rml::factory::st_success ) {
102 runtime_warning(
"rml::tbb_factory::make_server failed with status %x, falling back on private rml", status );
115 __TBB_ASSERT( (uintptr_t(
s)&1) == 0,
"Bad pointer to the scheduler" );
117 return uintptr_t(
s) | uintptr_t((
s && (
s->my_arena ||
s->is_worker()))? 1 : 0);
131 #if __TBB_SURVIVE_THREAD_SWITCH 132 if( watch_stack_handler ) {
136 if( (*watch_stack_handler)(&
s->my_cilk_unwatch_thunk, o) ) {
138 s->my_cilk_unwatch_thunk.routine = NULL;
142 s->my_cilk_state = generic_scheduler::cs_running;
153 #if __TBB_SURVIVE_THREAD_SWITCH 163 #if __TBB_SURVIVE_THREAD_SWITCH 172 s->my_auto_initialized =
true;
181 __TBB_ASSERT(
s->my_ref_count == 1,
"weakly initialized scheduler must have refcount equal to 1" );
182 __TBB_ASSERT( !
s->my_arena,
"weakly initialized scheduler must have no arena" );
183 __TBB_ASSERT(
s->my_auto_initialized,
"weakly initialized scheduler is supposed to be auto-initialized" );
185 __TBB_ASSERT(
s->my_arena_index == 0,
"Master thread must occupy the first slot in its arena" );
186 s->my_arena_slot->my_scheduler =
s;
187 s->my_arena->my_default_ctx =
s->default_context();
192 if ( !auto_init )
s->my_ref_count += 1;
193 __TBB_ASSERT(
s->my_arena,
"scheduler is not initialized fully" );
201 __TBB_ASSERT(
s,
"Somehow a local scheduler creation for a master thread failed");
203 s->my_auto_initialized = auto_init;
210 if (0 == --(
s->my_ref_count)) {
211 ok =
s->cleanup_master( blocking );
219 if(
s &&
s->my_auto_initialized ) {
220 if( !--(
s->my_ref_count) ) {
225 s->cleanup_master(
false );
238 #if __TBB_SURVIVE_THREAD_SWITCH 239 if( watch_stack_handler )
249 #if __TBB_SURVIVE_THREAD_SWITCH 256 uintptr_t thread_id = GetCurrentThreadId();
258 uintptr_t thread_id = uintptr_t(pthread_self());
263 __TBB_ASSERT( !current &&
s->my_cilk_state==generic_scheduler::cs_limbo ||
264 current==
s &&
s->my_cilk_state==generic_scheduler::cs_running,
"invalid adoption" );
267 runtime_warning(
"redundant adoption of %p by thread %p\n",
s, (
void*)thread_id );
268 s->my_cilk_state = generic_scheduler::cs_running;
274 __TBB_ASSERT( current==
s &&
s->my_cilk_state==generic_scheduler::cs_running,
"invalid orphaning" );
276 s->my_cilk_state = generic_scheduler::cs_limbo;
282 __TBB_ASSERT( !current &&
s->my_cilk_state==generic_scheduler::cs_limbo ||
283 current==
s &&
s->my_cilk_state==generic_scheduler::cs_running,
"invalid release" );
285 s->my_cilk_state = generic_scheduler::cs_freed;
287 s->my_cilk_unwatch_thunk.routine = NULL;
304 using namespace internal;
308 initialize( number_of_threads, 0 );
312 #if __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS 313 uintptr_t new_mode = thread_stack_size & propagation_mode_mask;
316 if( number_of_threads!=deferred ) {
319 "number_of_threads for task_scheduler_init must be automatic or positive" );
321 #if __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS 322 if (
s->master_outermost_level() ) {
323 uintptr_t &vt =
s->default_context()->my_version_and_traits;
326 : new_mode & propagation_mode_captured ? vt & ~
task_group_context::exact_exception : vt;
330 my_scheduler = static_cast<scheduler*>((
generic_scheduler*)((uintptr_t)
s | prev_mode));
336 __TBB_ASSERT_RELEASE( !thread_stack_size,
"deferred initialization ignores stack size setting" );
341 #if __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS 342 uintptr_t prev_mode = (uintptr_t)my_scheduler & propagation_mode_exact;
343 my_scheduler = (
scheduler*)((uintptr_t)my_scheduler & ~(uintptr_t)propagation_mode_exact);
347 __TBB_ASSERT_RELEASE(
s,
"task_scheduler_init::terminate without corresponding task_scheduler_init::initialize()");
348 #if __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS 349 if (
s->master_outermost_level() ) {
350 uintptr_t &vt =
s->default_context()->my_version_and_traits;
359 internal_terminate(
false);
362 #if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE 363 bool task_scheduler_init::internal_blocking_terminate(
bool throwing ) {
364 bool ok = internal_terminate(
true );
365 #if TBB_USE_EXCEPTIONS 366 if( throwing && !ok )
373 #endif // __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE
void __TBB_EXPORTED_FUNC runtime_warning(const char *format,...)
Report a runtime warning.
static bool is_rethrow_broken
bool gcc_rethrow_exception_broken()
static void print_version_info()
__cilk_tbb_pfn_stack_op routine
static generic_scheduler * init_scheduler_weak()
Automatic initialization of scheduler in a master thread with default settings without arena.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
static generic_scheduler * create_master(arena *a)
Initialize a scheduler for a master thread.
static const int automatic
Typedef for number of threads that is automatic.
Used to form groups of tasks.
void suppress_unused_warning(const T1 &)
Utility template function to prevent "unused" warnings by various compilers.
static unsigned default_num_threads()
void PrintRMLVersionInfo(void *arg, const char *server_info)
A callback routine to print RML version information on stderr.
static void release_resources()
Destroy the thread-local storage key and deinitialize RML.
void __TBB_EXPORTED_METHOD initialize(int number_of_threads=automatic)
Ensure that scheduler exists for this thread.
static rml::tbb_server * create_rml_server(rml::tbb_client &)
static generic_scheduler * local_scheduler_if_initialized()
static arena * create_arena(int num_slots, int num_reserved_slots, size_t stack_size)
Creates an arena object.
void PrintExtraVersionInfo(const char *category, const char *format,...)
Prints arbitrary extra TBB version information on stderr.
Work stealing task scheduler.
Association between a handler name and location of pointer to it.
static void sign_off(generic_scheduler *s)
Unregister TBB scheduler instance from thread-local storage.
static void assume_scheduler(generic_scheduler *s)
Temporarily set TLS slot to the given scheduler.
static rml::tbb_factory theRMLServerFactory
OPEN_INTERNAL_NAMESPACE bool dynamic_link(const char *, const dynamic_link_descriptor *, size_t, dynamic_link_handle *handle, int)
static bool UsePrivateRML
void throw_exception(exception_id eid)
Versionless convenience wrapper for throw_exception_v4()
static uintptr_t tls_value_of(generic_scheduler *s)
Computes the value of the TLS.
static bool is_speculation_enabled
static void acquire_resources()
Create key for thread-local storage and initialize RML.
static bool initialization_done()
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_id __itt_string_handle __itt_metadata_type size_t void * data
static void sign_on(generic_scheduler *s)
Register TBB scheduler instance in thread-local storage.
static generic_scheduler * tls_scheduler_of(uintptr_t v)
Converts TLS value to the scheduler pointer.
static void initialize_rml_factory()
static basic_tls< uintptr_t > theTLS
TLS for scheduler instances associated with individual threads.
void destroy_process_mask()
static void one_time_init()
void atomic_do_once(const F &initializer, atomic< do_once_state > &state)
One-time initialization function.
static int __TBB_EXPORTED_FUNC default_num_threads()
Returns the number of threads TBB scheduler would create if initialized by default.
void DoOneTimeInitializations()
Performs thread-safe lazy one-time general TBB initialization.
const int DYNAMIC_LINK_GLOBAL
#define __TBB_ASSERT_RELEASE(predicate, message)
std::size_t stack_size_type
void const char const char int ITT_FORMAT __itt_group_sync s
tbb_server * make_private_server(tbb_client &client)
Factory method called from task.cpp to create a private_server.
static void auto_terminate(void *scheduler)
The internal routine to undo automatic initialization.
static bool is_set(generic_scheduler *s)
Used to check validity of the local scheduler TLS contents.
bool cpu_has_speculation()
check for transaction support.
void dynamic_unlink_all()
__cilk_tbb_pfn_unwatch_stacks routine
void __TBB_EXPORTED_FUNC handle_perror(int error_code, const char *aux_info)
Throws std::runtime_error with what() returning error_code description prefixed with aux_info.
void __TBB_EXPORTED_METHOD terminate()
Inverse of method initialize.
static bool terminate_scheduler(generic_scheduler *s, bool blocking)
Processes scheduler termination request (possibly nested) in a master thread.
static generic_scheduler * init_scheduler(int num_threads, stack_size_type stack_size, bool auto_init)
Processes scheduler initialization request (possibly nested) in a master thread.
bool internal_terminate(bool blocking)
CILK_EXPORT __cilk_tbb_retcode __cilkrts_watch_stack(struct __cilk_tbb_unwatch_thunk *u, struct __cilk_tbb_stack_op_thunk o)