summaryrefslogtreecommitdiff
path: root/power-libperfmgr/aidl/PowerHintSession.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'power-libperfmgr/aidl/PowerHintSession.cpp')
-rw-r--r--power-libperfmgr/aidl/PowerHintSession.cpp266
1 files changed, 151 insertions, 115 deletions
diff --git a/power-libperfmgr/aidl/PowerHintSession.cpp b/power-libperfmgr/aidl/PowerHintSession.cpp
index 5d0e2c5..e8ef1e2 100644
--- a/power-libperfmgr/aidl/PowerHintSession.cpp
+++ b/power-libperfmgr/aidl/PowerHintSession.cpp
@@ -127,8 +127,16 @@ PowerHintSession::PowerHintSession(std::shared_ptr<AdaptiveCpu> adaptiveCpu, int
: mAdaptiveCpu(adaptiveCpu) {
mDescriptor = new AppHintDesc(tgid, uid, threadIds);
mDescriptor->duration = std::chrono::nanoseconds(durationNanos);
- mHintTimerHandler = sp<HintTimerHandler>(new HintTimerHandler(this));
+ mStaleTimerHandler = sp<StaleTimerHandler>(new StaleTimerHandler(this));
+ mEarlyBoostHandler = sp<EarlyBoostHandler>(new EarlyBoostHandler(this));
mPowerManagerHandler = PowerSessionManager::getInstance();
+ mLastUpdatedTime.store(std::chrono::steady_clock::now());
+ mLastStartedTimeNs =
+ std::chrono::duration_cast<std::chrono::nanoseconds>(
+ (std::chrono::steady_clock::now() - mDescriptor->duration).time_since_epoch())
+ .count();
+ mLastDurationNs = durationNanos;
+ mWorkPeriodNs = durationNanos;
if (ATRACE_ENABLED()) {
const std::string idstr = getIdString();
@@ -139,7 +147,7 @@ PowerHintSession::PowerHintSession(std::shared_ptr<AdaptiveCpu> adaptiveCpu, int
}
PowerSessionManager::getInstance()->addPowerSession(this);
// init boost
- setSessionUclampMin(HintManager::GetInstance()->GetAdpfProfile()->mUclampMinInit);
+ wakeup();
ALOGV("PowerHintSession created: %s", mDescriptor->toString().c_str());
}
@@ -159,7 +167,6 @@ PowerHintSession::~PowerHintSession() {
std::lock_guard<std::mutex> guard(mSessionLock);
mSessionClosed.store(true);
}
- mHintTimerHandler->setSessionDead();
delete mDescriptor;
}
@@ -193,7 +200,11 @@ int PowerHintSession::setSessionUclampMin(int32_t min) {
std::lock_guard<std::mutex> guard(mSessionLock);
mDescriptor->current_min = min;
}
+ if (min) {
+ mStaleTimerHandler->updateTimer();
+ }
PowerSessionManager::getInstance()->setUclampMin(this, min);
+
if (ATRACE_ENABLED()) {
const std::string idstr = getIdString();
std::string sz = StringPrintf("adpf.%s-min", idstr.c_str());
@@ -207,10 +218,10 @@ int PowerHintSession::getUclampMin() {
}
void PowerHintSession::dumpToStream(std::ostream &stream) {
- stream << "ID.Min.Act.Stale(" << getIdString();
+ stream << "ID.Min.Act.Timeout(" << getIdString();
stream << ", " << mDescriptor->current_min;
stream << ", " << mDescriptor->is_active;
- stream << ", " << isStale() << ")";
+ stream << ", " << isTimeout() << ")";
}
ndk::ScopedAStatus PowerHintSession::pause() {
@@ -240,7 +251,6 @@ ndk::ScopedAStatus PowerHintSession::resume() {
if (mDescriptor->is_active.load())
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
mDescriptor->is_active.store(true);
- mHintTimerHandler->updateHintTimer(0);
// resume boost
setSessionUclampMin(mDescriptor->current_min);
if (ATRACE_ENABLED()) {
@@ -257,6 +267,9 @@ ndk::ScopedAStatus PowerHintSession::close() {
if (!mSessionClosed.compare_exchange_strong(sessionClosedExpectedToBe, true)) {
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
+ mDescriptor->is_active.store(false);
+ mEarlyBoostHandler->setSessionDead();
+ mStaleTimerHandler->setSessionDead();
setSessionUclampMin(0);
PowerSessionManager::getInstance()->removePowerSession(this);
updateUniveralBoostMode();
@@ -306,6 +319,7 @@ ndk::ScopedAStatus PowerHintSession::reportActualWorkDuration(
}
std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
mDescriptor->update_count++;
+ bool isFirstFrame = isTimeout();
if (ATRACE_ENABLED()) {
const std::string idstr = getIdString();
std::string sz = StringPrintf("adpf.%s-batch_size", idstr.c_str());
@@ -321,7 +335,10 @@ ndk::ScopedAStatus PowerHintSession::reportActualWorkDuration(
actualDurations.back().durationNanos - mDescriptor->duration.count() > 0);
}
- mHintTimerHandler->updateHintTimer(actualDurations);
+ mLastUpdatedTime.store(std::chrono::steady_clock::now());
+ if (isFirstFrame) {
+ updateUniveralBoostMode();
+ }
if (!adpfConfig->mPidOn) {
setSessionUclampMin(adpfConfig->mUclampMinHigh);
@@ -336,6 +353,11 @@ ndk::ScopedAStatus PowerHintSession::reportActualWorkDuration(
mDescriptor->current_min + static_cast<int>(output));
next_min = std::max(static_cast<int>(adpfConfig->mUclampMinLow), next_min);
setSessionUclampMin(next_min);
+ mStaleTimerHandler->updateTimer(getStaleTime());
+ if (HintManager::GetInstance()->GetAdpfProfile()->mEarlyBoostOn) {
+ updateWorkPeriod(actualDurations);
+ mEarlyBoostHandler->updateTimer(getEarlyBoostTime());
+ }
mAdaptiveCpu->ReportWorkDurations(actualDurations, mDescriptor->duration);
@@ -367,9 +389,9 @@ bool PowerHintSession::isActive() {
return mDescriptor->is_active.load();
}
-bool PowerHintSession::isStale() {
+bool PowerHintSession::isTimeout() {
auto now = std::chrono::steady_clock::now();
- return now >= mHintTimerHandler->getStaleTime();
+ return now >= getStaleTime();
}
const std::vector<int> &PowerHintSession::getTidList() const {
@@ -381,26 +403,29 @@ void PowerHintSession::setStale() {
PowerSessionManager::getInstance()->setUclampMin(this, 0);
// Deliver a task to check if all sessions are inactive.
updateUniveralBoostMode();
+ if (ATRACE_ENABLED()) {
+ const std::string idstr = getIdString();
+ std::string sz = StringPrintf("adpf.%s-min", idstr.c_str());
+ ATRACE_INT(sz.c_str(), 0);
+ }
}
void PowerHintSession::wakeup() {
std::lock_guard<std::mutex> guard(mSessionLock);
// We only wake up non-paused and stale sessions
- if (mSessionClosed || !isActive() || !isStale())
+ if (mSessionClosed || !isActive() || !isTimeout())
return;
if (ATRACE_ENABLED()) {
- std::string tag =
- StringPrintf("wakeup.%s(a:%d,s:%d)", getIdString().c_str(), isActive(), isStale());
+ std::string tag = StringPrintf("wakeup.%s(a:%d,s:%d)", getIdString().c_str(), isActive(),
+ isTimeout());
ATRACE_NAME(tag.c_str());
}
std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
int min = std::max(mDescriptor->current_min, static_cast<int>(adpfConfig->mUclampMinInit));
mDescriptor->current_min = min;
PowerSessionManager::getInstance()->setUclampMinLocked(this, min);
- PowerHintMonitor::getInstance()->getLooper()->removeMessages(mHintTimerHandler);
- PowerHintMonitor::getInstance()->getLooper()->sendMessage(
- mHintTimerHandler, Message(static_cast<int>(HintTimerHandler::POKE)));
+ mStaleTimerHandler->updateTimer();
if (ATRACE_ENABLED()) {
const std::string idstr = getIdString();
@@ -409,147 +434,158 @@ void PowerHintSession::wakeup() {
}
}
-void PowerHintSession::HintTimerHandler::updateHintTimer(int64_t actualDurationNs) {
- std::lock_guard<std::mutex> guard(mStaleLock);
- PowerHintSession::HintTimerHandler::updateHintTimerLocked(actualDurationNs);
-}
-
-void PowerHintSession::HintTimerHandler::updateHintTimerLocked(int64_t actualDurationNs) {
- std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
- HintTimerState prevState = mState;
- mState = MONITORING;
- auto now = std::chrono::steady_clock::now();
- mLastUpdatedTime.store(now);
- nanoseconds nextStartDur = nanoseconds((mSession->mDescriptor->work_period
- ? mSession->mDescriptor->work_period
- : mSession->mDescriptor->duration.count()) -
- actualDurationNs);
- mNextStartTime.store(actualDurationNs <= 0 ? now : now + nextStartDur);
- if (prevState != MONITORING) {
- int64_t next =
- static_cast<int64_t>(duration_cast<nanoseconds>(getEarlyBoostTime() - now).count());
- PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mHintTimerHandler);
- PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed(
- next, mSession->mHintTimerHandler, NULL);
- if (prevState == STALE) {
- mSession->updateUniveralBoostMode();
- }
- }
- if (ATRACE_ENABLED()) {
- const std::string idstr = mSession->getIdString();
- std::string sz = StringPrintf("adpf.%s-timer.state", idstr.c_str());
- ATRACE_INT(sz.c_str(), mState);
- sz = StringPrintf("adpf.%s-timer.nextvsync", idstr.c_str());
- ATRACE_INT(sz.c_str(), nextStartDur.count());
- sz = StringPrintf("adpf.%s-timer.nexthint", idstr.c_str());
- ATRACE_INT(sz.c_str(),
- (int64_t)(nextStartDur.count() + mSession->mDescriptor->duration.count() *
- adpfConfig->mEarlyBoostTimeFactor));
- }
-}
-
-void PowerHintSession::HintTimerHandler::updateHintTimer(
- const std::vector<WorkDuration> &actualDurations) {
+void PowerHintSession::updateWorkPeriod(const std::vector<WorkDuration> &actualDurations) {
if (actualDurations.size() == 0)
return;
if (actualDurations.size() >= 2) {
const WorkDuration &last = actualDurations[actualDurations.size() - 2];
- mSession->mDescriptor->last_start = last.timeStampNanos - last.durationNanos;
+ mLastStartedTimeNs = last.timeStampNanos - last.durationNanos;
}
const WorkDuration &current = actualDurations.back();
int64_t curr_start = current.timeStampNanos - current.durationNanos;
- if (!mSession->mDescriptor->last_start) {
- mSession->mDescriptor->last_start = curr_start;
- updateHintTimer(current.durationNanos);
- return;
- }
- int64_t period = curr_start - mSession->mDescriptor->last_start;
- mSession->mDescriptor->last_start = curr_start;
- if (period > 0 && period < mSession->mDescriptor->duration.count() * 2) {
+ int64_t period = mDescriptor->duration.count();
+ period = curr_start - mLastStartedTimeNs;
+ if (period > 0 && period < mDescriptor->duration.count() * 2) {
// Accounting workload period with moving average for the last 10 workload.
- mSession->mDescriptor->work_period =
- 0.9 * mSession->mDescriptor->work_period + 0.1 * period;
+ mWorkPeriodNs = 0.9 * mWorkPeriodNs + 0.1 * period;
if (ATRACE_ENABLED()) {
- const std::string idstr = mSession->getIdString();
+ const std::string idstr = getIdString();
std::string sz = StringPrintf("adpf.%s-timer.period", idstr.c_str());
- ATRACE_INT(sz.c_str(), period);
+ ATRACE_INT(sz.c_str(), mWorkPeriodNs);
}
}
- updateHintTimer(current.durationNanos);
+ mLastStartedTimeNs = curr_start;
+ mLastDurationNs = current.durationNanos;
}
-time_point<steady_clock> PowerHintSession::HintTimerHandler::getEarlyBoostTime() {
+time_point<steady_clock> PowerHintSession::getEarlyBoostTime() {
std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
- if (!adpfConfig->mEarlyBoostOn) {
- return getStaleTime();
- }
int64_t earlyBoostTimeoutNs =
- (int64_t)mSession->mDescriptor->duration.count() * adpfConfig->mEarlyBoostTimeFactor;
- return mNextStartTime.load() + nanoseconds(earlyBoostTimeoutNs);
+ (int64_t)mDescriptor->duration.count() * adpfConfig->mEarlyBoostTimeFactor;
+ time_point<steady_clock> nextStartTime =
+ mLastUpdatedTime.load() + nanoseconds(mWorkPeriodNs - mLastDurationNs);
+ return nextStartTime + nanoseconds(earlyBoostTimeoutNs);
}
-time_point<steady_clock> PowerHintSession::HintTimerHandler::getStaleTime() {
+time_point<steady_clock> PowerHintSession::getStaleTime() {
return mLastUpdatedTime.load() +
nanoseconds(static_cast<int64_t>(
- mSession->mDescriptor->duration.count() *
+ mDescriptor->duration.count() *
HintManager::GetInstance()->GetAdpfProfile()->mStaleTimeFactor));
}
-PowerHintSession::HintTimerHandler::~HintTimerHandler() {
- ATRACE_CALL();
+void PowerHintSession::StaleTimerHandler::updateTimer() {
+ time_point<steady_clock> staleTime =
+ std::chrono::steady_clock::now() +
+ nanoseconds(static_cast<int64_t>(
+ mSession->mDescriptor->duration.count() *
+ HintManager::GetInstance()->GetAdpfProfile()->mStaleTimeFactor));
+ updateTimer(staleTime);
}
-void PowerHintSession::HintTimerHandler::handleMessage(const Message &msg) {
- std::lock_guard<std::mutex> guard(mStaleLock);
- if (mIsSessionDead) {
- return;
+void PowerHintSession::StaleTimerHandler::updateTimer(time_point<steady_clock> staleTime) {
+ mStaleTime.store(staleTime);
+ {
+ std::lock_guard<std::mutex> guard(mMessageLock);
+ PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mStaleTimerHandler);
+ PowerHintMonitor::getInstance()->getLooper()->sendMessage(mSession->mStaleTimerHandler,
+ NULL);
}
- if (msg.what == POKE) {
- updateHintTimerLocked(0);
+ mIsMonitoring.store(true);
+ if (ATRACE_ENABLED()) {
+ const std::string idstr = mSession->getIdString();
+ std::string sz = StringPrintf("adpf.%s-timer.stale", idstr.c_str());
+ ATRACE_INT(sz.c_str(), 0);
+ }
+}
+
+void PowerHintSession::StaleTimerHandler::handleMessage(const Message &) {
+ if (mIsSessionDead) {
return;
}
- std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
auto now = std::chrono::steady_clock::now();
- auto staleTime = getStaleTime();
- auto earlyBoostTime = getEarlyBoostTime();
- if (adpfConfig->mEarlyBoostOn && now < earlyBoostTime) {
- int64_t next =
- static_cast<int64_t>(duration_cast<nanoseconds>(earlyBoostTime - now).count());
- mState = MONITORING;
- // Schedule for the early hint check.
- PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mHintTimerHandler);
+ int64_t next =
+ static_cast<int64_t>(duration_cast<nanoseconds>(mStaleTime.load() - now).count());
+ if (next > 0) {
+ // Schedule for the stale timeout check.
+ std::lock_guard<std::mutex> guard(mMessageLock);
+ PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mStaleTimerHandler);
PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed(
- next, mSession->mHintTimerHandler, static_cast<int>(HintTimerHandler::TIMER));
+ next, mSession->mStaleTimerHandler, NULL);
+ } else {
+ mSession->setStale();
+ mIsMonitoring.store(false);
if (ATRACE_ENABLED()) {
const std::string idstr = mSession->getIdString();
- std::string sz = StringPrintf("adpf.%s-timer.nexthint", idstr.c_str());
- ATRACE_INT(sz.c_str(), next);
- }
- } else if (now >= staleTime) { // Check if the session is stale.
- mSession->setStale();
- mState = STALE;
- } else { // Check if it's time to do early boost.
- if (adpfConfig->mEarlyBoostOn) {
- mState = EARLY_BOOST;
- mSession->setSessionUclampMin(adpfConfig->mUclampMinHigh);
+ std::string sz = StringPrintf("adpf.%s-timer.earlyboost", idstr.c_str());
+ ATRACE_INT(sz.c_str(), 0);
}
- int64_t next = static_cast<int64_t>(duration_cast<nanoseconds>(staleTime - now).count());
- // Schedule for the stale timeout check.
- PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mHintTimerHandler);
- PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed(
- next, mSession->mHintTimerHandler, static_cast<int>(HintTimerHandler::TIMER));
}
if (ATRACE_ENABLED()) {
const std::string idstr = mSession->getIdString();
- std::string sz = StringPrintf("adpf.%s-timer.state", idstr.c_str());
- ATRACE_INT(sz.c_str(), mState);
+ std::string sz = StringPrintf("adpf.%s-timer.stale", idstr.c_str());
+ ATRACE_INT(sz.c_str(), mIsMonitoring ? 0 : 1);
}
}
-void PowerHintSession::HintTimerHandler::setSessionDead() {
+void PowerHintSession::StaleTimerHandler::setSessionDead() {
std::lock_guard<std::mutex> guard(mStaleLock);
- PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mHintTimerHandler);
mIsSessionDead = true;
+ PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mStaleTimerHandler);
+}
+
+void PowerHintSession::EarlyBoostHandler::updateTimer(time_point<steady_clock> boostTime) {
+ mBoostTime.store(boostTime);
+ {
+ std::lock_guard<std::mutex> guard(mMessageLock);
+ PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mEarlyBoostHandler);
+ PowerHintMonitor::getInstance()->getLooper()->sendMessage(mSession->mEarlyBoostHandler,
+ NULL);
+ }
+ mIsMonitoring.store(true);
+ if (ATRACE_ENABLED()) {
+ const std::string idstr = mSession->getIdString();
+ std::string sz = StringPrintf("adpf.%s-timer.earlyboost", idstr.c_str());
+ ATRACE_INT(sz.c_str(), 1);
+ }
+}
+
+void PowerHintSession::EarlyBoostHandler::handleMessage(const Message &) {
+ std::lock_guard<std::mutex> guard(mBoostLock);
+ if (mIsSessionDead) {
+ return;
+ }
+ auto now = std::chrono::steady_clock::now();
+ int64_t next =
+ static_cast<int64_t>(duration_cast<nanoseconds>(mBoostTime.load() - now).count());
+ if (next > 0) {
+ if (ATRACE_ENABLED()) {
+ const std::string idstr = mSession->getIdString();
+ std::string sz = StringPrintf("adpf.%s-timer.earlyboost", idstr.c_str());
+ ATRACE_INT(sz.c_str(), 1);
+ }
+ std::lock_guard<std::mutex> guard(mMessageLock);
+ PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mEarlyBoostHandler);
+ PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed(
+ next, mSession->mEarlyBoostHandler, NULL);
+ } else {
+ std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
+ PowerSessionManager::getInstance()->setUclampMin(mSession, adpfConfig->mUclampMinHigh);
+ mIsMonitoring.store(false);
+ if (ATRACE_ENABLED()) {
+ const std::string idstr = mSession->getIdString();
+ std::string sz = StringPrintf("adpf.%s-min", idstr.c_str());
+ ATRACE_INT(sz.c_str(), adpfConfig->mUclampMinHigh);
+ sz = StringPrintf("adpf.%s-timer.earlyboost", idstr.c_str());
+ ATRACE_INT(sz.c_str(), 2);
+ }
+ }
+}
+
+void PowerHintSession::EarlyBoostHandler::setSessionDead() {
+ std::lock_guard<std::mutex> guard(mBoostLock);
+ mIsSessionDead = true;
+ PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mEarlyBoostHandler);
}
} // namespace pixel