diff options
-rw-r--r-- | base/Android.bp | 25 | ||||
-rw-r--r-- | base/chrono_utils.cpp (renamed from bootstat/uptime_parser.h) | 21 | ||||
-rw-r--r-- | base/chrono_utils_test.cpp | 47 | ||||
-rw-r--r-- | base/include/android-base/chrono_utils.h (renamed from bootstat/uptime_parser.cpp) | 35 | ||||
-rw-r--r-- | bootstat/Android.bp | 1 | ||||
-rw-r--r-- | bootstat/boot_event_record_store.cpp | 10 | ||||
-rw-r--r-- | bootstat/boot_event_record_store_test.cpp | 15 | ||||
-rw-r--r-- | bootstat/bootstat.cpp | 16 | ||||
-rw-r--r-- | init/Android.mk | 2 | ||||
-rw-r--r-- | init/init.cpp | 4 | ||||
-rw-r--r-- | init/service.cpp | 2 | ||||
-rw-r--r-- | init/service.h | 6 | ||||
-rw-r--r-- | init/util.cpp | 17 | ||||
-rw-r--r-- | init/util.h | 26 |
14 files changed, 154 insertions, 73 deletions
diff --git a/base/Android.bp b/base/Android.bp index b9a6e0bd6..515b063f9 100644 --- a/base/Android.bp +++ b/base/Android.bp @@ -42,21 +42,31 @@ cc_library { srcs: [ "errors_unix.cpp", "properties.cpp", + "chrono_utils.cpp", ], cppflags: ["-Wexit-time-destructors"], }, darwin: { - srcs: ["errors_unix.cpp"], + srcs: [ + "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: [ @@ -88,7 +98,14 @@ cc_test { ], target: { android: { - srcs: ["properties_test.cpp"], + srcs: [ + "chrono_utils_test.cpp", + "properties_test.cpp" + ], + }, + linux: { + srcs: ["chrono_utils_test.cpp"], + host_ldlibs: ["-lrt"], }, windows: { srcs: ["utf8_test.cpp"], diff --git a/bootstat/uptime_parser.h b/base/chrono_utils.cpp index 756ae9b7c..d1c69c5cc 100644 --- a/bootstat/uptime_parser.h +++ b/base/chrono_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 The Android Open Source Project + * 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. @@ -14,16 +14,19 @@ * limitations under the License. */ -#ifndef UPTIME_PARSER_H_ -#define UPTIME_PARSER_H_ +#include "android-base/chrono_utils.h" #include <time.h> -namespace bootstat { +namespace android { +namespace base { -// Returns the number of seconds the system has been on since reboot. -time_t ParseUptime(); +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)); +} -} // namespace bootstat - -#endif // UPTIME_PARSER_H_
\ No newline at end of file +} // namespace base +} // namespace android
\ No newline at end of file diff --git a/base/chrono_utils_test.cpp b/base/chrono_utils_test.cpp new file mode 100644 index 000000000..bc6df4b9a --- /dev/null +++ b/base/chrono_utils_test.cpp @@ -0,0 +1,47 @@ +/* + * 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/bootstat/uptime_parser.cpp b/base/include/android-base/chrono_utils.h index 7c2034c3d..0086425e5 100644 --- a/bootstat/uptime_parser.cpp +++ b/base/include/android-base/chrono_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 The Android Open Source Project + * 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. @@ -14,25 +14,24 @@ * limitations under the License. */ -#include "uptime_parser.h" +#ifndef ANDROID_BASE_CHRONO_UTILS_H +#define ANDROID_BASE_CHRONO_UTILS_H -#include <time.h> -#include <cstdlib> -#include <string> -#include <android-base/file.h> -#include <android-base/logging.h> +#include <chrono> -namespace bootstat { +namespace android { +namespace base { -time_t ParseUptime() { - std::string uptime_str; - if (!android::base::ReadFileToString("/proc/uptime", &uptime_str)) { - PLOG(ERROR) << "Failed to read /proc/uptime"; - return -1; - } +// 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; - // Cast intentionally rounds down. - return static_cast<time_t>(strtod(uptime_str.c_str(), NULL)); -} + static time_point now(); +}; -} // namespace bootstat
\ No newline at end of file +} // namespace base +} // namespace android + +#endif // ANDROID_BASE_CHRONO_UTILS_H diff --git a/bootstat/Android.bp b/bootstat/Android.bp index d98a9d7dd..7d9d7a27a 100644 --- a/bootstat/Android.bp +++ b/bootstat/Android.bp @@ -17,7 +17,6 @@ bootstat_lib_src_files = [ "boot_event_record_store.cpp", "histogram_logger.cpp", - "uptime_parser.cpp", ] cc_defaults { diff --git a/bootstat/boot_event_record_store.cpp b/bootstat/boot_event_record_store.cpp index f902af337..8babf1a9e 100644 --- a/bootstat/boot_event_record_store.cpp +++ b/bootstat/boot_event_record_store.cpp @@ -20,14 +20,18 @@ #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 "histogram_logger.h" -#include "uptime_parser.h" namespace { @@ -56,7 +60,9 @@ BootEventRecordStore::BootEventRecordStore() { } 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 90f6513e4..0df67061f 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" using testing::UnorderedElementsAreArray; @@ -89,6 +92,12 @@ void DeleteDirectory(const std::string& path) { 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 +135,7 @@ TEST_F(BootEventRecordStoreTest, AddSingleBootEvent) { BootEventRecordStore store; store.SetStorePath(GetStorePathForTesting()); - time_t uptime = bootstat::ParseUptime(); + time_t uptime = GetUptimeSeconds(); ASSERT_NE(-1, uptime); store.AddBootEvent("cenozoic"); @@ -141,7 +150,7 @@ TEST_F(BootEventRecordStoreTest, AddMultipleBootEvents) { 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 c85667e86..322add327 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> @@ -31,6 +32,7 @@ #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> @@ -38,7 +40,6 @@ #include "boot_event_record_store.h" #include "histogram_logger.h" -#include "uptime_parser.h" namespace { @@ -247,7 +248,8 @@ void RecordBootComplete() { 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)) { @@ -274,22 +276,22 @@ void RecordBootComplete() { // 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); + 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/init/Android.mk b/init/Android.mk index 9e61fb2f6..53ef2d07c 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -36,7 +36,7 @@ LOCAL_MODULE := init_parser_tests LOCAL_SRC_FILES := \ parser/tokenizer_test.cpp \ -LOCAL_STATIC_LIBRARIES := libinit_parser +LOCAL_STATIC_LIBRARIES := libbase libinit_parser LOCAL_CLANG := true include $(BUILD_HOST_NATIVE_TEST) endif diff --git a/init/init.cpp b/init/init.cpp index 43f601f69..4af0656c0 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/stringprintf.h> #include <android-base/strings.h> @@ -68,6 +69,7 @@ #include "util.h" #include "watchdogd.h" +using android::base::boot_clock; using android::base::StringPrintf; struct selabel_handle *sehandle; @@ -750,7 +752,7 @@ int main(int argc, char** argv) { return watchdogd_main(argc, argv); } - boot_clock::time_point start_time = boot_clock::now(); + boot_clock::time_point start_time = android::base::boot_clock::now(); // Clear the umask. umask(0); diff --git a/init/service.cpp b/init/service.cpp index e186f27a8..cbdc4a8f8 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/stringprintf.h> @@ -47,6 +48,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 013e65f04..3dc0e53a2 100644 --- a/init/service.h +++ b/init/service.h @@ -25,6 +25,8 @@ #include <string> #include <vector> +#include <android-base/chrono_utils.h> + #include "action.h" #include "capabilities.h" #include "descriptors.h" @@ -135,8 +137,8 @@ private: 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 888a36652..f59ba82e1 100644 --- a/init/util.cpp +++ b/init/util.cpp @@ -51,6 +51,8 @@ #include "property_service.h" #include "util.h" +using android::base::boot_clock; + static unsigned int do_decode_uid(const char *s) { unsigned int v; @@ -199,11 +201,16 @@ bool write_file(const char* path, const char* content) { 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)); +Timer::Timer() : start_(boot_clock::now()) { +} + +double Timer::duration_s() const { + typedef std::chrono::duration<double> double_duration; + return std::chrono::duration_cast<double_duration>(boot_clock::now() - start_).count(); +} + +int64_t Timer::duration_ms() const { + return std::chrono::duration_cast<std::chrono::milliseconds>(boot_clock::now() - start_).count(); } int mkdir_recursive(const char *pathname, mode_t mode) diff --git a/init/util.h b/init/util.h index 5c38dc3c9..4444427ea 100644 --- a/init/util.h +++ b/init/util.h @@ -25,6 +25,8 @@ #include <ostream> #include <string> +#include <android-base/chrono_utils.h> + #define COLDBOOT_DONE "/dev/.coldboot_done" using namespace std::chrono_literals; @@ -35,32 +37,16 @@ int create_socket(const char *name, int type, mode_t perm, 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()) { - } + Timer(); - 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; - int64_t duration_ms() const { - return std::chrono::duration_cast<std::chrono::milliseconds>(boot_clock::now() - start_).count(); - } + int64_t duration_ms() const; private: - boot_clock::time_point start_; + android::base::boot_clock::time_point start_; }; std::ostream& operator<<(std::ostream& os, const Timer& t); |