boost::uint32_t get_parent_locality_id() { thread_self* self = get_self_ptr(); return (0 != self) ? reinterpret_cast<thread_data*>(self->get_thread_id())->get_parent_locality_id() : naming::invalid_locality_id; }
thread_id_type get_parent_id() { thread_self* self = get_self_ptr(); return (0 != self) ? reinterpret_cast<thread_data*>(self->get_thread_id())->get_parent_thread_id() : threads::invalid_thread_id; }
std::size_t get_parent_phase() { thread_self* self = get_self_ptr(); return (0 != self) ? reinterpret_cast<thread_data*>(self->get_thread_id())->get_parent_thread_phase() : 0; }
std::size_t get_parent_phase() { thread_self* self = get_self_ptr(); return (0 != self) ? static_cast<thread_data_base*>(self->get_thread_id())->get_parent_thread_phase() : 0; }
thread_id_type get_parent_id() { thread_self* self = get_self_ptr(); return (0 != self) ? static_cast<thread_data_base*>(self->get_thread_id())->get_parent_thread_id() : threads::invalid_thread_id; }
thread_self& get_self() { thread_self* p = get_self_ptr(); if (HPX_UNLIKELY(!p)) { HPX_THROW_EXCEPTION(null_thread_id, "threads::get_self", "NULL thread id encountered (is this executed on a HPX-thread?)"); } return *p; }
naming::address::address_type get_self_component_id() { #if !HPX_THREAD_MAINTAIN_TARGET_ADDRESS return 0; #else thread_self* self = get_self_ptr(); return (0 != self) ? reinterpret_cast<thread_data*>(self->get_thread_id())->get_component_id() : 0; #endif }
~scheduler_specific_ptr() { // clean up data if this type is used locally for one thread if (get_self_ptr()) { detail::set_tss_data(this, std::shared_ptr<coroutines::detail::tss_cleanup_function>(), 0, true); } }
hpx::future<typename util::result_of<F&&(Ts &&...)>::type> run_as_os_thread(F && f, Ts &&... vs) { HPX_ASSERT(get_self_ptr() != 0); typedef executors::io_pool_executor executor_type; typedef parallel::executor_traits<executor_type> traits; executor_type scheduler; return traits::async_execute(scheduler, std::forward<F>(f), std::forward<Ts>(vs)...); }
inline void create_thread( policies::scheduler_base* scheduler, thread_init_data& data, threads::thread_id_type& id, thread_state_enum initial_state = pending, bool run_now = true, error_code& ec = throws) { // verify parameters switch (initial_state) { case pending: case pending_do_not_schedule: case suspended: break; default: { std::ostringstream strm; strm << "invalid initial state: " << get_thread_state_name(initial_state); HPX_THROWS_IF(ec, bad_parameter, "threads::detail::create_thread", strm.str()); return; } } #ifdef HPX_HAVE_THREAD_DESCRIPTION if (!data.description) { HPX_THROWS_IF(ec, bad_parameter, "threads::detail::create_thread", "description is nullptr"); return; } #endif thread_self* self = get_self_ptr(); #ifdef HPX_HAVE_THREAD_PARENT_REFERENCE if (nullptr == data.parent_id) { if (self) { data.parent_id = threads::get_self_id().get(); data.parent_phase = self->get_thread_phase(); } } if (0 == data.parent_locality_id) data.parent_locality_id = get_locality_id(); #endif if (nullptr == data.scheduler_base) data.scheduler_base = scheduler; // Pass critical priority from parent to child. if (self) { if (thread_priority_critical == threads::get_self_id()->get_priority()) data.priority = thread_priority_critical; } // create the new thread std::size_t num_thread = data.num_os_thread; scheduler->create_thread(data, &id, initial_state, run_now, ec, num_thread); LTM_(info) << "register_thread(" << id << "): initial_state(" << get_thread_state_name(initial_state) << "), " << "run_now(" << (run_now ? "true" : "false") #ifdef HPX_HAVE_THREAD_DESCRIPTION << "), description(" << data.description #endif << ")"; // potentially wake up waiting thread scheduler->do_some_work(num_thread); }
thread_id_type get_self_id() { thread_self* self = get_self_ptr(); return (0 != self) ? self->get_thread_id() : threads::invalid_thread_id; }
inline threads::thread_id_type create_thread( policies::scheduler_base* scheduler, thread_init_data& data, thread_state_enum initial_state = pending, bool run_now = true, error_code& ec = throws) { // verify parameters switch (initial_state) { case pending: case suspended: break; default: { hpx::util::osstream strm; strm << "invalid initial state: " << get_thread_state_name(initial_state); HPX_THROWS_IF(ec, bad_parameter, "threads::detail::create_thread", hpx::util::osstream_get_string(strm)); return invalid_thread_id; } } #if HPX_THREAD_MAINTAIN_DESCRIPTION if (0 == data.description) { HPX_THROWS_IF(ec, bad_parameter, "threads::detail::create_thread", "description is NULL"); return invalid_thread_id; } #endif #if HPX_THREAD_MAINTAIN_PARENT_REFERENCE if (0 == data.parent_id) { thread_self* self = get_self_ptr(); if (self) { data.parent_id = threads::get_self_id().get(); data.parent_phase = self->get_thread_phase(); } } if (0 == data.parent_locality_id) data.parent_locality_id = get_locality_id(); #endif if (0 == data.scheduler_base) data.scheduler_base = scheduler; // create the new thread thread_id_type newid = scheduler->create_thread( data, initial_state, run_now, ec, data.num_os_thread); LTM_(info) << "register_thread(" << newid << "): initial_state(" << get_thread_state_name(initial_state) << "), " << "run_now(" << (run_now ? "true" : "false") #if HPX_THREAD_MAINTAIN_DESCRIPTION << "), description(" << data.description #endif << ")"; return newid; }
~thread_specific_ptr() { // clean up data if this type is used locally for one thread if (get_self_ptr()) coroutines::detail::erase_tss_node(this, true); }