1 /*
2 * Copyright 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #pragma once
18
19 #include <chrono>
20 #include <string>
21
22 #include <android-base/stringprintf.h>
23 #include <utils/Timers.h>
24
25 namespace android {
26 namespace scheduler {
27
28 // TODO(b/185535769): Pull Clock.h to libscheduler to reuse this.
29 using SchedulerClock = std::chrono::steady_clock;
30 static_assert(SchedulerClock::is_steady);
31
32 } // namespace scheduler
33
34 struct Duration;
35
36 struct TimePoint : scheduler::SchedulerClock::time_point {
37 constexpr TimePoint() = default;
38 explicit constexpr TimePoint(const Duration&);
39
40 // Implicit conversion from std::chrono counterpart.
TimePointTimePoint41 constexpr TimePoint(scheduler::SchedulerClock::time_point p)
42 : scheduler::SchedulerClock::time_point(p) {}
43
44 static constexpr TimePoint fromNs(nsecs_t);
45
nowTimePoint46 static TimePoint now() { return scheduler::SchedulerClock::now(); };
47
48 nsecs_t ns() const;
49 };
50
51 struct Duration : TimePoint::duration {
52 // Implicit conversion from std::chrono counterpart.
53 template <typename R, typename P>
DurationDuration54 constexpr Duration(std::chrono::duration<R, P> d) : TimePoint::duration(d) {}
55
fromNsDuration56 static constexpr Duration fromNs(nsecs_t ns) { return {std::chrono::nanoseconds(ns)}; }
57
nsDuration58 nsecs_t ns() const { return std::chrono::nanoseconds(*this).count(); }
59 };
60
61 using Period = Duration;
62
TimePoint(const Duration & d)63 constexpr TimePoint::TimePoint(const Duration& d) : scheduler::SchedulerClock::time_point(d) {}
64
fromNs(nsecs_t ns)65 constexpr TimePoint TimePoint::fromNs(nsecs_t ns) {
66 return TimePoint(Duration::fromNs(ns));
67 }
68
ns()69 inline nsecs_t TimePoint::ns() const {
70 return Duration(time_since_epoch()).ns();
71 }
72
73 // Shorthand to convert the tick count of a Duration to Period and Rep. For example:
74 //
75 // const auto i = ticks<std::ratio<1>>(d); // Integer seconds.
76 // const auto f = ticks<std::milli, float>(d); // Floating-point milliseconds.
77 //
78 template <typename Period, typename Rep = Duration::rep>
ticks(Duration d)79 constexpr Rep ticks(Duration d) {
80 using D = std::chrono::duration<Rep, Period>;
81 return std::chrono::duration_cast<D>(d).count();
82 }
83
to_string(Duration d)84 inline std::string to_string(Duration d) {
85 return base::StringPrintf("%.3f ms", ticks<std::milli, float>(d));
86 }
87
88 } // namespace android
89