From d09092fd6d2632e6e2787af06ad6fdb69099966c Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 22 Jul 2021 10:22:28 -0700 Subject: Migrate profcollectd's libflags bindings from bindgen to cxx. This should both simplify the code and fix some errors in the existing implementation. Bug: 182498247 Test: Build Change-Id: I2a5bcbcac407ba0bb41d4884b99fe8a55113ae38 (cherry picked from commit c8fb4177717b50c3c5789011e4ab795771a62102) --- .../libprofcollectd/bindings/libflags/Android.bp | 15 +++++---- .../bindings/libflags/get_flags.cpp | 13 +++----- .../bindings/libflags/get_flags.hpp | 7 ++-- .../libprofcollectd/bindings/libflags/lib.rs | 37 ++++++++++------------ profcollectd/libprofcollectd/config.rs | 2 +- 5 files changed, 36 insertions(+), 38 deletions(-) diff --git a/profcollectd/libprofcollectd/bindings/libflags/Android.bp b/profcollectd/libprofcollectd/bindings/libflags/Android.bp index 102a6c05..fb846678 100644 --- a/profcollectd/libprofcollectd/bindings/libflags/Android.bp +++ b/profcollectd/libprofcollectd/bindings/libflags/Android.bp @@ -26,20 +26,23 @@ package { cc_library_static { name: "libprofcollect_libflags", srcs: ["get_flags.cpp"], + generated_headers: ["cxx-bridge-header"], + generated_sources: ["libprofcollect_libflags_bridge_code"], } -rust_bindgen { - name: "libprofcollect_libflags_bindgen", - wrapper_src: "get_flags.hpp", - crate_name: "profcollect_libflags_bindgen", - source_stem: "bindings", +genrule { + name: "libprofcollect_libflags_bridge_code", + tools: ["cxxbridge"], + cmd: "$(location cxxbridge) $(in) >> $(out)", + srcs: ["lib.rs"], + out: ["libprofcollect_libflags_cxx_generated.cc"], } rust_library { name: "libprofcollect_libflags_rust", crate_name: "profcollect_libflags_rust", srcs: ["lib.rs"], - rlibs: ["libprofcollect_libflags_bindgen"], + rustlibs: ["libcxx"], static_libs: ["libprofcollect_libflags"], shared_libs: [ "libc++", diff --git a/profcollectd/libprofcollectd/bindings/libflags/get_flags.cpp b/profcollectd/libprofcollectd/bindings/libflags/get_flags.cpp index e5ce65a1..d8bab841 100644 --- a/profcollectd/libprofcollectd/bindings/libflags/get_flags.cpp +++ b/profcollectd/libprofcollectd/bindings/libflags/get_flags.cpp @@ -17,12 +17,9 @@ #include "../../../../../server_configurable_flags/libflags/include/server_configurable_flags/get_flags.h" #include "get_flags.hpp" -const char* GetServerConfigurableFlag(const char* experiment_category_name, - const char* experiment_flag_name, - const char* default_value) { - auto v = server_configurable_flags::GetServerConfigurableFlag( - std::string(experiment_category_name), - std::string(experiment_flag_name), - std::string(default_value)); - return strdup(v.c_str()); +rust::String GetServerConfigurableFlag(rust::Str experiment_category_name, + rust::Str experiment_flag_name, rust::Str default_value) { + return server_configurable_flags::GetServerConfigurableFlag(std::string(experiment_category_name), + std::string(experiment_flag_name), + std::string(default_value)); } diff --git a/profcollectd/libprofcollectd/bindings/libflags/get_flags.hpp b/profcollectd/libprofcollectd/bindings/libflags/get_flags.hpp index ab3be989..a42c52e8 100644 --- a/profcollectd/libprofcollectd/bindings/libflags/get_flags.hpp +++ b/profcollectd/libprofcollectd/bindings/libflags/get_flags.hpp @@ -14,5 +14,8 @@ * limitations under the License. */ -// C declaration for bindgen. -const char* GetServerConfigurableFlag(const char*, const char*, const char*); +#pragma once + +#include "rust/cxx.h" + +rust::String GetServerConfigurableFlag(rust::Str, rust::Str, rust::Str); diff --git a/profcollectd/libprofcollectd/bindings/libflags/lib.rs b/profcollectd/libprofcollectd/bindings/libflags/lib.rs index c8875cb1..c6435bbd 100644 --- a/profcollectd/libprofcollectd/bindings/libflags/lib.rs +++ b/profcollectd/libprofcollectd/bindings/libflags/lib.rs @@ -17,27 +17,22 @@ //! This module implements safe wrappers for GetServerConfigurableFlag method //! from libflags. -use std::ffi::{CStr, CString}; +pub use ffi::GetServerConfigurableFlag; -/// Use the category name and flag name registered in SettingsToPropertiesMapper.java -/// to query the experiment flag value. This method will return default_value if -/// querying fails. -/// Note that for flags from Settings.Global, experiment_category_name should -/// always be global_settings. -pub fn get_server_configurable_flag<'a>( - experiment_category_name: &str, - experiment_flag_name: &str, - default_value: &'a str, -) -> &'a str { - let experiment_category_name = CString::new(experiment_category_name).unwrap(); - let experiment_flag_name = CString::new(experiment_flag_name).unwrap(); - let default_value = CString::new(default_value).unwrap(); - unsafe { - let cstr = profcollect_libflags_bindgen::GetServerConfigurableFlag( - experiment_category_name.as_ptr(), - experiment_flag_name.as_ptr(), - default_value.as_ptr(), - ); - CStr::from_ptr(cstr).to_str().unwrap() +#[cxx::bridge] +mod ffi { + unsafe extern "C++" { + include!("get_flags.hpp"); + + /// Use the category name and flag name registered in SettingsToPropertiesMapper.java + /// to query the experiment flag value. This method will return default_value if + /// querying fails. + /// Note that for flags from Settings.Global, experiment_category_name should + /// always be global_settings. + fn GetServerConfigurableFlag( + experiment_category_name: &str, + experiment_flag_name: &str, + default_value: &str, + ) -> String; } } diff --git a/profcollectd/libprofcollectd/config.rs b/profcollectd/libprofcollectd/config.rs index 11098fe1..e8afb37f 100644 --- a/profcollectd/libprofcollectd/config.rs +++ b/profcollectd/libprofcollectd/config.rs @@ -107,7 +107,7 @@ where T::Err: Error + Send + Sync + 'static, { let default_value = default_value.to_string(); - let config = profcollect_libflags_rust::get_server_configurable_flag( + let config = profcollect_libflags_rust::GetServerConfigurableFlag( &PROFCOLLECT_CONFIG_NAMESPACE, &key, &default_value, -- cgit v1.2.3 From ee3097ce79889c5e0bbaec34cda8becebcc9f64f Mon Sep 17 00:00:00 2001 From: Yabin Cui Date: Thu, 22 Jul 2021 13:33:24 -0700 Subject: simpleperf: replace InCloudAndroid() with runtime check. On x86 and x86_64, it's likely to run on an emulator or vm without hardware perf counters. It's hard to enumerate them all. So check if hardware perf counters are available at runtime. Bug: 191277482 Test: run simpleperf_unit_test Change-Id: I38cc89bc7f81f8d6d6165a4b8f344c0660c10364 (cherry picked from commit 1f6f51aee77235b1fb374a917f0b46c9c09f0933) --- simpleperf/test_util.cpp | 41 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/simpleperf/test_util.cpp b/simpleperf/test_util.cpp index c2a21960..547eaf90 100644 --- a/simpleperf/test_util.cpp +++ b/simpleperf/test_util.cpp @@ -48,29 +48,6 @@ bool IsInNativeAbi() { return in_native_abi == 1; } -static bool InCloudAndroid() { -#if defined(__i386__) || defined(__x86_64__) -#if defined(__ANDROID__) - std::string prop_value = android::base::GetProperty("ro.build.flavor", ""); - if (android::base::StartsWith(prop_value, "cf_x86_phone") || - android::base::StartsWith(prop_value, "aosp_cf_x86_phone") || - android::base::StartsWith(prop_value, "cf_x86_64_phone") || - android::base::StartsWith(prop_value, "aosp_cf_x86_64_phone")) { - return true; - } - // aosp_x86* builds may also run on cloud Android. Detect it by checking - /// if cpu-cycles isn't supported. - if (android::base::StartsWith(prop_value, "aosp_x86")) { - const simpleperf::EventType* type = simpleperf::FindEventTypeByName("cpu-cycles", false); - CHECK(type != nullptr); - perf_event_attr attr = CreateDefaultPerfEventAttr(*type); - return !IsEventAttrSupported(attr, "cpu-cycles"); - } -#endif -#endif - return false; -} - #if defined(__arm__) // Check if we can get a non-zero instruction event count by monitoring current thread. static bool HasNonZeroInstructionEventCount() { @@ -96,18 +73,28 @@ static bool HasNonZeroInstructionEventCount() { #endif // defined(__arm__) bool HasHardwareCounter() { +#if defined(__linux__) static int has_hw_counter = -1; if (has_hw_counter == -1) { - // Cloud Android doesn't have hardware counters. - has_hw_counter = InCloudAndroid() ? 0 : 1; -#if defined(__arm__) + has_hw_counter = 1; +#if defined(__x86__) || defined(__x86_64__) + // On x86 and x86_64, it's likely to run on an emulator or vm without hardware perf counters. + // It's hard to enumerate them all. So check the support at runtime. + const simpleperf::EventType* type = simpleperf::FindEventTypeByName("cpu-cycles", false); + CHECK(type != nullptr); + perf_event_attr attr = CreateDefaultPerfEventAttr(*type); + has_hw_counter = IsEventAttrSupported(attr, "cpu-cycles") ? 1 : 0; +#elif defined(__arm__) // For arm32 devices, external non-invasive debug signal controls PMU counters. Once it is // disabled for security reason, we always get zero values for PMU counters. And we want to // skip hardware counter tests once we detect it. has_hw_counter &= HasNonZeroInstructionEventCount() ? 1 : 0; -#endif +#endif // defined(__arm__) } return has_hw_counter == 1; +#else // defined(__linux__) + return false; +#endif // defined(__linux__) } bool HasPmuCounter() { -- cgit v1.2.3