forked from donjohanliebert/hardware_xiaomi
power: Fix uclamp_min stuck at high freq
Separate Stale and EarlyBoost handlers and refine the code. Test: adb shell dumpsys android.hardware.power.IPower/default Test: Manual Bug: 232992641 Change-Id: I81a4fd96fb7311ae5bbb7cbabe72378c9cad4aa3
This commit is contained in:
parent
4ad8e47249
commit
43c9b76b8a
@ -125,8 +125,16 @@ PowerHintSession::PowerHintSession(int32_t tgid, int32_t uid, const std::vector<
|
||||
int64_t durationNanos) {
|
||||
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();
|
||||
@ -137,7 +145,7 @@ PowerHintSession::PowerHintSession(int32_t tgid, int32_t uid, const std::vector<
|
||||
}
|
||||
PowerSessionManager::getInstance()->addPowerSession(this);
|
||||
// init boost
|
||||
setSessionUclampMin(HintManager::GetInstance()->GetAdpfProfile()->mUclampMinInit);
|
||||
wakeup();
|
||||
ALOGV("PowerHintSession created: %s", mDescriptor->toString().c_str());
|
||||
}
|
||||
|
||||
@ -157,7 +165,6 @@ PowerHintSession::~PowerHintSession() {
|
||||
std::lock_guard<std::mutex> guard(mSessionLock);
|
||||
mSessionClosed.store(true);
|
||||
}
|
||||
mHintTimerHandler->setSessionDead();
|
||||
delete mDescriptor;
|
||||
}
|
||||
|
||||
@ -191,7 +198,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());
|
||||
@ -205,10 +216,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() {
|
||||
@ -238,7 +249,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()) {
|
||||
@ -255,6 +265,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();
|
||||
@ -304,6 +317,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());
|
||||
@ -319,7 +333,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);
|
||||
@ -334,6 +351,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());
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
@ -363,9 +385,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 {
|
||||
@ -377,26 +399,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();
|
||||
@ -405,147 +430,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 ¤t = 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);
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (msg.what == POKE) {
|
||||
updateHintTimerLocked(0);
|
||||
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);
|
||||
std::string sz = StringPrintf("adpf.%s-timer.earlyboost", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), 0);
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
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
|
||||
|
@ -51,9 +51,7 @@ struct AppHintDesc {
|
||||
is_active(true),
|
||||
update_count(0),
|
||||
integral_error(0),
|
||||
previous_error(0),
|
||||
work_period(0),
|
||||
last_start(0) {}
|
||||
previous_error(0) {}
|
||||
std::string toString() const;
|
||||
const int32_t tgid;
|
||||
const int32_t uid;
|
||||
@ -66,9 +64,6 @@ struct AppHintDesc {
|
||||
uint64_t update_count;
|
||||
int64_t integral_error;
|
||||
int64_t previous_error;
|
||||
// earlyhint pace
|
||||
int64_t work_period;
|
||||
int64_t last_start;
|
||||
};
|
||||
|
||||
class PowerHintSession : public BnPowerHintSession {
|
||||
@ -83,7 +78,7 @@ class PowerHintSession : public BnPowerHintSession {
|
||||
ndk::ScopedAStatus reportActualWorkDuration(
|
||||
const std::vector<WorkDuration> &actualDurations) override;
|
||||
bool isActive();
|
||||
bool isStale();
|
||||
bool isTimeout();
|
||||
void wakeup();
|
||||
void setStale();
|
||||
// Is this hint session for a user application
|
||||
@ -92,41 +87,42 @@ class PowerHintSession : public BnPowerHintSession {
|
||||
int getUclampMin();
|
||||
void dumpToStream(std::ostream &stream);
|
||||
|
||||
void updateWorkPeriod(const std::vector<WorkDuration> &actualDurations);
|
||||
time_point<steady_clock> getEarlyBoostTime();
|
||||
time_point<steady_clock> getStaleTime();
|
||||
|
||||
private:
|
||||
class HintTimerHandler : public MessageHandler {
|
||||
class StaleTimerHandler : public MessageHandler {
|
||||
public:
|
||||
enum MsgType {
|
||||
TIMER = 0,
|
||||
POKE,
|
||||
};
|
||||
enum HintTimerState {
|
||||
STALE,
|
||||
MONITORING,
|
||||
EARLY_BOOST,
|
||||
};
|
||||
HintTimerHandler(PowerHintSession *session)
|
||||
: mSession(session),
|
||||
mState(STALE),
|
||||
mLastUpdatedTime(steady_clock::now()),
|
||||
mIsSessionDead(false) {}
|
||||
~HintTimerHandler();
|
||||
StaleTimerHandler(PowerHintSession *session)
|
||||
: mSession(session), mIsMonitoring(false), mIsSessionDead(false) {}
|
||||
void updateTimer();
|
||||
void updateTimer(time_point<steady_clock> staleTime);
|
||||
void handleMessage(const Message &message) override;
|
||||
// Update HintTimer by actual work duration.
|
||||
void updateHintTimer(int64_t actualDurationNs);
|
||||
void updateHintTimerLocked(int64_t actualDurationNs);
|
||||
// Update HintTimer by a list of work durations which could be used for
|
||||
// calculating the work period.
|
||||
void updateHintTimer(const std::vector<WorkDuration> &actualDurations);
|
||||
time_point<steady_clock> getEarlyBoostTime();
|
||||
time_point<steady_clock> getStaleTime();
|
||||
void setSessionDead();
|
||||
|
||||
private:
|
||||
PowerHintSession *mSession;
|
||||
HintTimerState mState;
|
||||
std::atomic<time_point<steady_clock>> mLastUpdatedTime;
|
||||
std::atomic<time_point<steady_clock>> mNextStartTime;
|
||||
std::mutex mStaleLock;
|
||||
std::mutex mMessageLock;
|
||||
std::atomic<time_point<steady_clock>> mStaleTime;
|
||||
std::atomic<bool> mIsMonitoring;
|
||||
bool mIsSessionDead;
|
||||
};
|
||||
|
||||
class EarlyBoostHandler : public MessageHandler {
|
||||
public:
|
||||
EarlyBoostHandler(PowerHintSession *session) : mSession(session) {}
|
||||
void updateTimer(time_point<steady_clock> boostTime);
|
||||
void handleMessage(const Message &message) override;
|
||||
void setSessionDead();
|
||||
|
||||
private:
|
||||
PowerHintSession *mSession;
|
||||
std::mutex mBoostLock;
|
||||
std::mutex mMessageLock;
|
||||
std::atomic<time_point<steady_clock>> mBoostTime;
|
||||
std::atomic<bool> mIsMonitoring;
|
||||
bool mIsSessionDead;
|
||||
};
|
||||
|
||||
@ -135,10 +131,16 @@ class PowerHintSession : public BnPowerHintSession {
|
||||
int setSessionUclampMin(int32_t min);
|
||||
std::string getIdString() const;
|
||||
AppHintDesc *mDescriptor = nullptr;
|
||||
sp<HintTimerHandler> mHintTimerHandler;
|
||||
sp<StaleTimerHandler> mStaleTimerHandler;
|
||||
sp<EarlyBoostHandler> mEarlyBoostHandler;
|
||||
std::atomic<time_point<steady_clock>> mLastUpdatedTime;
|
||||
sp<MessageHandler> mPowerManagerHandler;
|
||||
std::mutex mSessionLock;
|
||||
std::atomic<bool> mSessionClosed = false;
|
||||
// These 3 variables are for earlyboost work period estimation.
|
||||
int64_t mLastStartedTimeNs;
|
||||
int64_t mLastDurationNs;
|
||||
int64_t mWorkPeriodNs;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
|
@ -162,12 +162,11 @@ void PowerSessionManager::setUclampMinLocked(PowerHintSession *session, int val)
|
||||
// Get thex max uclamp.min across sessions which include the tid.
|
||||
int tidMax = 0;
|
||||
for (PowerHintSession *s : mTidSessionListMap[t]) {
|
||||
if (!s->isActive() || s->isStale())
|
||||
if (!s->isActive() || s->isTimeout())
|
||||
continue;
|
||||
tidMax = std::max(tidMax, s->getUclampMin());
|
||||
}
|
||||
val = std::max(val, tidMax);
|
||||
set_uclamp_min(t, val);
|
||||
set_uclamp_min(t, std::max(val, tidMax));
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,7 +175,7 @@ std::optional<bool> PowerSessionManager::isAnyAppSessionActive() {
|
||||
bool active = false;
|
||||
for (PowerHintSession *s : mSessions) {
|
||||
// session active and not stale is actually active.
|
||||
if (s->isActive() && !s->isStale() && s->isAppSession()) {
|
||||
if (s->isActive() && !s->isTimeout() && s->isAppSession()) {
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user