/// Default discoverer function for performance counters; to be registered /// with the counter types. It is suitable to be used for all counters /// following the naming scheme: /// /// /<objectname>{locality#<locality_id>/total}/<instancename> /// bool locality_counter_discoverer(counter_info const& info, HPX_STD_FUNCTION<discover_counter_func> const& f, error_code& ec) { performance_counters::counter_info i = info; // compose the counter name templates performance_counters::counter_path_elements p; performance_counters::counter_status status = get_counter_path_elements(info.fullname_, p, ec); if (!status_is_valid(status)) return false; p.parentinstancename_ = "locality#<*>"; p.parentinstanceindex_ = -1; p.instancename_ = "total"; p.instanceindex_ = -1; status = get_counter_name(p, i.fullname_, ec); if (!status_is_valid(status) || !f(i, ec) || ec) return false; // boost::uint32_t last_locality = get_num_localities(); // for (boost::uint32_t l = 0; l < last_locality; ++l) // { // p.parentinstanceindex_ = static_cast<boost::int32_t>(l); // status = get_counter_name(p, i.fullname_, ec); // if (!status_is_valid(status) || !f(i, ec) || ec) // return false; // } if (&ec != &throws) ec = make_success_code(); return true; }
/// Creation function for uptime counters. naming::gid_type uptime_counter_creator(counter_info const& info, error_code& ec) { switch (info.type_) { case counter_elapsed_time: { // verify the validity of the counter instance name counter_path_elements paths; get_counter_path_elements(info.fullname_, paths, ec); if (ec) return naming::invalid_gid; // allowed counter names: /runtime(locality#%d/*)/uptime if (paths.parentinstance_is_basename_) { HPX_THROWS_IF(ec, bad_parameter, "uptime_counter_creator", "invalid counter instance parent name: " + paths.parentinstancename_); return naming::invalid_gid; } // create the counter return create_counter(info, ec); } default: HPX_THROWS_IF(ec, bad_parameter, "uptime_counter_creator", "invalid counter type requested"); return naming::invalid_gid; } }
/// Default discoverer function for performance counters; to be registered /// with the counter types. It is suitable to be used for all counters /// following the naming scheme: /// /// /<objectname>(<objectinstance>/total)/<instancename> /// bool agas_counter_discoverer(counter_info const& info, HPX_STD_FUNCTION<discover_counter_func> const& f, error_code& ec) { performance_counters::counter_info i_ = info; // compose the counter names performance_counters::counter_path_elements p; performance_counters::counter_status status = get_counter_path_elements(info.fullname_, p, ec); if (!status_is_valid(status)) return false; p.parentinstancename_ = "agas"; p.parentinstanceindex_ = -1; p.instanceindex_ = -1; // list all counter related to agas for (std::size_t i = 0; i < sizeof(agas::detail::counter_services)/sizeof(agas::detail::counter_services[0]); ++i) { p.instancename_ = agas::detail::counter_services[i].name_; status = get_counter_name(p, i_.fullname_, ec); if (!status_is_valid(status) || !f(i_, ec) || ec) return false; } return true; }
/////////////////////////////////////////////////////////////////////////// /// Creation function for raw AGAS counters. This function checks the /// validity of the supplied counter name, it has to follow the scheme: /// /// /agas(<objectinstance>/total)/<instancename> /// naming::gid_type agas_raw_counter_creator( counter_info const& info, error_code& ec, char const* const service_name) { // verify the validity of the counter instance name counter_path_elements paths; get_counter_path_elements(info.fullname_, paths, ec); if (ec) return naming::invalid_gid; if (paths.objectname_ != "agas") { HPX_THROWS_IF(ec, bad_parameter, "agas_raw_counter_creator", "unknown performance counter (unrelated to AGAS)"); return naming::invalid_gid; } if (paths.parentinstance_is_basename_) { HPX_THROWS_IF(ec, bad_parameter, "agas_raw_counter_creator", "invalid counter instance parent name: " + paths.parentinstancename_); return naming::invalid_gid; } // counter instance name: <agas_instance_name>/total // for instance: locality#0/total if (paths.instancename_ == "total" && paths.instanceindex_ == -1) { // find the referenced AGAS instance and dispatch the request there std::string service(agas::service_name); service += paths.parentinstancename_; if (-1 == paths.parentinstanceindex_) { HPX_THROWS_IF(ec, bad_parameter, "agas_raw_counter_creator", "invalid parent instance index: -1"); return naming::invalid_gid; } service += "#"; service += boost::lexical_cast<std::string>(paths.parentinstanceindex_); service += "/"; service += service_name; naming::id_type id; bool result = agas::resolve_name_sync(service, id, ec); if (!result) { HPX_THROWS_IF(ec, not_implemented, "agas_raw_counter_creator", "invalid counter name: " + remove_counter_prefix(info.fullname_)); return naming::invalid_gid; } return detail::retrieve_agas_counter(info.fullname_, id, ec); } HPX_THROWS_IF(ec, not_implemented, "agas_raw_counter_creator", "invalid counter type name: " + paths.instancename_); return naming::invalid_gid; }
/// Creation function for aggregating performance counters to be registered /// with the counter types. naming::gid_type statistics_counter_creator(counter_info const& info, error_code& ec) { switch (info.type_) { case counter_aggregating: { counter_path_elements paths; get_counter_path_elements(info.fullname_, paths, ec); if (ec) return naming::invalid_gid; if (!paths.parentinstance_is_basename_) { HPX_THROWS_IF(ec, bad_parameter, "statistics_counter_creator", "invalid aggregate counter " "name (instance name must be valid base counter name)"); return naming::invalid_gid; } std::string base_name; get_counter_name(paths.parentinstancename_, base_name, ec); if (ec) return naming::invalid_gid; std::vector<boost::int64_t> parameters; if (!paths.parameters_.empty()) { // try to interpret the additional parameter as interval // time (ms) namespace qi = boost::spirit::qi; if (!qi::parse(paths.parameters_.begin(), paths.parameters_.end(), qi::int_ % ',', parameters)) { HPX_THROWS_IF(ec, bad_parameter, "statistics_counter_creator", "invalid parameter specification for counter: " + paths.parameters_); return naming::invalid_gid; } } else { parameters.push_back(1000); // sample interval parameters.push_back(10); // rolling window } return create_statistics_counter(info, base_name, parameters, ec); } break; default: HPX_THROWS_IF(ec, bad_parameter, "statistics_counter_creator", "invalid counter type requested"); return naming::invalid_gid; } }
/////////////////////////////////////////////////////////////////////////// /// Creation function for raw AGAS counters. This function checks the /// validity of the supplied counter name, it has to follow the scheme: /// /// /agas(<objectinstance>/total)/<instancename> /// naming::gid_type agas_raw_counter_creator( counter_info const& info, error_code& ec, char const* const service_name) { // verify the validity of the counter instance name counter_path_elements paths; get_counter_path_elements(info.fullname_, paths, ec); if (ec) return naming::invalid_gid; if (paths.objectname_ != "agas") { HPX_THROWS_IF(ec, bad_parameter, "agas_raw_counter_creator", "unknown performance counter (unrelated to AGAS)"); return naming::invalid_gid; } if (paths.parentinstance_is_basename_) { HPX_THROWS_IF(ec, bad_parameter, "agas_raw_counter_creator", "invalid counter instance parent name: " + paths.parentinstancename_); return naming::invalid_gid; } if (service_name == paths.parentinstancename_ && paths.parentinstanceindex_ == -1) { // counter instance name: /<agas_service_name>/<agas_instance_name>/total // for instance: /component_namespace/root/total std::string::size_type p = paths.instancename_.find("total"); if (p == paths.instancename_.size() - 5 && paths.instanceindex_ == -1) { // find the referenced AGAS instance and dispatch the request there std::string agas_instance; performance_counters::get_counter_instance_name(paths, agas_instance, ec); if (ec) return naming::invalid_gid; naming::id_type id; bool result = agas::resolve_name( agas_instance.substr(0, agas_instance.size() - 6), id, ec); if (!result) { HPX_THROWS_IF(ec, not_implemented, "agas_raw_counter_creator", "invalid counter instance name: " + agas_instance); return naming::invalid_gid; } return detail::retrieve_statistics_counter(info.fullname_, id, ec); } } HPX_THROWS_IF(ec, not_implemented, "agas_raw_counter_creator", "invalid counter type name: " + paths.instancename_); return naming::invalid_gid; }
/// Default discoverer function for performance counters; to be registered /// with the counter types. It is suitable to be used for all counters /// following the naming scheme: /// /// /<objectname>{locality#<locality_id>/thread#<threadnum>}/<instancename> /// bool locality_thread_counter_discoverer(counter_info const& info, HPX_STD_FUNCTION<discover_counter_func> const& f, discover_counters_mode mode, error_code& ec) { performance_counters::counter_info i = info; // compose the counter name templates performance_counters::counter_path_elements p; performance_counters::counter_status status = get_counter_path_elements(info.fullname_, p, ec); if (!status_is_valid(status)) return false; if (mode == discover_counters_minimal || p.parentinstancename_.empty() || p.instancename_.empty()) { if (p.parentinstancename_.empty()) { p.parentinstancename_ = "locality#*"; p.parentinstanceindex_ = -1; } if (p.instancename_.empty()) { p.instancename_ = "total"; p.instanceindex_ = -1; } status = get_counter_name(p, i.fullname_, ec); if (!status_is_valid(status) || !f(i, ec) || ec) return false; p.instancename_ = "worker-thread#*"; p.instanceindex_ = -1; status = get_counter_name(p, i.fullname_, ec); if (!status_is_valid(status) || !f(i, ec) || ec) return false; } else if (!f(i, ec) || ec) { return false; } if (&ec != &throws) ec = make_success_code(); return true; }
// create an arbitrary counter on this locality naming::gid_type create_counter_local(counter_info const& info) { // find create function for given counter error_code ec; create_counter_func f; get_runtime().get_counter_registry().get_counter_create_function( info, f, ec); if (ec) { HPX_THROW_EXCEPTION(bad_parameter, "create_counter_local", "no create function for performance counter found: " + remove_counter_prefix(info.fullname_) + " (" + ec.get_message() + ")"); return naming::invalid_gid; } counter_path_elements paths; get_counter_path_elements(info.fullname_, paths, ec); if (ec) return hpx::naming::invalid_gid; if (paths.parentinstancename_ == "locality" && paths.parentinstanceindex_ != static_cast<boost::int64_t>(hpx::get_locality_id())) { HPX_THROW_EXCEPTION(bad_parameter, "create_counter_local", "attempt to create counter on wrong locality (" + ec.get_message() + ")"); return hpx::naming::invalid_gid; } // attempt to create the new counter instance naming::gid_type gid = f(info, ec); if (ec) { HPX_THROW_EXCEPTION(bad_parameter, "create_counter_local", "couldn't create performance counter: " + remove_counter_prefix(info.fullname_) + " (" + ec.get_message() + ")"); return naming::invalid_gid; } return gid; }
/////////////////////////////////////////////////////////////////////////// /// Creation function for raw counters. The passed function is encapsulating /// the actual value to monitor. This function checks the validity of the /// supplied counter name, it has to follow the scheme: /// /// /<objectname>{locality#<locality_id>/total}/<instancename> /// naming::gid_type locality_raw_counter_creator(counter_info const& info, HPX_STD_FUNCTION<boost::int64_t()> const& f, error_code& ec) { // verify the validity of the counter instance name counter_path_elements paths; get_counter_path_elements(info.fullname_, paths, ec); if (ec) return naming::invalid_gid; if (paths.parentinstance_is_basename_) { HPX_THROWS_IF(ec, bad_parameter, "locality_raw_counter_creator", "invalid counter instance parent name: " + paths.parentinstancename_); return naming::invalid_gid; } if (paths.instancename_ == "total" && paths.instanceindex_ == -1) return detail::create_raw_counter(info, f, ec); // overall counter HPX_THROWS_IF(ec, bad_parameter, "locality_raw_counter_creator", "invalid counter instance name: " + paths.instancename_); return naming::invalid_gid; }
/// Creation function for aggregating performance counters to be registered /// with the counter types. naming::gid_type arithmetics_counter_extended_creator( counter_info const& info, error_code& ec) { switch (info.type_) { case counter_aggregating: { counter_path_elements paths; get_counter_path_elements(info.fullname_, paths, ec); if (ec) return naming::invalid_gid; if (!paths.parameters_.empty()) { // try to interpret the additional parameter as a list of // two performance counter names std::vector<std::string> names; boost::split(names, paths.parameters_, boost::is_any_of(",")); if (names.empty()) { HPX_THROWS_IF(ec, bad_parameter, "arithmetics_counter_extended_creator", "the parameter specification for an arithmetic counter " "has to expand to at least one counter name: " + paths.parameters_); return naming::invalid_gid; } for (std::string const& name : names) { counter_path_elements paths; if (status_valid_data != get_counter_path_elements( name, paths, ec) || ec) { HPX_THROWS_IF(ec, bad_parameter, "arithmetics_counter_extended_creator", "the given (expanded) counter name is not " "a validly formed performance counter name: " + name); return naming::invalid_gid; } } return create_arithmetics_counter_extended(info, names, ec); } else { HPX_THROWS_IF(ec, bad_parameter, "arithmetics_counter_extended_creator", "the parameter specification for an arithmetic counter " "has to be a comma separated list of performance " "counter names, none is given: " + remove_counter_prefix(info.fullname_)); } } break; default: HPX_THROWS_IF(ec, bad_parameter, "arithmetics_counter_extended_creator", "invalid counter type requested"); break; } return naming::invalid_gid; }
/////////////////////////////////////////////////////////////////////////// /// Creation function for instance counter naming::gid_type component_instance_counter_creator( counter_info const& info, error_code& ec) { switch (info.type_) { case counter_raw: { counter_path_elements paths; get_counter_path_elements(info.fullname_, paths, ec); if (ec) return naming::invalid_gid; if (paths.parentinstance_is_basename_) { HPX_THROWS_IF(ec, bad_parameter, "component_instance_counter_creator", "invalid instance counter name (instance name must not " "be a valid base counter name)"); return naming::invalid_gid; } if (paths.parameters_.empty()) { std::stringstream strm; strm << "invalid instance counter parameter: must specify " "a component type\n" "known component types:\n"; components::enumerate_instance_counts( [&strm](components::component_type type) -> bool { strm << " " << agas::get_component_type_name(type) << "\n"; return true; }); HPX_THROWS_IF(ec, bad_parameter, "component_instance_counter_creator", strm.str()); return naming::invalid_gid; } // ask AGAS to resolve the component type components::component_type type = naming::get_agas_client().get_component_id(paths.parameters_); if (type == components::component_invalid) { HPX_THROWS_IF(ec, bad_parameter, "component_instance_counter_creator", "invalid component type as counter parameter: " + paths.parameters_); return naming::invalid_gid; } hpx::util::function_nonser<std::int64_t()> f = util::bind_front(&get_instance_count, type); return create_raw_counter(info, std::move(f), ec); } break; default: HPX_THROWS_IF(ec, bad_parameter, "component_instance_counter_creator", "invalid counter type requested"); return naming::invalid_gid; } }