Merge "liblog: Speed up and extend the radio log redirect code"
diff --git a/base/Android.bp b/base/Android.bp
index 7b1dc8e..121da42 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -42,24 +42,36 @@
srcs: [
"errors_unix.cpp",
"properties.cpp",
+ "chrono_utils.cpp",
],
cppflags: ["-Wexit-time-destructors"],
sanitize: {
misc_undefined: ["integer"],
},
+
},
darwin: {
- srcs: ["errors_unix.cpp"],
+ srcs: [
+ "chrono_utils.cpp",
+ "errors_unix.cpp",
+ ],
cppflags: ["-Wexit-time-destructors"],
},
linux_bionic: {
- srcs: ["errors_unix.cpp"],
+ srcs: [
+ "chrono_utils.cpp",
+ "errors_unix.cpp",
+ ],
cppflags: ["-Wexit-time-destructors"],
enabled: true,
},
linux: {
- srcs: ["errors_unix.cpp"],
+ srcs: [
+ "chrono_utils.cpp",
+ "errors_unix.cpp",
+ ],
cppflags: ["-Wexit-time-destructors"],
+ host_ldlibs: ["-lrt"],
},
windows: {
srcs: [
@@ -92,11 +104,18 @@
],
target: {
android: {
- srcs: ["properties_test.cpp"],
+ srcs: [
+ "chrono_utils_test.cpp",
+ "properties_test.cpp"
+ ],
sanitize: {
misc_undefined: ["integer"],
},
},
+ linux: {
+ srcs: ["chrono_utils_test.cpp"],
+ host_ldlibs: ["-lrt"],
+ },
windows: {
srcs: ["utf8_test.cpp"],
enabled: true,
diff --git a/base/chrono_utils.cpp b/base/chrono_utils.cpp
new file mode 100644
index 0000000..5eedf3b
--- /dev/null
+++ b/base/chrono_utils.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "android-base/chrono_utils.h"
+
+#include <time.h>
+
+namespace android {
+namespace base {
+
+boot_clock::time_point boot_clock::now() {
+#ifdef __ANDROID__
+ timespec ts;
+ clock_gettime(CLOCK_BOOTTIME, &ts);
+ return boot_clock::time_point(std::chrono::seconds(ts.tv_sec) +
+ std::chrono::nanoseconds(ts.tv_nsec));
+#else
+ // Darwin does not support clock_gettime.
+ return boot_clock::time_point();
+#endif // __ANDROID__
+}
+
+} // namespace base
+} // namespace android
diff --git a/base/chrono_utils_test.cpp b/base/chrono_utils_test.cpp
new file mode 100644
index 0000000..057132d
--- /dev/null
+++ b/base/chrono_utils_test.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "android-base/chrono_utils.h"
+
+#include <time.h>
+
+#include <chrono>
+
+#include <gtest/gtest.h>
+
+namespace android {
+namespace base {
+
+std::chrono::seconds GetBootTimeSeconds() {
+ struct timespec now;
+ clock_gettime(CLOCK_BOOTTIME, &now);
+
+ auto now_tp = boot_clock::time_point(std::chrono::seconds(now.tv_sec) +
+ std::chrono::nanoseconds(now.tv_nsec));
+ return std::chrono::duration_cast<std::chrono::seconds>(now_tp.time_since_epoch());
+}
+
+// Tests (at least) the seconds accuracy of the boot_clock::now() method.
+TEST(ChronoUtilsTest, BootClockNowSeconds) {
+ auto now = GetBootTimeSeconds();
+ auto boot_seconds =
+ std::chrono::duration_cast<std::chrono::seconds>(boot_clock::now().time_since_epoch());
+ EXPECT_EQ(now, boot_seconds);
+}
+
+} // namespace base
+} // namespace android
\ No newline at end of file
diff --git a/base/include/android-base/chrono_utils.h b/base/include/android-base/chrono_utils.h
new file mode 100644
index 0000000..0086425
--- /dev/null
+++ b/base/include/android-base/chrono_utils.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_BASE_CHRONO_UTILS_H
+#define ANDROID_BASE_CHRONO_UTILS_H
+
+#include <chrono>
+
+namespace android {
+namespace base {
+
+// A std::chrono clock based on CLOCK_BOOTTIME.
+class boot_clock {
+ public:
+ typedef std::chrono::nanoseconds duration;
+ typedef std::chrono::time_point<boot_clock, duration> time_point;
+
+ static time_point now();
+};
+
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_CHRONO_UTILS_H
diff --git a/bootstat/Android.bp b/bootstat/Android.bp
index f744ad1..95c9af5 100644
--- a/bootstat/Android.bp
+++ b/bootstat/Android.bp
@@ -16,7 +16,6 @@
bootstat_lib_src_files = [
"boot_event_record_store.cpp",
- "uptime_parser.cpp",
]
cc_defaults {
diff --git a/bootstat/boot_event_record_store.cpp b/bootstat/boot_event_record_store.cpp
index 2648594..99d9405 100644
--- a/bootstat/boot_event_record_store.cpp
+++ b/bootstat/boot_event_record_store.cpp
@@ -20,13 +20,16 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <utime.h>
+
+#include <chrono>
#include <cstdlib>
#include <string>
#include <utility>
+
+#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
-#include "uptime_parser.h"
namespace {
@@ -55,7 +58,9 @@
}
void BootEventRecordStore::AddBootEvent(const std::string& event) {
- AddBootEventWithValue(event, bootstat::ParseUptime());
+ auto uptime = std::chrono::duration_cast<std::chrono::seconds>(
+ android::base::boot_clock::now().time_since_epoch());
+ AddBootEventWithValue(event, uptime.count());
}
// The implementation of AddBootEventValue makes use of the mtime file
diff --git a/bootstat/boot_event_record_store_test.cpp b/bootstat/boot_event_record_store_test.cpp
index 90f6513..d98169b 100644
--- a/bootstat/boot_event_record_store_test.cpp
+++ b/bootstat/boot_event_record_store_test.cpp
@@ -21,15 +21,18 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
+
+#include <chrono>
#include <cstdint>
#include <cstdlib>
+
+#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/test_utils.h>
#include <android-base/unique_fd.h>
-#include <gtest/gtest.h>
#include <gmock/gmock.h>
-#include "uptime_parser.h"
+#include <gtest/gtest.h>
using testing::UnorderedElementsAreArray;
@@ -89,6 +92,13 @@
rmdir(path.c_str());
}
+// Returns the time in seconds since boot.
+time_t GetUptimeSeconds() {
+ return std::chrono::duration_cast<std::chrono::seconds>(
+ android::base::boot_clock::now().time_since_epoch())
+ .count();
+}
+
class BootEventRecordStoreTest : public ::testing::Test {
public:
BootEventRecordStoreTest() {
@@ -126,7 +136,7 @@
BootEventRecordStore store;
store.SetStorePath(GetStorePathForTesting());
- time_t uptime = bootstat::ParseUptime();
+ time_t uptime = GetUptimeSeconds();
ASSERT_NE(-1, uptime);
store.AddBootEvent("cenozoic");
@@ -141,7 +151,7 @@
BootEventRecordStore store;
store.SetStorePath(GetStorePathForTesting());
- time_t uptime = bootstat::ParseUptime();
+ time_t uptime = GetUptimeSeconds();
ASSERT_NE(-1, uptime);
store.AddBootEvent("cretaceous");
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index a4cc5f2..6f25d96 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -21,6 +21,7 @@
#include <getopt.h>
#include <unistd.h>
+#include <chrono>
#include <cmath>
#include <cstddef>
#include <cstdio>
@@ -30,15 +31,15 @@
#include <string>
#include <vector>
-#include <android/log.h>
+#include <android-base/chrono_utils.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
+#include <android/log.h>
#include <cutils/properties.h>
#include <metricslogger/metrics_logger.h>
#include "boot_event_record_store.h"
-#include "uptime_parser.h"
namespace {
@@ -255,7 +256,8 @@
BootEventRecordStore boot_event_store;
BootEventRecordStore::BootEventRecord record;
- time_t uptime = bootstat::ParseUptime();
+ auto uptime = std::chrono::duration_cast<std::chrono::seconds>(
+ android::base::boot_clock::now().time_since_epoch());
time_t current_time_utc = time(nullptr);
if (boot_event_store.GetBootEvent("last_boot_time_utc", &record)) {
@@ -282,22 +284,21 @@
// Log the amount of time elapsed until the device is decrypted, which
// includes the variable amount of time the user takes to enter the
// decryption password.
- boot_event_store.AddBootEventWithValue("boot_decryption_complete", uptime);
+ boot_event_store.AddBootEventWithValue("boot_decryption_complete", uptime.count());
// Subtract the decryption time to normalize the boot cycle timing.
- time_t boot_complete = uptime - record.second;
+ std::chrono::seconds boot_complete = std::chrono::seconds(uptime.count() - record.second);
boot_event_store.AddBootEventWithValue(boot_complete_prefix + "_post_decrypt",
- boot_complete);
-
+ boot_complete.count());
} else {
- boot_event_store.AddBootEventWithValue(boot_complete_prefix + "_no_encryption",
- uptime);
+ boot_event_store.AddBootEventWithValue(boot_complete_prefix + "_no_encryption",
+ uptime.count());
}
// Record the total time from device startup to boot complete, regardless of
// encryption state.
- boot_event_store.AddBootEventWithValue(boot_complete_prefix, uptime);
+ boot_event_store.AddBootEventWithValue(boot_complete_prefix, uptime.count());
RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init");
RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init.selinux");
diff --git a/bootstat/uptime_parser.cpp b/bootstat/uptime_parser.cpp
deleted file mode 100644
index 7c2034c..0000000
--- a/bootstat/uptime_parser.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "uptime_parser.h"
-
-#include <time.h>
-#include <cstdlib>
-#include <string>
-#include <android-base/file.h>
-#include <android-base/logging.h>
-
-namespace bootstat {
-
-time_t ParseUptime() {
- std::string uptime_str;
- if (!android::base::ReadFileToString("/proc/uptime", &uptime_str)) {
- PLOG(ERROR) << "Failed to read /proc/uptime";
- return -1;
- }
-
- // Cast intentionally rounds down.
- return static_cast<time_t>(strtod(uptime_str.c_str(), NULL));
-}
-
-} // namespace bootstat
\ No newline at end of file
diff --git a/bootstat/uptime_parser.h b/bootstat/uptime_parser.h
deleted file mode 100644
index 756ae9b..0000000
--- a/bootstat/uptime_parser.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef UPTIME_PARSER_H_
-#define UPTIME_PARSER_H_
-
-#include <time.h>
-
-namespace bootstat {
-
-// Returns the number of seconds the system has been on since reboot.
-time_t ParseUptime();
-
-} // namespace bootstat
-
-#endif // UPTIME_PARSER_H_
\ No newline at end of file
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 720ec03..0406efd 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -625,17 +625,6 @@
return fstab;
}
-/* combines fstab entries passed in from device tree with
- * the ones found from fstab_path
- */
-struct fstab *fs_mgr_read_fstab_with_dt(const char *fstab_path)
-{
- struct fstab *fstab_dt = fs_mgr_read_fstab_dt();
- struct fstab *fstab = fs_mgr_read_fstab(fstab_path);
-
- return in_place_merge(fstab_dt, fstab);
-}
-
/*
* tries to load default fstab.<hardware> file from /odm/etc, /vendor/etc
* or /. loads the first one found and also combines fstab entries passed
@@ -658,7 +647,12 @@
LWARNING << __FUNCTION__ << "(): failed to find device hardware name";
}
- return fs_mgr_read_fstab_with_dt(default_fstab.c_str());
+ // combines fstab entries passed in from device tree with
+ // the ones found from default_fstab file
+ struct fstab *fstab_dt = fs_mgr_read_fstab_dt();
+ struct fstab *fstab = fs_mgr_read_fstab(default_fstab.c_str());
+
+ return in_place_merge(fstab_dt, fstab);
}
void fs_mgr_free_fstab(struct fstab *fstab)
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index e4aeb48..4b626de 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -88,7 +88,6 @@
struct fstab *fs_mgr_read_fstab_default();
struct fstab *fs_mgr_read_fstab_dt();
struct fstab *fs_mgr_read_fstab(const char *fstab_path);
-struct fstab *fs_mgr_read_fstab_with_dt(const char *fstab_path);
void fs_mgr_free_fstab(struct fstab *fstab);
#define FS_MGR_MNTALL_DEV_FILE_ENCRYPTED 5
diff --git a/init/init.cpp b/init/init.cpp
index 6f3b3a6..e14034f 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -40,6 +40,7 @@
#include <selinux/label.h>
#include <selinux/android.h>
+#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
@@ -69,6 +70,7 @@
#include "util.h"
#include "watchdogd.h"
+using android::base::boot_clock;
using android::base::GetProperty;
using android::base::StringPrintf;
diff --git a/init/service.cpp b/init/service.cpp
index 3db34db..e89de9a 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -32,6 +32,7 @@
#include <selinux/selinux.h>
+#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
@@ -48,6 +49,7 @@
#include "property_service.h"
#include "util.h"
+using android::base::boot_clock;
using android::base::ParseInt;
using android::base::StringPrintf;
using android::base::WriteStringToFile;
diff --git a/init/service.h b/init/service.h
index f08a03f..d84ce02 100644
--- a/init/service.h
+++ b/init/service.h
@@ -26,6 +26,8 @@
#include <string>
#include <vector>
+#include <android-base/chrono_utils.h>
+
#include "action.h"
#include "capabilities.h"
#include "descriptors.h"
@@ -144,8 +146,8 @@
unsigned flags_;
pid_t pid_;
- boot_clock::time_point time_started_; // time of last start
- boot_clock::time_point time_crashed_; // first crash within inspection window
+ android::base::boot_clock::time_point time_started_; // time of last start
+ android::base::boot_clock::time_point time_crashed_; // first crash within inspection window
int crash_count_; // number of times crashed within window
uid_t uid_;
diff --git a/init/util.cpp b/init/util.cpp
index 73d97ed..3f8f244 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -52,6 +52,8 @@
#include "reboot.h"
#include "util.h"
+using android::base::boot_clock;
+
static unsigned int do_decode_uid(const char *s)
{
unsigned int v;
@@ -198,13 +200,6 @@
return success;
}
-boot_clock::time_point boot_clock::now() {
- timespec ts;
- clock_gettime(CLOCK_BOOTTIME, &ts);
- return boot_clock::time_point(std::chrono::seconds(ts.tv_sec) +
- std::chrono::nanoseconds(ts.tv_nsec));
-}
-
int mkdir_recursive(const char *pathname, mode_t mode)
{
char buf[128];
diff --git a/init/util.h b/init/util.h
index 81c64d7..23509d3 100644
--- a/init/util.h
+++ b/init/util.h
@@ -25,8 +25,11 @@
#include <ostream>
#include <string>
+#include <android-base/chrono_utils.h>
+
#define COLDBOOT_DONE "/dev/.coldboot_done"
+using android::base::boot_clock;
using namespace std::chrono_literals;
int create_socket(const char *name, int type, mode_t perm,
@@ -35,32 +38,22 @@
bool read_file(const char* path, std::string* content);
bool write_file(const char* path, const char* content);
-// A std::chrono clock based on CLOCK_BOOTTIME.
-class boot_clock {
- public:
- typedef std::chrono::nanoseconds duration;
- typedef std::chrono::time_point<boot_clock, duration> time_point;
- static constexpr bool is_steady = true;
-
- static time_point now();
-};
-
class Timer {
- public:
- Timer() : start_(boot_clock::now()) {
- }
+ public:
+ Timer() : start_(boot_clock::now()) {}
- double duration_s() const {
- typedef std::chrono::duration<double> double_duration;
- return std::chrono::duration_cast<double_duration>(boot_clock::now() - start_).count();
- }
+ double duration_s() const {
+ typedef std::chrono::duration<double> double_duration;
+ return std::chrono::duration_cast<double_duration>(boot_clock::now() - start_).count();
+ }
- int64_t duration_ms() const {
- return std::chrono::duration_cast<std::chrono::milliseconds>(boot_clock::now() - start_).count();
- }
+ int64_t duration_ms() const {
+ return std::chrono::duration_cast<std::chrono::milliseconds>(boot_clock::now() - start_)
+ .count();
+ }
- private:
- boot_clock::time_point start_;
+ private:
+ android::base::boot_clock::time_point start_;
};
std::ostream& operator<<(std::ostream& os, const Timer& t);
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index 0037f15..3eeb9dc 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -130,6 +130,7 @@
#define AID_MEDIA_OBB 1059 /* GID for OBB files on internal media storage */
#define AID_ESE 1060 /* embedded secure element (eSE) subsystem */
#define AID_OTA_UPDATE 1061 /* resource tracking UID for OTA updates */
+#define AID_DISK_RESERVED 1062 /* GID that has access to reserved disk space */
/* Changes to this file must be made in AOSP, *not* in internal branches. */
#define AID_SHELL 2000 /* adb and debug shell user */
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index 3f79552..c4bf959 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -527,11 +527,13 @@
/*
* Measure the time it takes to submit the android event logging call
* using discrete acquisition (StartBenchmarkTiming() -> StopBenchmarkTiming())
- * under light load. Expect this to be a dozen or so syscall periods (40us)
+ * under light load. Expect this to be a long path to logger to convert the
+ * unknown tag (0) into a tagname (less than 200us).
*/
static void BM_log_event_overhead(int iters) {
for (unsigned long long i = 0; i < (unsigned)iters; ++i) {
StartBenchmarkTiming();
+ // log tag number 0 is not known, nor shall it ever be known
__android_log_btwrite(0, EVENT_TYPE_LONG, &i, sizeof(i));
StopBenchmarkTiming();
logd_yield();
@@ -539,6 +541,28 @@
}
BENCHMARK(BM_log_event_overhead);
+/*
+ * Measure the time it takes to submit the android event logging call
+ * using discrete acquisition (StartBenchmarkTiming() -> StopBenchmarkTiming())
+ * under light load with a known logtag. Expect this to be a dozen or so
+ * syscall periods (less than 40us)
+ */
+static void BM_log_event_overhead_42(int iters) {
+ for (unsigned long long i = 0; i < (unsigned)iters; ++i) {
+ StartBenchmarkTiming();
+ // In system/core/logcat/event.logtags:
+ // # These are used for testing, do not modify without updating
+ // # tests/framework-tests/src/android/util/EventLogFunctionalTest.java.
+ // # system/core/liblog/tests/liblog_benchmark.cpp
+ // # system/core/liblog/tests/liblog_test.cpp
+ // 42 answer (to life the universe etc|3)
+ __android_log_btwrite(42, EVENT_TYPE_LONG, &i, sizeof(i));
+ StopBenchmarkTiming();
+ logd_yield();
+ }
+}
+BENCHMARK(BM_log_event_overhead_42);
+
static void BM_log_event_overhead_null(int iters) {
set_log_null();
BM_log_event_overhead(iters);
diff --git a/logcat/event.logtags b/logcat/event.logtags
index 909f8e2..9f05351 100644
--- a/logcat/event.logtags
+++ b/logcat/event.logtags
@@ -36,6 +36,8 @@
# These are used for testing, do not modify without updating
# tests/framework-tests/src/android/util/EventLogFunctionalTest.java.
+# system/core/liblog/tests/liblog_benchmark.cpp
+# system/core/liblog/tests/liblog_test.cpp
42 answer (to life the universe etc|3)
314 pi
2718 e
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 86ea6b4..0984e81 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -109,11 +109,11 @@
LogBuffer::LogBuffer(LastLogTimes* times)
: monotonic(android_log_clockid() == CLOCK_MONOTONIC), mTimes(*times) {
- pthread_mutex_init(&mLogElementsLock, NULL);
+ pthread_mutex_init(&mLogElementsLock, nullptr);
log_id_for_each(i) {
- lastLoggedElements[i] = NULL;
- droppedElements[i] = NULL;
+ lastLoggedElements[i] = nullptr;
+ droppedElements[i] = nullptr;
}
init();
@@ -196,7 +196,7 @@
new LogBufferElement(log_id, realtime, uid, pid, tid, msg, len);
if (log_id != LOG_ID_SECURITY) {
int prio = ANDROID_LOG_INFO;
- const char* tag = NULL;
+ const char* tag = nullptr;
if (log_id == LOG_ID_EVENTS) {
tag = tagToName(elem->getTag());
} else {
@@ -222,24 +222,24 @@
//
// State Init
// incoming:
- // dropped = NULL
- // currentLast = NULL;
+ // dropped = nullptr
+ // currentLast = nullptr;
// elem = incoming message
// outgoing:
- // dropped = NULL -> State 0
+ // dropped = nullptr -> State 0
// currentLast = copy of elem
// log elem
// State 0
// incoming:
// count = 0
- // dropped = NULL
+ // dropped = nullptr
// currentLast = copy of last message
// elem = incoming message
// outgoing: if match != DIFFERENT
// dropped = copy of first identical message -> State 1
// currentLast = reference to elem
// break: if match == DIFFERENT
- // dropped = NULL -> State 0
+ // dropped = nullptr -> State 0
// delete copy of last message (incoming currentLast)
// currentLast = copy of elem
// log elem
@@ -266,7 +266,7 @@
// currentLast = reference to elem, sum liblog.
// break: if match == DIFFERENT
// delete dropped
- // dropped = NULL -> State 0
+ // dropped = nullptr -> State 0
// log reference to last held-back (currentLast)
// currentLast = copy of elem
// log elem
@@ -285,7 +285,7 @@
// currentLast = reference to elem
// break: if match == DIFFERENT
// log dropped (chatty message)
- // dropped = NULL -> State 0
+ // dropped = nullptr -> State 0
// log reference to last held-back (currentLast)
// currentLast = copy of elem
// log elem
@@ -350,7 +350,7 @@
} else { // State 1
delete dropped;
}
- droppedElements[log_id] = NULL;
+ droppedElements[log_id] = nullptr;
log(currentLast); // report last message in the series
} else { // State 0
delete currentLast;
@@ -654,7 +654,7 @@
// mLogElementsLock must be held when this function is called.
//
bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
- LogTimeEntry* oldest = NULL;
+ LogTimeEntry* oldest = nullptr;
bool busy = false;
bool clearAll = pruneRows == ULONG_MAX;
@@ -1076,9 +1076,11 @@
return retval;
}
-log_time LogBuffer::flushTo(
- SocketClient* reader, const log_time& start, bool privileged, bool security,
- int (*filter)(const LogBufferElement* element, void* arg), void* arg) {
+log_time LogBuffer::flushTo(SocketClient* reader, const log_time& start,
+ pid_t* lastTid, bool privileged, bool security,
+ int (*filter)(const LogBufferElement* element,
+ void* arg),
+ void* arg) {
LogBufferElementCollection::iterator it;
uid_t uid = reader->getUid();
@@ -1107,9 +1109,6 @@
}
log_time max = start;
- // Help detect if the valid message before is from the same source so
- // we can differentiate chatty filter types.
- pid_t lastTid[LOG_ID_MAX] = { 0 };
for (; it != mLogElements.end(); ++it) {
LogBufferElement* element = *it;
@@ -1137,14 +1136,17 @@
}
}
- bool sameTid = lastTid[element->getLogId()] == element->getTid();
- // Dropped (chatty) immediately following a valid log from the
- // same source in the same log buffer indicates we have a
- // multiple identical squash. chatty that differs source
- // is due to spam filter. chatty to chatty of different
- // source is also due to spam filter.
- lastTid[element->getLogId()] =
- (element->getDropped() && !sameTid) ? 0 : element->getTid();
+ bool sameTid = false;
+ if (lastTid) {
+ sameTid = lastTid[element->getLogId()] == element->getTid();
+ // Dropped (chatty) immediately following a valid log from the
+ // same source in the same log buffer indicates we have a
+ // multiple identical squash. chatty that differs source
+ // is due to spam filter. chatty to chatty of different
+ // source is also due to spam filter.
+ lastTid[element->getLogId()] =
+ (element->getDropped() && !sameTid) ? 0 : element->getTid();
+ }
pthread_mutex_unlock(&mLogElementsLock);
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index fcf6b9a..19d11cb 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -115,11 +115,15 @@
int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
const char* msg, unsigned short len);
+ // lastTid is an optional context to help detect if the last previous
+ // valid message was from the same source so we can differentiate chatty
+ // filter types (identical or expired)
log_time flushTo(SocketClient* writer, const log_time& start,
+ pid_t* lastTid, // &lastTid[LOG_ID_MAX] or nullptr
bool privileged, bool security,
int (*filter)(const LogBufferElement* element,
- void* arg) = NULL,
- void* arg = NULL);
+ void* arg) = nullptr,
+ void* arg = nullptr);
bool clear(log_id_t id, uid_t uid = AID_ROOT);
unsigned long getSize(log_id_t id);
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
index 620d4d0..af19279 100644
--- a/logd/LogReader.cpp
+++ b/logd/LogReader.cpp
@@ -182,7 +182,7 @@
} logFindStart(pid, logMask, sequence,
logbuf().isMonotonic() && android::isMonotonic(start));
- logbuf().flushTo(cli, sequence, FlushCommand::hasReadLogs(cli),
+ logbuf().flushTo(cli, sequence, nullptr, FlushCommand::hasReadLogs(cli),
FlushCommand::hasSecurityLogs(cli),
logFindStart.callback, &logFindStart);
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index 04e531f..ccc550a 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -15,6 +15,7 @@
*/
#include <errno.h>
+#include <string.h>
#include <sys/prctl.h>
#include <private/android_logger.h>
@@ -47,7 +48,8 @@
mEnd(log_time(android_log_clockid())) {
mTimeout.tv_sec = timeout / NS_PER_SEC;
mTimeout.tv_nsec = timeout % NS_PER_SEC;
- pthread_cond_init(&threadTriggeredCondition, NULL);
+ memset(mLastTid, 0, sizeof(mLastTid));
+ pthread_cond_init(&threadTriggeredCondition, nullptr);
cleanSkip_Locked();
}
@@ -98,7 +100,7 @@
it++;
}
- me->mClient = NULL;
+ me->mClient = nullptr;
reader.release(client);
}
@@ -122,7 +124,7 @@
SocketClient* client = me->mClient;
if (!client) {
me->error();
- return NULL;
+ return nullptr;
}
LogBuffer& logbuf = me->mReader.logbuf();
@@ -151,12 +153,12 @@
unlock();
if (me->mTail) {
- logbuf.flushTo(client, start, privileged, security, FilterFirstPass,
- me);
+ logbuf.flushTo(client, start, nullptr, privileged, security,
+ FilterFirstPass, me);
me->leadingDropped = true;
}
- start = logbuf.flushTo(client, start, privileged, security,
- FilterSecondPass, me);
+ start = logbuf.flushTo(client, start, me->mLastTid, privileged,
+ security, FilterSecondPass, me);
lock();
@@ -182,7 +184,7 @@
pthread_cleanup_pop(true);
- return NULL;
+ return nullptr;
}
// A first pass to count the number of elements
@@ -281,7 +283,5 @@
}
void LogTimeEntry::cleanSkip_Locked(void) {
- for (log_id_t i = LOG_ID_MIN; i < LOG_ID_MAX; i = (log_id_t)(i + 1)) {
- skipAhead[i] = 0;
- }
+ memset(skipAhead, 0, sizeof(skipAhead));
}
diff --git a/logd/LogTimes.h b/logd/LogTimes.h
index 9a3ddab..ec8252e 100644
--- a/logd/LogTimes.h
+++ b/logd/LogTimes.h
@@ -44,6 +44,7 @@
const unsigned int mLogMask;
const pid_t mPid;
unsigned int skipAhead[LOG_ID_MAX];
+ pid_t mLastTid[LOG_ID_MAX];
unsigned long mCount;
unsigned long mTail;
unsigned long mIndex;
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index ddff393..d0101ed 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -426,7 +426,7 @@
" BM_log_maximum_retry"
" BM_log_maximum"
" BM_clock_overhead"
- " BM_log_overhead"
+ " BM_log_print_overhead"
" BM_log_latency"
" BM_log_delay",
"r")));
@@ -434,13 +434,13 @@
char buffer[5120];
static const char* benchmarks[] = {
- "BM_log_maximum_retry ", "BM_log_maximum ", "BM_clock_overhead ",
- "BM_log_overhead ", "BM_log_latency ", "BM_log_delay "
+ "BM_log_maximum_retry ", "BM_log_maximum ", "BM_clock_overhead ",
+ "BM_log_print_overhead ", "BM_log_latency ", "BM_log_delay "
};
static const unsigned int log_maximum_retry = 0;
static const unsigned int log_maximum = 1;
static const unsigned int clock_overhead = 2;
- static const unsigned int log_overhead = 3;
+ static const unsigned int log_print_overhead = 3;
static const unsigned int log_latency = 4;
static const unsigned int log_delay = 5;
@@ -469,21 +469,23 @@
}
EXPECT_GE(200000UL, ns[log_maximum_retry]); // 104734 user
+ EXPECT_NE(0UL, ns[log_maximum_retry]); // failure to parse
EXPECT_GE(90000UL, ns[log_maximum]); // 46913 user
+ EXPECT_NE(0UL, ns[log_maximum]); // failure to parse
EXPECT_GE(4096UL, ns[clock_overhead]); // 4095
+ EXPECT_NE(0UL, ns[clock_overhead]); // failure to parse
- EXPECT_GE(250000UL, ns[log_overhead]); // 126886 user
+ EXPECT_GE(250000UL, ns[log_print_overhead]); // 126886 user
+ EXPECT_NE(0UL, ns[log_print_overhead]); // failure to parse
EXPECT_GE(10000000UL,
ns[log_latency]); // 1453559 user space (background cgroup)
+ EXPECT_NE(0UL, ns[log_latency]); // failure to parse
EXPECT_GE(20000000UL, ns[log_delay]); // 10500289 user
-
- for (unsigned i = 0; i < arraysize(ns); ++i) {
- EXPECT_NE(0UL, ns[i]);
- }
+ EXPECT_NE(0UL, ns[log_delay]); // failure to parse
alloc_statistics(&buf, &len);