Beispiel #1
0
    threads::thread_priority get_thread_priority(thread_id_type id, error_code& ec)
    {
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
        if (NULL == app)
        {
            HPX_THROWS_IF(ec, invalid_status,
                "hpx::threads::get_thread_priority",
                "global applier object is not accessible");
            return threads::thread_priority_unknown;
        }

        if (&ec != &throws)
            ec = make_success_code();

        return app->get_thread_manager().get_priority(id);
    }
Beispiel #2
0
    std::size_t set_thread_data(thread_id_type id, std::size_t d, error_code& ec)
    {
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
        if (NULL == app)
        {
            HPX_THROWS_IF(ec, invalid_status,
                "hpx::threads::set_thread_data",
                "global applier object is not accessible");
            return 0;
        }

        if (&ec != &throws)
            ec = make_success_code();

        return app->get_thread_manager().set_thread_data(id, d, ec);
    }
Beispiel #3
0
    util::backtrace const* get_thread_backtrace(thread_id_type id, error_code& ec)
    {
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
        if (NULL == app)
        {
            HPX_THROWS_IF(ec, invalid_status,
                "hpx::threads::get_thread_backtrace",
                "global applier object is not accessible");
            return NULL;
        }

        if (&ec != &throws)
            ec = make_success_code();

        return app->get_thread_manager().get_backtrace(id);
    }
Beispiel #4
0
        counter_status install(
            HPX_STD_FUNCTION<create_counter_func> const& create_counter,
            HPX_STD_FUNCTION<discover_counters_func> const& discover_counters,
            error_code& ec = throws)
        {
            if (status_invalid_data != status_) {
                HPX_THROWS_IF(ec, hpx::invalid_status,
                    "manage_counter_type::install",
                    "generic counter type " + info_.fullname_ +
                    " has been already installed.");
                return status_invalid_data;
            }

            return status_ = add_counter_type(
                info_, create_counter, discover_counters, ec);
        }
 void decode_compact_distribution(hwloc_topology& t,
     std::vector<mask_type>& affinities, error_code& ec)
 {
     std::size_t num_threads = affinities.size();
     for(std::size_t i = 0; i != num_threads; ++i)
     {
         if (any(affinities[i]))
         {
             HPX_THROWS_IF(ec, bad_parameter, "decode_compact_distribution",
                 boost::str(boost::format("affinity mask for thread %1% has "
                     "already been set") % i));
             return;
         }
         affinities[i] = t.init_thread_affinity_mask(i);
     }
 }
Beispiel #6
0
    threads::thread_state_ex_enum suspend(
        boost::posix_time::time_duration const& after_duration,
        char const* description, error_code& ec)
    {
        // handle interruption, if needed
        this_thread::interruption_point();

        // schedule a thread waking us up after_duration
        threads::thread_self& self = threads::get_self();
        threads::thread_id_type id = self.get_thread_id();

        threads::set_thread_state(id,
            after_duration, threads::pending, threads::wait_signaled,
            threads::thread_priority_critical, ec);
        if (ec) return threads::wait_unknown;

        // let the thread manager do other things while waiting
        threads::thread_state_ex_enum statex = threads::wait_unknown;
        {
            // verify that there are no more registered locks for this OS-thread
            util::verify_no_locks();

            // suspend the HPX-thread
            detail::reset_lco_description desc(id, description, ec);

#if HPX_THREAD_MAINTAIN_BACKTRACE_ON_SUSPENSION
            detail::reset_backtrace bt(id, ec);
#endif
            statex = self.yield(threads::suspended);
        }

        // handle interrupt and abort
        this_thread::interruption_point();
        if (statex == threads::wait_abort) {
            hpx::util::osstream strm;
            strm << "thread(" << id << ", "
                  << threads::get_thread_description(id)
                  << ") aborted (yield returned wait_abort)";
            HPX_THROWS_IF(ec, yield_aborted, description,
                hpx::util::osstream_get_string(strm));
        }

        if (&ec != &throws)
            ec = make_success_code();

        return statex;
    }
Beispiel #7
0
    threads::thread_id_type register_thread_plain(
        threads::thread_init_data& data, threads::thread_state_enum state,
        bool run_now, error_code& ec)
    {
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
        if (NULL == app)
        {
            HPX_THROWS_IF(ec, invalid_status,
                "hpx::applier::register_thread_plain",
                "global applier object is not accessible");
            return threads::invalid_thread_id;
        }

        threads::thread_id_type id = threads::invalid_thread_id;
        app->get_thread_manager().register_thread(data, id, state, run_now, ec);
        return id;
    }
Beispiel #8
0
    parcelset::endpoints_type request::get_endpoints(
        error_code& ec
        ) const
    { // {{{
        switch (data->which())
        {
            case request_data::subtype_locality_count:
                return data->get_data<request_data::subtype_locality_count, 0>(ec);

            default: {
                HPX_THROWS_IF(ec, bad_parameter,
                    "request::get_endpoints",
                    "invalid operation for request type");
                return parcelset::endpoints_type();
            }
        }
    } // }}}
Beispiel #9
0
    char const* set_thread_lco_description(thread_id_type const& id,
        char const* desc, error_code& ec)
    {
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
        if (NULL == app)
        {
            HPX_THROWS_IF(ec, invalid_status,
                "hpx::threads::set_thread_lco_description",
                "global applier object is not accessible");
            return NULL;
        }

        if (&ec != &throws)
            ec = make_success_code();

        return app->get_thread_manager().set_lco_description(id, desc);
    }
Beispiel #10
0
// Stop the executor identified with the given cookie
void resource_manager::stop_executor(std::size_t cookie, error_code& ec)
{
    std::lock_guard<mutex_type> l(mtx_);
    proxies_map_type::iterator it = proxies_.find(cookie);
    if (it == proxies_.end()) {
        HPX_THROWS_IF(ec, bad_parameter, "resource_manager::detach",
                      "the given cookie is not known to the resource manager");
        return;
    }

    // inform executor to give up virtual cores
    proxy_data& p = (*it).second;
    for (coreids_type coreids : p.core_ids_)
    {
        p.proxy_->remove_processing_unit(coreids.second, ec);
    }
}
Beispiel #11
0
    /// The function \a suspend will return control to the thread manager
    /// (suspends the current thread). It sets the new state of this thread
    /// to the thread state passed as the parameter.
    ///
    /// If the suspension was aborted, this function will throw a
    /// \a yield_aborted exception.
    threads::thread_state_ex_enum suspend(threads::thread_state_enum state,
        char const* description, error_code& ec)
    {
        // handle interruption, if needed
        this_thread::interruption_point();

        // let the thread manager do other things while waiting
        threads::thread_self& self = threads::get_self();
        threads::thread_state_ex_enum statex = threads::wait_unknown;
        {
            // verify that there are no more registered locks for this OS-thread
#if HPX_HAVE_VERIFY_LOCKS
            util::verify_no_locks();
#endif
#if HPX_THREAD_MAINTAIN_DESCRIPTION
            threads::thread_id_type id = self.get_thread_id();
            detail::reset_lco_description desc(id, description, ec);
#endif
#if HPX_THREAD_MAINTAIN_BACKTRACE_ON_SUSPENSION
            detail::reset_backtrace bt(id, ec);
#endif

            // suspend the HPX-thread
            statex = self.yield(state);
        }

        // handle interruption, if needed
        this_thread::interruption_point();

        // handle interrupt and abort
        if (statex == threads::wait_abort) {
            threads::thread_id_type id = self.get_thread_id();
            hpx::util::osstream strm;
            strm << "thread(" << id << ", "
                  << threads::get_thread_description(id)
                  << ") aborted (yield returned wait_abort)";
            HPX_THROWS_IF(ec, yield_aborted, description,
                hpx::util::osstream_get_string(strm));
        }

        if (&ec != &throws)
            ec = make_success_code();

        return statex;
    }
Beispiel #12
0
    void hwloc_topology::set_thread_affinity_mask(
        mask_type mask
      , error_code& ec
        ) const
    { // {{{
        hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();

        for (std::size_t i = 0; i < sizeof(std::size_t) * CHAR_BIT; ++i)
        {
            if (mask & (static_cast<std::size_t>(1) << i))
            {
                hwloc_bitmap_set(cpuset, static_cast<unsigned int>(i));
            }
        }

        {
            scoped_lock lk(topo_mtx);
            if (hwloc_set_cpubind(topo, cpuset,
                  HWLOC_CPUBIND_STRICT | HWLOC_CPUBIND_THREAD))
            {
                // Strict binding not supported or failed, try weak binding.
                if (hwloc_set_cpubind(topo, cpuset, HWLOC_CPUBIND_THREAD))
                {
                    hwloc_bitmap_free(cpuset);

                    HPX_THROWS_IF(ec, kernel_error
                      , "hpx::threads::hwloc_topology::set_thread_affinity_mask"
                      , boost::str(boost::format(
                            "failed to set thread %x affinity mask")
                            % mask));

                    if (ec)
                        return;
                }
            }
        }
#if defined(__linux) || defined(linux) || defined(__linux__) || defined(__FreeBSD__)
        sleep(0);   // Allow the OS to pick up the change.
#endif

        hwloc_bitmap_free(cpuset);

        if (&ec != &throws)
            ec = make_success_code();
    } // }}}
Beispiel #13
0
    void set_thread_affinity_mask(
        boost::thread& thrd
      , mask_type mask
      , error_code& ec = throws
        ) const
    { // {{{
        if (!SetThreadAffinityMask(thrd.native_handle(), DWORD_PTR(mask)))
        {
            HPX_THROWS_IF(ec, kernel_error
              , "hpx::threads::windows_topology::set_thread_affinity_mask"
              , boost::str(boost::format(
                    "failed to set thread %1% affinity mask")
                    % mask));
        }

        else if (&ec != &throws)
            ec = make_success_code();
    } // }}}
Beispiel #14
0
    thread_state set_thread_state(thread_id_type id, thread_state_enum state,
        thread_state_ex_enum stateex, thread_priority priority, error_code& ec)
    {
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
        if (NULL == app)
        {
            HPX_THROWS_IF(ec, invalid_status,
                "hpx::threads::set_thread_state",
                "global applier object is not accessible");
            return thread_state(unknown);
        }

        if (&ec != &throws)
            ec = make_success_code();

        return app->get_thread_manager().set_state(id, state, stateex,
            priority, ec);
    }
    // Return the requested policy element
    std::size_t generic_thread_pool_executor::get_policy_element(
        threads::detail::executor_parameter p, error_code& ec) const
    {
        switch(p) {
        case threads::detail::min_concurrency:
        case threads::detail::max_concurrency:
        case threads::detail::current_concurrency:
            return hpx::get_os_thread_count();

        default:
            break;
        }

        HPX_THROWS_IF(ec, bad_parameter,
            "thread_pool_executor::get_policy_element",
            "requested value of invalid policy element");
        return std::size_t(-1);
    }
Beispiel #16
0
naming::gid_type get_next_id(
    std::size_t count
  , error_code& ec
    )
{
    if (get_runtime_ptr() == 0)
    {
        HPX_THROWS_IF(ec, invalid_status,
            "get_next_id", "the runtime system has not been started yet.");
        return naming::invalid_gid;
    }

    naming::resolver_client& agas_ = naming::get_agas_client();
    naming::gid_type lower_bound, upper_bound;
    agas_.get_id_range(count, lower_bound, upper_bound, ec);
    if (ec) return naming::invalid_gid;

    return lower_bound;
}
Beispiel #17
0
    thread_id_type set_thread_state(thread_id_type const& id,
        boost::posix_time::time_duration const& after, thread_state_enum state,
        thread_state_ex_enum stateex, thread_priority priority, error_code& ec)
    {
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
        if (NULL == app)
        {
            HPX_THROWS_IF(ec, invalid_status,
                "hpx::threads::set_thread_state",
                "global applier object is not accessible");
            return invalid_thread_id;
        }

        if (&ec != &throws)
            ec = make_success_code();

        return app->get_thread_manager().set_state(after, id, state,
            stateex, priority, ec);
    }
response component_namespace::bind_name(
    request const& req
  , error_code& ec
    )
{ // {{{ bind_name implementation
    // parameters
    std::string key = req.get_name();

    std::unique_lock<mutex_type> l(mutex_);

    component_id_table_type::left_map::iterator it = component_ids_.left.find(key)
                                    , end = component_ids_.left.end();

    // If the name is not in the table, register it (this is only done so
    // we can implement a backwards compatible get_component_id).
    if (it == end)
    {
        if (HPX_UNLIKELY(!util::insert_checked(component_ids_.left.insert(
                std::make_pair(key, type_counter)), it)))
        {
            l.unlock();

            HPX_THROWS_IF(ec, lock_error
              , "component_namespace::bind_name"
              , "component id table insertion failed due to a locking "
                "error or memory corruption");
            return response();
        }

        // If the insertion succeeded, we need to increment the type
        // counter.
        ++type_counter;
    }

    LAGAS_(info) << (boost::format(
        "component_namespace::bind_name, key(%1%), ctype(%2%)")
        % key % it->second);

    if (&ec != &throws)
        ec = make_success_code();

    return response(component_ns_bind_name, it->second);
} // }}}
    void decode_balanced_distribution(hwloc_topology& t,
        std::vector<mask_type>& affinities,
        std::size_t used_cores, std::size_t max_cores,
        std::vector<std::size_t>& num_pus, error_code& ec)
    {
        std::size_t num_threads = affinities.size();
        std::size_t num_cores = (std::min)(max_cores, t.get_number_of_cores());

        std::vector<std::size_t> num_pus_cores(num_cores, 0);
        num_pus.resize(num_threads);
        // At first, calculate the number of used pus per core.
        // This needs to be done to make sure that we occupy all the available cores
        for (std::size_t num_thread = 0; num_thread != num_threads; /**/)
        {
            for(std::size_t num_core = 0; num_core != num_cores; ++num_core)
            {
                num_pus_cores[num_core]++;
                if(++num_thread == num_threads)
                    break;
            }
        }

        // Iterate over the cores and assigned pus per core. this additional loop
        // is needed so that we have consecutive worker thread numbers
        std::size_t num_thread = 0;
        for(std::size_t num_core = 0; num_core != num_cores; ++num_core)
        {
            for(std::size_t num_pu = 0; num_pu != num_pus_cores[num_core]; ++num_pu)
            {
                if (any(affinities[num_thread]))
                {
                    HPX_THROWS_IF(ec, bad_parameter, "decode_balanced_distribution",
                        boost::str(boost::format("affinity mask for thread %1% has "
                            "already been set") % num_thread));
                    return;
                }
                num_pus[num_thread] = t.get_pu_number(num_core + used_cores, num_pu);
                affinities[num_thread] = t.init_thread_affinity_mask(
                    num_core + used_cores, num_pu);
                ++num_thread;
            }
        }
    }
Beispiel #20
0
// Detach the executor identified with the given cookie
void resource_manager::detach(std::size_t cookie, error_code& ec)
{
    std::lock_guard<mutex_type> l(mtx_);
    proxies_map_type::iterator it = proxies_.find(cookie);
    if (it == proxies_.end()) {
        HPX_THROWS_IF(ec, bad_parameter, "resource_manager::detach",
                      "the given cookie is not known to the resource manager");
        return;
    }

    // adjust resource usage count
    proxy_data& p = (*it).second;
    for (coreids_type coreids : p.core_ids_)
    {
        HPX_ASSERT(punits_[coreids.first].use_count_ != 0);
        --punits_[coreids.first].use_count_;
    }

    proxies_.erase(cookie);
}
Beispiel #21
0
    boost::uint64_t request::get_count(
        error_code& ec
        ) const
    { // {{{
        switch (data->which())
        {
            case request_data::subtype_gid_count:
                return data->get_data<request_data::subtype_gid_count, 1>(ec);

            case request_data::subtype_locality_count:
                return data->get_data<request_data::subtype_locality_count, 1>(ec);

            default: {
                HPX_THROWS_IF(ec, bad_parameter,
                    "request::get_count",
                    "invalid operation for request type");
                return 0;
            }
        }
    } // }}}
Beispiel #22
0
    std::size_t get_numa_node_number(
        std::size_t num_thread
      , error_code& ec = throws
        ) const
    { // {{{
        if (num_thread < numa_node_numbers_.size())
        {
            if (&ec != &throws)
                ec = make_success_code();

            return numa_node_numbers_[num_thread];
        }

        HPX_THROWS_IF(ec, bad_parameter
          , "hpx::threads::windows_topology::get_numa_node_number"
          , boost::str(boost::format(
                "thread number %1% is out of range")
                % num_thread));
        return std::size_t(-1);
    } // }}}
Beispiel #23
0
        std::string regex_from_pattern(std::string const& pattern, error_code& ec)
        {
            std::string result;
            std::string::const_iterator end = pattern.end();
            for (std::string::const_iterator it = pattern.begin(); it != end; ++it)
            {
                char c = *it;
                switch (c) {
                case '*':
                    result.append(".*");
                    break;

                case '?':
                    result.append(1, '.');
                    break;

                case '[':
                    {
                        std::string r = regex_from_character_set(it, end, ec);
                        if (ec) return "";
                        result.append(r);
                    }
                    break;

                case '\\':
                    if (++it == end) {
                        HPX_THROWS_IF(ec, bad_parameter,
                            "regex_from_pattern",
                            "Invalid escape sequence at: " + pattern);
                        return "";
                    }
                    result.append(1, *it);
                    break;

                default:
                    result.append(1, c);
                    break;
                }
            }
            return result;
        }
    std::vector<mask_info>
    extract_socket_or_numanode_masks(hwloc_topology const& t,
        spec_type const& s, error_code& ec)
    {
        switch (s.type_)
        {
        case spec_type::socket:
            // requested top level is a socket
            {
                std::size_t num_sockets = t.get_number_of_sockets();
                return extract_socket_masks(
                    t, extract_bounds(s, num_sockets, ec));
            }

        case spec_type::numanode:
            // requested top level is a NUMA node
            {
                std::size_t num_numanodes = t.get_number_of_numa_nodes();
                return extract_numanode_masks(
                    t, extract_bounds(s, num_numanodes, ec));
            }

        case spec_type::unknown:
            {
                std::vector<mask_info> masks;
                masks.push_back(util::make_tuple(
                    std::size_t(-1), extract_machine_mask(t, ec)
                ));
                return masks;
            }

        default:
            HPX_THROWS_IF(ec, bad_parameter, "extract_socket_or_numanode_mask",
                boost::str(boost::format(
                    "unexpected specification type %s"
                ) % spec_type::type_name(s.type_)));
            break;
        }

        return std::vector<mask_info>();
    }
Beispiel #25
0
    void register_work_plain(
        threads::thread_function_type && func,
        char const* desc, naming::address::address_type lva,
        threads::thread_state_enum state, threads::thread_priority priority,
        std::size_t os_thread, threads::thread_stacksize stacksize,
        error_code& ec)
    {
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
        if (NULL == app)
        {
            HPX_THROWS_IF(ec, invalid_status,
                "hpx::applier::register_work_plain",
                "global applier object is not accessible");
            return;
        }

        threads::thread_init_data data(std::move(func),
            desc ? desc : "<unknown>", lva, priority, os_thread,
            threads::get_stack_size(stacksize));
        app->get_thread_manager().register_work(data, state, ec);
    }
Beispiel #26
0
/// \brief Create a full name of a counter from the contents of the given
///        \a counter_path_elements instance.
counter_status get_counter_type_name(counter_type_path_elements const& path,
                                     std::string& result, error_code& ec)
{
    if (path.objectname_.empty()) {
        HPX_THROWS_IF(ec, bad_parameter, "get_counter_type_name",
                      "empty counter object name");
        return status_invalid_data;
    }

    result = "/";
    result += path.objectname_;

    if (!path.countername_.empty()) {
        result += "/";
        result += path.countername_;
    }

    if (&ec != &throws)
        ec = make_success_code();
    return status_valid_data;
}
Beispiel #27
0
    void register_non_suspendable_work(
        util::unique_function_nonser<void(threads::thread_state_ex_enum)> && func,
        char const* desc, threads::thread_state_enum state,
        threads::thread_priority priority, std::size_t os_thread,
        error_code& ec)
    {
        hpx::applier::applier* app = hpx::applier::get_applier_ptr();
        if (NULL == app)
        {
            HPX_THROWS_IF(ec, invalid_status,
                "hpx::applier::register_work",
                "global applier object is not accessible");
            return;
        }

        threads::thread_init_data data(
            util::bind(util::one_shot(&thread_function), std::move(func)),
            desc ? desc : "<unknown>", 0, priority, os_thread,
            threads::get_stack_size(threads::thread_stacksize_nostack));
        app->get_thread_manager().register_work(data, state, ec);
    }
Beispiel #28
0
    boost::uint32_t request::get_locality_id(
        error_code& ec
        ) const
    {
        switch (data->which())
        {
            case request_data::subtype_gid_gva_prefix:
                return naming::get_locality_id_from_gid(
                    data->get_data<request_data::subtype_gid_gva_prefix, 2>(ec));

            case request_data::subtype_name_prefix:
                return data->get_data<request_data::subtype_name_prefix, 1>(ec);

            default: {
                HPX_THROWS_IF(ec, bad_parameter,
                    "request::get_locality_id",
                    "invalid operation for request type");
                return naming::invalid_locality_id;
            }
        }
    }
Beispiel #29
0
    boost::int64_t request::get_credit(
        error_code& ec
        ) const
    {
        switch (data->which())
        {
            case request_data::subtype_gid_gid_credit:
                return data->get_data<request_data::subtype_gid_gid_credit, 2>(ec);

            case request_data::subtype_gid_count:
                return static_cast<boost::int64_t>(
                    data->get_data<request_data::subtype_gid_count, 1>(ec));

            default: {
                HPX_THROWS_IF(ec, bad_parameter,
                    "request::get_credit",
                    "invalid operation for request type");
                return 0;
            }
        }
    }
Beispiel #30
0
        naming::gid_type retrieve_agas_counter(std::string const& name,
            naming::id_type const& agas_id, error_code& ec)
        {
            naming::gid_type id;

            //  get action code from counter type
            agas::namespace_action_code service_code =
                agas::detail::retrieve_action_service_code(name, ec);
            if (agas::invalid_request == service_code) return id;

            // compose request
            agas::request req(service_code, name);
            agas::response rep;

            switch (service_code) {
            case agas::component_ns_statistics_counter:
                rep = agas::stubs::component_namespace::service(
                    agas_id, req, threads::thread_priority_default, ec);
                break;
            case agas::primary_ns_statistics_counter:
                rep = agas::stubs::primary_namespace::service(
                    agas_id, req, threads::thread_priority_default, ec);
                break;
            case agas::symbol_ns_statistics_counter:
                rep = agas::stubs::symbol_namespace::service(
                    agas_id, req, threads::thread_priority_default, ec);
                break;
            case agas::locality_ns_statistics_counter:
                rep = agas::stubs::locality_namespace::service(
                    agas_id, req, threads::thread_priority_default, ec);
                break;
            default:
                HPX_THROWS_IF(ec, bad_parameter, "retrieve_statistics_counter",
                    "unknown counter agas counter name: " + name);
                break;
            }
            if (!ec)
                id = rep.get_statistics_counter();
            return id;
        }