Loading services/mediametrics/AudioPowerUsage.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -549,7 +549,7 @@ std::pair<std::string, int32_t> AudioPowerUsage::dump(int limit) const { int slot = 1; std::stringstream ss; ss << "AudioPowerUsage:\n"; ss << "AudioPowerUsage interval " << mIntervalHours << " hours:\n"; for (const auto &item : mItems) { if (slot >= limit - 1) { ss << "-- AudioPowerUsage may be truncated!\n"; Loading services/mediametrics/include/mediametricsservice/TimedAction.h +15 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,12 @@ namespace android::mediametrics { class TimedAction { // Use system_clock instead of steady_clock to include suspend time. using TimerClock = class std::chrono::system_clock; // Define granularity of wakeup to prevent delayed events if // device is suspended. static constexpr auto kWakeupInterval = std::chrono::minutes(15); public: TimedAction() : mThread{[this](){threadLoop();}} {} Loading @@ -35,7 +41,7 @@ public: // TODO: return a handle for cancelling the action? template <typename T> // T is in units of std::chrono::duration. void postIn(const T& time, std::function<void()> f) { postAt(std::chrono::steady_clock::now() + time, f); postAt(TimerClock::now() + time, f); } template <typename T> // T is in units of std::chrono::time_point Loading Loading @@ -75,16 +81,21 @@ private: void threadLoop() NO_THREAD_SAFETY_ANALYSIS { // thread safety doesn't cover unique_lock std::unique_lock l(mLock); while (!mQuit) { auto sleepUntilTime = std::chrono::time_point<std::chrono::steady_clock>::max(); auto sleepUntilTime = std::chrono::time_point<TimerClock>::max(); if (!mMap.empty()) { sleepUntilTime = mMap.begin()->first; if (sleepUntilTime <= std::chrono::steady_clock::now()) { const auto now = TimerClock::now(); if (sleepUntilTime <= now) { auto node = mMap.extract(mMap.begin()); // removes from mMap. l.unlock(); node.mapped()(); l.lock(); continue; } // Bionic uses CLOCK_MONOTONIC for its pthread_mutex regardless // of REALTIME specification, use kWakeupInterval to ensure minimum // granularity if suspended. sleepUntilTime = std::min(sleepUntilTime, now + kWakeupInterval); } mCondition.wait_until(l, sleepUntilTime); } Loading @@ -93,7 +104,7 @@ private: mutable std::mutex mLock; std::condition_variable mCondition GUARDED_BY(mLock); bool mQuit GUARDED_BY(mLock) = false; std::multimap<std::chrono::time_point<std::chrono::steady_clock>, std::function<void()>> std::multimap<std::chrono::time_point<TimerClock>, std::function<void()>> mMap GUARDED_BY(mLock); // multiple functions could execute at the same time. // needs to be initialized after the variables above, done in constructor initializer list. Loading Loading
services/mediametrics/AudioPowerUsage.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -549,7 +549,7 @@ std::pair<std::string, int32_t> AudioPowerUsage::dump(int limit) const { int slot = 1; std::stringstream ss; ss << "AudioPowerUsage:\n"; ss << "AudioPowerUsage interval " << mIntervalHours << " hours:\n"; for (const auto &item : mItems) { if (slot >= limit - 1) { ss << "-- AudioPowerUsage may be truncated!\n"; Loading
services/mediametrics/include/mediametricsservice/TimedAction.h +15 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,12 @@ namespace android::mediametrics { class TimedAction { // Use system_clock instead of steady_clock to include suspend time. using TimerClock = class std::chrono::system_clock; // Define granularity of wakeup to prevent delayed events if // device is suspended. static constexpr auto kWakeupInterval = std::chrono::minutes(15); public: TimedAction() : mThread{[this](){threadLoop();}} {} Loading @@ -35,7 +41,7 @@ public: // TODO: return a handle for cancelling the action? template <typename T> // T is in units of std::chrono::duration. void postIn(const T& time, std::function<void()> f) { postAt(std::chrono::steady_clock::now() + time, f); postAt(TimerClock::now() + time, f); } template <typename T> // T is in units of std::chrono::time_point Loading Loading @@ -75,16 +81,21 @@ private: void threadLoop() NO_THREAD_SAFETY_ANALYSIS { // thread safety doesn't cover unique_lock std::unique_lock l(mLock); while (!mQuit) { auto sleepUntilTime = std::chrono::time_point<std::chrono::steady_clock>::max(); auto sleepUntilTime = std::chrono::time_point<TimerClock>::max(); if (!mMap.empty()) { sleepUntilTime = mMap.begin()->first; if (sleepUntilTime <= std::chrono::steady_clock::now()) { const auto now = TimerClock::now(); if (sleepUntilTime <= now) { auto node = mMap.extract(mMap.begin()); // removes from mMap. l.unlock(); node.mapped()(); l.lock(); continue; } // Bionic uses CLOCK_MONOTONIC for its pthread_mutex regardless // of REALTIME specification, use kWakeupInterval to ensure minimum // granularity if suspended. sleepUntilTime = std::min(sleepUntilTime, now + kWakeupInterval); } mCondition.wait_until(l, sleepUntilTime); } Loading @@ -93,7 +104,7 @@ private: mutable std::mutex mLock; std::condition_variable mCondition GUARDED_BY(mLock); bool mQuit GUARDED_BY(mLock) = false; std::multimap<std::chrono::time_point<std::chrono::steady_clock>, std::function<void()>> std::multimap<std::chrono::time_point<TimerClock>, std::function<void()>> mMap GUARDED_BY(mLock); // multiple functions could execute at the same time. // needs to be initialized after the variables above, done in constructor initializer list. Loading