diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-03-23 10:24:02 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-03-23 10:24:02 +0000 |
commit | 6b0915e761b0a360c1853f585df6b441cecaf527 (patch) | |
tree | a3a392a1a443d592d7ec7115168943bce27d2e2e /automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp | |
parent | 1e28f6e696943d2967f7a1960151446eb3d48dc9 (diff) | |
parent | 0b9798cf11d9eddcde7fae9cf1b4e071664d82b2 (diff) |
Snap for 9798568 from 0b9798cf11d9eddcde7fae9cf1b4e071664d82b2 to t-keystone-qcom-release
Change-Id: Ia54f3d6af82485690772ecdd05457df18f2de708
Diffstat (limited to 'automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp')
-rw-r--r-- | automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp | 67 |
1 files changed, 35 insertions, 32 deletions
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp index 2eca6b7a17..908564c2ff 100644 --- a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp +++ b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp @@ -101,68 +101,71 @@ void RecurrentTimer::removeInvalidCallbackLocked() { } } -std::unique_ptr<RecurrentTimer::CallbackInfo> RecurrentTimer::popNextCallbackLocked() { +std::shared_ptr<RecurrentTimer::Callback> RecurrentTimer::getNextCallbackLocked(int64_t now) { std::pop_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp); - std::unique_ptr<CallbackInfo> info = std::move(mCallbackQueue[mCallbackQueue.size() - 1]); - mCallbackQueue.pop_back(); + auto& callbackInfo = mCallbackQueue[mCallbackQueue.size() - 1]; + auto nextCallback = callbackInfo->callback; + // intervalCount is the number of interval we have to advance until we pass now. + size_t intervalCount = (now - callbackInfo->nextTime) / callbackInfo->interval + 1; + callbackInfo->nextTime += intervalCount * callbackInfo->interval; + std::push_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp); + // Make sure the first element is always valid. removeInvalidCallbackLocked(); - return info; + + return nextCallback; } void RecurrentTimer::loop() { - std::unique_lock<std::mutex> uniqueLock(mLock); - + std::vector<std::shared_ptr<Callback>> callbacksToRun; while (true) { - // Wait until the timer exits or we have at least one recurrent callback. - mCond.wait(uniqueLock, [this] { - ScopedLockAssertion lockAssertion(mLock); - return mStopRequested || mCallbackQueue.size() != 0; - }); - - int64_t interval; { + std::unique_lock<std::mutex> uniqueLock(mLock); ScopedLockAssertion lockAssertion(mLock); + // Wait until the timer exits or we have at least one recurrent callback. + mCond.wait(uniqueLock, [this] { + ScopedLockAssertion lockAssertion(mLock); + return mStopRequested || mCallbackQueue.size() != 0; + }); + + int64_t interval; if (mStopRequested) { return; } // The first element is the nearest next event. int64_t nextTime = mCallbackQueue[0]->nextTime; int64_t now = uptimeNanos(); + if (nextTime > now) { interval = nextTime - now; } else { interval = 0; } - } - // Wait for the next event or the timer exits. - if (mCond.wait_for(uniqueLock, std::chrono::nanoseconds(interval), [this] { - ScopedLockAssertion lockAssertion(mLock); - return mStopRequested; - })) { - return; - } + // Wait for the next event or the timer exits. + if (mCond.wait_for(uniqueLock, std::chrono::nanoseconds(interval), [this] { + ScopedLockAssertion lockAssertion(mLock); + return mStopRequested; + })) { + return; + } - { - ScopedLockAssertion lockAssertion(mLock); - int64_t now = uptimeNanos(); + now = uptimeNanos(); + callbacksToRun.clear(); while (mCallbackQueue.size() > 0) { int64_t nextTime = mCallbackQueue[0]->nextTime; if (nextTime > now) { break; } - std::unique_ptr<CallbackInfo> info = popNextCallbackLocked(); - info->nextTime += info->interval; - - auto callback = info->callback; - mCallbackQueue.push_back(std::move(info)); - std::push_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp); - - (*callback)(); + callbacksToRun.push_back(getNextCallbackLocked(now)); } } + + // Do not execute the callback while holding the lock. + for (size_t i = 0; i < callbacksToRun.size(); i++) { + (*callbacksToRun[i])(); + } } } |