summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-08-18 04:04:45 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-08-18 04:04:45 +0000
commit99e36d03aa715bf6bce0a471af09a4c0d887f147 (patch)
treedd72a84514306c5cc0c9025a1fb9e9e3976ced32
parent1d70a3df7d45fb302abf0a614d33d0436c2a5707 (diff)
parent3b739c8720db08d5b34e8a547a5b2f6305fe37b6 (diff)
downloadextras-android12-mainline-cellbroadcast-release.tar.gz
Change-Id: I7326e99447d6441a5d0344523170d43a180b4da1
-rw-r--r--profcollectd/libprofcollectd/bindings/libflags/Android.bp15
-rw-r--r--profcollectd/libprofcollectd/bindings/libflags/get_flags.cpp13
-rw-r--r--profcollectd/libprofcollectd/bindings/libflags/get_flags.hpp7
-rw-r--r--profcollectd/libprofcollectd/bindings/libflags/lib.rs37
-rw-r--r--profcollectd/libprofcollectd/config.rs4
-rw-r--r--profcollectd/libprofcollectd/report.rs11
-rw-r--r--profcollectd/libprofcollectd/service.rs31
-rw-r--r--simpleperf/test_util.cpp41
8 files changed, 90 insertions, 69 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 c3ab45cf..e8afb37f 100644
--- a/profcollectd/libprofcollectd/config.rs
+++ b/profcollectd/libprofcollectd/config.rs
@@ -29,6 +29,8 @@ use std::time::Duration;
const PROFCOLLECT_CONFIG_NAMESPACE: &str = "profcollect_native_boot";
const PROFCOLLECT_NODE_ID_PROPERTY: &str = "persist.profcollectd.node_id";
+pub const REPORT_RETENTION_SECS: u64 = 14 * 24 * 60 * 60; // 14 days.
+
lazy_static! {
pub static ref TRACE_OUTPUT_DIR: &'static Path = Path::new("/data/misc/profcollectd/trace/");
pub static ref PROFILE_OUTPUT_DIR: &'static Path = Path::new("/data/misc/profcollectd/output/");
@@ -105,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,
diff --git a/profcollectd/libprofcollectd/report.rs b/profcollectd/libprofcollectd/report.rs
index c37993b7..a67d500b 100644
--- a/profcollectd/libprofcollectd/report.rs
+++ b/profcollectd/libprofcollectd/report.rs
@@ -23,7 +23,7 @@ use std::fs::{self, File, Permissions};
use std::io::{Read, Write};
use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf};
-use std::time::SystemTime;
+use std::time::{Duration, SystemTime};
use uuid::v1::{Context, Timestamp};
use uuid::Uuid;
use zip::write::FileOptions;
@@ -82,3 +82,12 @@ fn get_report_filename(node_id: &MacAddr6) -> Result<String> {
let uuid = Uuid::new_v1(ts, &node_id.as_bytes())?;
Ok(uuid.to_string())
}
+
+/// Get report creation timestamp through its filename (version 1 UUID).
+pub fn get_report_ts(filename: &str) -> Result<SystemTime> {
+ let uuid_ts = Uuid::parse_str(filename)?
+ .to_timestamp()
+ .ok_or_else(|| anyhow!("filename is not a valid V1 UUID."))?
+ .to_unix();
+ Ok(SystemTime::UNIX_EPOCH + Duration::new(uuid_ts.0, uuid_ts.1))
+}
diff --git a/profcollectd/libprofcollectd/service.rs b/profcollectd/libprofcollectd/service.rs
index 0b9cca1e..04f30f89 100644
--- a/profcollectd/libprofcollectd/service.rs
+++ b/profcollectd/libprofcollectd/service.rs
@@ -21,16 +21,17 @@ use binder::public_api::Result as BinderResult;
use binder::Status;
use profcollectd_aidl_interface::aidl::com::android::server::profcollect::IProfCollectd::IProfCollectd;
use std::ffi::CString;
-use std::fs::{copy, create_dir, read_to_string, remove_dir_all, remove_file, write};
+use std::fs::{copy, create_dir, read_dir, read_to_string, remove_dir_all, remove_file, write};
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::{Mutex, MutexGuard};
+use std::time::Duration;
use crate::config::{
Config, BETTERBUG_CACHE_DIR_PREFIX, BETTERBUG_CACHE_DIR_SUFFIX, CONFIG_FILE,
- PROFILE_OUTPUT_DIR, REPORT_OUTPUT_DIR, TRACE_OUTPUT_DIR,
+ PROFILE_OUTPUT_DIR, REPORT_OUTPUT_DIR, REPORT_RETENTION_SECS, TRACE_OUTPUT_DIR,
};
-use crate::report::pack_report;
+use crate::report::{get_report_ts, pack_report};
use crate::scheduler::Scheduler;
fn err_to_binder_status(msg: Error) -> Status {
@@ -155,6 +156,30 @@ impl ProfcollectdBinderService {
write(*CONFIG_FILE, &new_config.to_string())?;
}
+ // Clear profile reports out of rentention period.
+ for report in read_dir(*REPORT_OUTPUT_DIR)? {
+ let report = report?.path();
+ let report_name = report
+ .file_stem()
+ .and_then(|f| f.to_str())
+ .ok_or_else(|| anyhow!("Malformed path {}", report.display()))?;
+ let report_ts = get_report_ts(report_name);
+ if let Err(e) = report_ts {
+ log::error!(
+ "Cannot decode creation timestamp for report {}, caused by {}, deleting",
+ report_name,
+ e
+ );
+ remove_file(report)?;
+ continue;
+ }
+ let report_age = report_ts.unwrap().elapsed()?;
+ if report_age > Duration::from_secs(REPORT_RETENTION_SECS) {
+ log::info!("Report {} past rentention period, deleting", report_name);
+ remove_file(report)?;
+ }
+ }
+
Ok(ProfcollectdBinderService {
lock: Mutex::new(Lock { scheduler: new_scheduler, config: new_config }),
})
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() {