sm6375-common: power-libperfmgr: ADPF: uclamp.min integration
Integrate the uclamp.min across sessions. Add UClampMininit as the display update boost Bug: 232313238 Test: Manual test Change-Id: I601f407b0b5383a1e39eac448d45cbaaeb7788fb
This commit is contained in:
parent
a4f9f7f383
commit
0ddf7227e4
6 changed files with 160 additions and 75 deletions
|
@ -137,6 +137,7 @@ ndk::ScopedAStatus Power::isModeSupported(Mode type, bool *_aidl_return) {
|
||||||
|
|
||||||
ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
|
ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
|
||||||
LOG(DEBUG) << "Power setBoost: " << toString(type) << " duration: " << durationMs;
|
LOG(DEBUG) << "Power setBoost: " << toString(type) << " duration: " << durationMs;
|
||||||
|
PowerSessionManager::getInstance()->updateHintBoost(toString(type), durationMs);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Boost::INTERACTION:
|
case Boost::INTERACTION:
|
||||||
if (mSustainedPerfModeOn) {
|
if (mSustainedPerfModeOn) {
|
||||||
|
|
|
@ -61,6 +61,7 @@ ndk::ScopedAStatus PowerExt::isModeSupported(const std::string &mode, bool *_aid
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerExt::setBoost(const std::string &boost, int32_t durationMs) {
|
ndk::ScopedAStatus PowerExt::setBoost(const std::string &boost, int32_t durationMs) {
|
||||||
LOG(DEBUG) << "PowerExt setBoost: " << boost << " duration: " << durationMs;
|
LOG(DEBUG) << "PowerExt setBoost: " << boost << " duration: " << durationMs;
|
||||||
|
PowerSessionManager::getInstance()->updateHintBoost(boost, durationMs);
|
||||||
|
|
||||||
if (durationMs > 0) {
|
if (durationMs > 0) {
|
||||||
HintManager::GetInstance()->DoHint(boost, std::chrono::milliseconds(durationMs));
|
HintManager::GetInstance()->DoHint(boost, std::chrono::milliseconds(durationMs));
|
||||||
|
|
|
@ -47,27 +47,6 @@ using std::chrono::duration_cast;
|
||||||
using std::chrono::nanoseconds;
|
using std::chrono::nanoseconds;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/* there is no glibc or bionic wrapper */
|
|
||||||
struct sched_attr {
|
|
||||||
__u32 size;
|
|
||||||
__u32 sched_policy;
|
|
||||||
__u64 sched_flags;
|
|
||||||
__s32 sched_nice;
|
|
||||||
__u32 sched_priority;
|
|
||||||
__u64 sched_runtime;
|
|
||||||
__u64 sched_deadline;
|
|
||||||
__u64 sched_period;
|
|
||||||
__u32 sched_util_min;
|
|
||||||
__u32 sched_util_max;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int sched_setattr(int pid, struct sched_attr *attr, unsigned int flags) {
|
|
||||||
if (!HintManager::GetInstance()->GetAdpfProfile()->mUclampMinOn) {
|
|
||||||
ALOGV("PowerHintSession:%s: skip", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return syscall(__NR_sched_setattr, pid, attr, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int64_t ns_to_100us(int64_t ns) {
|
static inline int64_t ns_to_100us(int64_t ns) {
|
||||||
return ns / 100000;
|
return ns / 100000;
|
||||||
|
@ -158,7 +137,7 @@ PowerHintSession::PowerHintSession(int32_t tgid, int32_t uid, const std::vector<
|
||||||
}
|
}
|
||||||
PowerSessionManager::getInstance()->addPowerSession(this);
|
PowerSessionManager::getInstance()->addPowerSession(this);
|
||||||
// init boost
|
// init boost
|
||||||
setUclamp(HintManager::GetInstance()->GetAdpfProfile()->mUclampMinHigh);
|
setSessionUclampMin(HintManager::GetInstance()->GetAdpfProfile()->mUclampMinInit);
|
||||||
ALOGV("PowerHintSession created: %s", mDescriptor->toString().c_str());
|
ALOGV("PowerHintSession created: %s", mDescriptor->toString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,35 +182,24 @@ void PowerHintSession::updateUniveralBoostMode() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int PowerHintSession::setUclamp(int32_t min, bool update) {
|
int PowerHintSession::setSessionUclampMin(int32_t min) {
|
||||||
std::lock_guard<std::mutex> guard(mLock);
|
{
|
||||||
min = std::max(0, min);
|
std::lock_guard<std::mutex> guard(mSessionLock);
|
||||||
min = std::min(min, kMaxUclampValue);
|
mDescriptor->current_min = min;
|
||||||
|
}
|
||||||
|
PowerSessionManager::getInstance()->setUclampMin(this, min);
|
||||||
if (ATRACE_ENABLED()) {
|
if (ATRACE_ENABLED()) {
|
||||||
const std::string idstr = getIdString();
|
const std::string idstr = getIdString();
|
||||||
std::string sz = StringPrintf("adpf.%s-min", idstr.c_str());
|
std::string sz = StringPrintf("adpf.%s-min", idstr.c_str());
|
||||||
ATRACE_INT(sz.c_str(), min);
|
ATRACE_INT(sz.c_str(), min);
|
||||||
}
|
}
|
||||||
for (const auto tid : mDescriptor->threadIds) {
|
|
||||||
sched_attr attr = {};
|
|
||||||
attr.size = sizeof(attr);
|
|
||||||
|
|
||||||
attr.sched_flags = (SCHED_FLAG_KEEP_ALL | SCHED_FLAG_UTIL_CLAMP);
|
|
||||||
attr.sched_util_min = min;
|
|
||||||
attr.sched_util_max = kMaxUclampValue;
|
|
||||||
|
|
||||||
int ret = sched_setattr(tid, &attr, 0);
|
|
||||||
if (ret) {
|
|
||||||
ALOGW("sched_setattr failed for thread %d, err=%d", tid, errno);
|
|
||||||
}
|
|
||||||
ALOGV("PowerHintSession tid: %d, uclamp(%d, %d)", tid, min, kMaxUclampValue);
|
|
||||||
}
|
|
||||||
if (update) {
|
|
||||||
mDescriptor->current_min = min;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PowerHintSession::getUclampMin() {
|
||||||
|
return mDescriptor->current_min;
|
||||||
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerHintSession::pause() {
|
ndk::ScopedAStatus PowerHintSession::pause() {
|
||||||
if (mSessionClosed) {
|
if (mSessionClosed) {
|
||||||
ALOGE("Error: session is dead");
|
ALOGE("Error: session is dead");
|
||||||
|
@ -240,8 +208,8 @@ ndk::ScopedAStatus PowerHintSession::pause() {
|
||||||
if (!mDescriptor->is_active.load())
|
if (!mDescriptor->is_active.load())
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
||||||
// Reset to default uclamp value.
|
// Reset to default uclamp value.
|
||||||
setUclamp(0, false);
|
|
||||||
mDescriptor->is_active.store(false);
|
mDescriptor->is_active.store(false);
|
||||||
|
setStale();
|
||||||
if (ATRACE_ENABLED()) {
|
if (ATRACE_ENABLED()) {
|
||||||
const std::string idstr = getIdString();
|
const std::string idstr = getIdString();
|
||||||
std::string sz = StringPrintf("adpf.%s-active", idstr.c_str());
|
std::string sz = StringPrintf("adpf.%s-active", idstr.c_str());
|
||||||
|
@ -261,7 +229,7 @@ ndk::ScopedAStatus PowerHintSession::resume() {
|
||||||
mDescriptor->is_active.store(true);
|
mDescriptor->is_active.store(true);
|
||||||
mHintTimerHandler->updateHintTimer(0);
|
mHintTimerHandler->updateHintTimer(0);
|
||||||
// resume boost
|
// resume boost
|
||||||
setUclamp(mDescriptor->current_min, false);
|
setSessionUclampMin(mDescriptor->current_min);
|
||||||
if (ATRACE_ENABLED()) {
|
if (ATRACE_ENABLED()) {
|
||||||
const std::string idstr = getIdString();
|
const std::string idstr = getIdString();
|
||||||
std::string sz = StringPrintf("adpf.%s-active", idstr.c_str());
|
std::string sz = StringPrintf("adpf.%s-active", idstr.c_str());
|
||||||
|
@ -276,7 +244,7 @@ ndk::ScopedAStatus PowerHintSession::close() {
|
||||||
if (!mSessionClosed.compare_exchange_strong(sessionClosedExpectedToBe, true)) {
|
if (!mSessionClosed.compare_exchange_strong(sessionClosedExpectedToBe, true)) {
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
|
||||||
}
|
}
|
||||||
setUclamp(0);
|
setSessionUclampMin(0);
|
||||||
PowerSessionManager::getInstance()->removePowerSession(this);
|
PowerSessionManager::getInstance()->removePowerSession(this);
|
||||||
updateUniveralBoostMode();
|
updateUniveralBoostMode();
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
|
@ -340,21 +308,10 @@ ndk::ScopedAStatus PowerHintSession::reportActualWorkDuration(
|
||||||
actualDurations.back().durationNanos - mDescriptor->duration.count() > 0);
|
actualDurations.back().durationNanos - mDescriptor->duration.count() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PowerHintMonitor::getInstance()->isRunning() && isStale()) {
|
|
||||||
mDescriptor->integral_error =
|
|
||||||
std::max(adpfConfig->getPidIInitDivI(), mDescriptor->integral_error);
|
|
||||||
if (ATRACE_ENABLED()) {
|
|
||||||
const std::string idstr = getIdString();
|
|
||||||
std::string sz = StringPrintf("adpf.%s-wakeup", idstr.c_str());
|
|
||||||
ATRACE_INT(sz.c_str(), mDescriptor->integral_error);
|
|
||||||
ATRACE_INT(sz.c_str(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mHintTimerHandler->updateHintTimer(actualDurations);
|
mHintTimerHandler->updateHintTimer(actualDurations);
|
||||||
|
|
||||||
if (!adpfConfig->mPidOn) {
|
if (!adpfConfig->mPidOn) {
|
||||||
setUclamp(adpfConfig->mUclampMinHigh);
|
setSessionUclampMin(adpfConfig->mUclampMinHigh);
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
int64_t output = convertWorkDurationToBoostByPid(
|
int64_t output = convertWorkDurationToBoostByPid(
|
||||||
|
@ -365,7 +322,7 @@ ndk::ScopedAStatus PowerHintSession::reportActualWorkDuration(
|
||||||
int next_min = std::min(static_cast<int>(adpfConfig->mUclampMinHigh),
|
int next_min = std::min(static_cast<int>(adpfConfig->mUclampMinHigh),
|
||||||
mDescriptor->current_min + static_cast<int>(output));
|
mDescriptor->current_min + static_cast<int>(output));
|
||||||
next_min = std::max(static_cast<int>(adpfConfig->mUclampMinLow), next_min);
|
next_min = std::max(static_cast<int>(adpfConfig->mUclampMinLow), next_min);
|
||||||
setUclamp(next_min);
|
setSessionUclampMin(next_min);
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
@ -406,13 +363,44 @@ const std::vector<int> &PowerHintSession::getTidList() const {
|
||||||
|
|
||||||
void PowerHintSession::setStale() {
|
void PowerHintSession::setStale() {
|
||||||
// Reset to default uclamp value.
|
// Reset to default uclamp value.
|
||||||
setUclamp(0, false);
|
PowerSessionManager::getInstance()->setUclampMin(this, 0);
|
||||||
// Deliver a task to check if all sessions are inactive.
|
// Deliver a task to check if all sessions are inactive.
|
||||||
updateUniveralBoostMode();
|
updateUniveralBoostMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PowerHintSession::wakeup() {
|
||||||
|
if (ATRACE_ENABLED()) {
|
||||||
|
std::string tag =
|
||||||
|
StringPrintf("wakeup.%s(a:%d,s:%d)", getIdString().c_str(), isActive(), isStale());
|
||||||
|
ATRACE_NAME(tag.c_str());
|
||||||
|
}
|
||||||
|
// We only wake up non-paused and stale sessions
|
||||||
|
if (!isActive() || !isStale())
|
||||||
|
return;
|
||||||
|
std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
|
||||||
|
int min = std::max(mDescriptor->current_min, static_cast<int>(adpfConfig->mUclampMinInit));
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(mSessionLock);
|
||||||
|
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)));
|
||||||
|
|
||||||
|
if (ATRACE_ENABLED()) {
|
||||||
|
const std::string idstr = getIdString();
|
||||||
|
std::string sz = StringPrintf("adpf.%s-min", idstr.c_str());
|
||||||
|
ATRACE_INT(sz.c_str(), min);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PowerHintSession::HintTimerHandler::updateHintTimer(int64_t actualDurationNs) {
|
void PowerHintSession::HintTimerHandler::updateHintTimer(int64_t actualDurationNs) {
|
||||||
std::lock_guard<std::mutex> guard(mStaleLock);
|
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();
|
std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
|
||||||
HintTimerState prevState = mState;
|
HintTimerState prevState = mState;
|
||||||
mState = MONITORING;
|
mState = MONITORING;
|
||||||
|
@ -422,7 +410,7 @@ void PowerHintSession::HintTimerHandler::updateHintTimer(int64_t actualDurationN
|
||||||
? mSession->mDescriptor->work_period
|
? mSession->mDescriptor->work_period
|
||||||
: mSession->mDescriptor->duration.count()) -
|
: mSession->mDescriptor->duration.count()) -
|
||||||
actualDurationNs);
|
actualDurationNs);
|
||||||
mNextStartTime.store(now + nextStartDur);
|
mNextStartTime.store(actualDurationNs <= 0 ? now : now + nextStartDur);
|
||||||
if (prevState != MONITORING) {
|
if (prevState != MONITORING) {
|
||||||
int64_t next =
|
int64_t next =
|
||||||
static_cast<int64_t>(duration_cast<nanoseconds>(getEarlyBoostTime() - now).count());
|
static_cast<int64_t>(duration_cast<nanoseconds>(getEarlyBoostTime() - now).count());
|
||||||
|
@ -497,11 +485,15 @@ PowerHintSession::HintTimerHandler::~HintTimerHandler() {
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerHintSession::HintTimerHandler::handleMessage(const Message &) {
|
void PowerHintSession::HintTimerHandler::handleMessage(const Message &msg) {
|
||||||
std::lock_guard<std::mutex> guard(mStaleLock);
|
std::lock_guard<std::mutex> guard(mStaleLock);
|
||||||
if (mIsSessionDead) {
|
if (mIsSessionDead) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (msg.what == POKE) {
|
||||||
|
updateHintTimerLocked(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
|
std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
|
||||||
auto now = std::chrono::steady_clock::now();
|
auto now = std::chrono::steady_clock::now();
|
||||||
auto staleTime = getStaleTime();
|
auto staleTime = getStaleTime();
|
||||||
|
@ -513,7 +505,7 @@ void PowerHintSession::HintTimerHandler::handleMessage(const Message &) {
|
||||||
// Schedule for the early hint check.
|
// Schedule for the early hint check.
|
||||||
PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mHintTimerHandler);
|
PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mHintTimerHandler);
|
||||||
PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed(
|
PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed(
|
||||||
next, mSession->mHintTimerHandler, NULL);
|
next, mSession->mHintTimerHandler, static_cast<int>(HintTimerHandler::TIMER));
|
||||||
if (ATRACE_ENABLED()) {
|
if (ATRACE_ENABLED()) {
|
||||||
const std::string idstr = mSession->getIdString();
|
const std::string idstr = mSession->getIdString();
|
||||||
std::string sz = StringPrintf("adpf.%s-timer.nexthint", idstr.c_str());
|
std::string sz = StringPrintf("adpf.%s-timer.nexthint", idstr.c_str());
|
||||||
|
@ -525,13 +517,13 @@ void PowerHintSession::HintTimerHandler::handleMessage(const Message &) {
|
||||||
} else { // Check if it's time to do early boost.
|
} else { // Check if it's time to do early boost.
|
||||||
if (adpfConfig->mEarlyBoostOn) {
|
if (adpfConfig->mEarlyBoostOn) {
|
||||||
mState = EARLY_BOOST;
|
mState = EARLY_BOOST;
|
||||||
mSession->setUclamp(adpfConfig->mUclampMinHigh);
|
mSession->setSessionUclampMin(adpfConfig->mUclampMinHigh);
|
||||||
}
|
}
|
||||||
int64_t next = static_cast<int64_t>(duration_cast<nanoseconds>(staleTime - now).count());
|
int64_t next = static_cast<int64_t>(duration_cast<nanoseconds>(staleTime - now).count());
|
||||||
// Schedule for the stale timeout check.
|
// Schedule for the stale timeout check.
|
||||||
PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mHintTimerHandler);
|
PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mHintTimerHandler);
|
||||||
PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed(
|
PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed(
|
||||||
next, mSession->mHintTimerHandler, NULL);
|
next, mSession->mHintTimerHandler, static_cast<int>(HintTimerHandler::TIMER));
|
||||||
}
|
}
|
||||||
if (ATRACE_ENABLED()) {
|
if (ATRACE_ENABLED()) {
|
||||||
const std::string idstr = mSession->getIdString();
|
const std::string idstr = mSession->getIdString();
|
||||||
|
|
|
@ -41,7 +41,6 @@ using std::chrono::nanoseconds;
|
||||||
using std::chrono::steady_clock;
|
using std::chrono::steady_clock;
|
||||||
using std::chrono::time_point;
|
using std::chrono::time_point;
|
||||||
|
|
||||||
static const int32_t kMaxUclampValue = 1024;
|
|
||||||
struct AppHintDesc {
|
struct AppHintDesc {
|
||||||
AppHintDesc(int32_t tgid, int32_t uid, std::vector<int> threadIds)
|
AppHintDesc(int32_t tgid, int32_t uid, std::vector<int> threadIds)
|
||||||
: tgid(tgid),
|
: tgid(tgid),
|
||||||
|
@ -49,7 +48,6 @@ struct AppHintDesc {
|
||||||
threadIds(std::move(threadIds)),
|
threadIds(std::move(threadIds)),
|
||||||
duration(0LL),
|
duration(0LL),
|
||||||
current_min(0),
|
current_min(0),
|
||||||
transitioanl_min(0),
|
|
||||||
is_active(true),
|
is_active(true),
|
||||||
update_count(0),
|
update_count(0),
|
||||||
integral_error(0),
|
integral_error(0),
|
||||||
|
@ -62,7 +60,6 @@ struct AppHintDesc {
|
||||||
const std::vector<int> threadIds;
|
const std::vector<int> threadIds;
|
||||||
nanoseconds duration;
|
nanoseconds duration;
|
||||||
int current_min;
|
int current_min;
|
||||||
int transitioanl_min;
|
|
||||||
// status
|
// status
|
||||||
std::atomic<bool> is_active;
|
std::atomic<bool> is_active;
|
||||||
// pid
|
// pid
|
||||||
|
@ -87,14 +84,20 @@ class PowerHintSession : public BnPowerHintSession {
|
||||||
const std::vector<WorkDuration> &actualDurations) override;
|
const std::vector<WorkDuration> &actualDurations) override;
|
||||||
bool isActive();
|
bool isActive();
|
||||||
bool isStale();
|
bool isStale();
|
||||||
|
void wakeup();
|
||||||
|
void setStale();
|
||||||
// Is this hint session for a user application
|
// Is this hint session for a user application
|
||||||
bool isAppSession();
|
bool isAppSession();
|
||||||
const std::vector<int> &getTidList() const;
|
const std::vector<int> &getTidList() const;
|
||||||
int restoreUclamp();
|
int getUclampMin();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class HintTimerHandler : public MessageHandler {
|
class HintTimerHandler : public MessageHandler {
|
||||||
public:
|
public:
|
||||||
|
enum MsgType {
|
||||||
|
TIMER = 0,
|
||||||
|
POKE,
|
||||||
|
};
|
||||||
enum HintTimerState {
|
enum HintTimerState {
|
||||||
STALE,
|
STALE,
|
||||||
MONITORING,
|
MONITORING,
|
||||||
|
@ -109,6 +112,7 @@ class PowerHintSession : public BnPowerHintSession {
|
||||||
void handleMessage(const Message &message) override;
|
void handleMessage(const Message &message) override;
|
||||||
// Update HintTimer by actual work duration.
|
// Update HintTimer by actual work duration.
|
||||||
void updateHintTimer(int64_t actualDurationNs);
|
void updateHintTimer(int64_t actualDurationNs);
|
||||||
|
void updateHintTimerLocked(int64_t actualDurationNs);
|
||||||
// Update HintTimer by a list of work durations which could be used for
|
// Update HintTimer by a list of work durations which could be used for
|
||||||
// calculating the work period.
|
// calculating the work period.
|
||||||
void updateHintTimer(const std::vector<WorkDuration> &actualDurations);
|
void updateHintTimer(const std::vector<WorkDuration> &actualDurations);
|
||||||
|
@ -126,14 +130,13 @@ class PowerHintSession : public BnPowerHintSession {
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setStale();
|
|
||||||
void updateUniveralBoostMode();
|
void updateUniveralBoostMode();
|
||||||
int setUclamp(int32_t min, bool update = true);
|
int setSessionUclampMin(int32_t min);
|
||||||
std::string getIdString() const;
|
std::string getIdString() const;
|
||||||
AppHintDesc *mDescriptor = nullptr;
|
AppHintDesc *mDescriptor = nullptr;
|
||||||
sp<HintTimerHandler> mHintTimerHandler;
|
sp<HintTimerHandler> mHintTimerHandler;
|
||||||
sp<MessageHandler> mPowerManagerHandler;
|
sp<MessageHandler> mPowerManagerHandler;
|
||||||
std::mutex mLock;
|
std::mutex mSessionLock;
|
||||||
std::atomic<bool> mSessionClosed = false;
|
std::atomic<bool> mSessionClosed = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <log/log.h>
|
#include <log/log.h>
|
||||||
#include <perfmgr/HintManager.h>
|
#include <perfmgr/HintManager.h>
|
||||||
#include <processgroup/processgroup.h>
|
#include <processgroup/processgroup.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
#include <utils/Trace.h>
|
#include <utils/Trace.h>
|
||||||
|
|
||||||
namespace aidl {
|
namespace aidl {
|
||||||
|
@ -33,6 +34,47 @@ namespace pixel {
|
||||||
|
|
||||||
using ::android::perfmgr::HintManager;
|
using ::android::perfmgr::HintManager;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
/* there is no glibc or bionic wrapper */
|
||||||
|
struct sched_attr {
|
||||||
|
__u32 size;
|
||||||
|
__u32 sched_policy;
|
||||||
|
__u64 sched_flags;
|
||||||
|
__s32 sched_nice;
|
||||||
|
__u32 sched_priority;
|
||||||
|
__u64 sched_runtime;
|
||||||
|
__u64 sched_deadline;
|
||||||
|
__u64 sched_period;
|
||||||
|
__u32 sched_util_min;
|
||||||
|
__u32 sched_util_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int sched_setattr(int pid, struct sched_attr *attr, unsigned int flags) {
|
||||||
|
if (!HintManager::GetInstance()->GetAdpfProfile()->mUclampMinOn) {
|
||||||
|
ALOGV("PowerSessionManager:%s: skip", __func__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return syscall(__NR_sched_setattr, pid, attr, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_uclamp_min(int tid, int min) {
|
||||||
|
static constexpr int32_t kMaxUclampValue = 1024;
|
||||||
|
min = std::max(0, min);
|
||||||
|
min = std::min(min, kMaxUclampValue);
|
||||||
|
|
||||||
|
sched_attr attr = {};
|
||||||
|
attr.size = sizeof(attr);
|
||||||
|
|
||||||
|
attr.sched_flags = (SCHED_FLAG_KEEP_ALL | SCHED_FLAG_UTIL_CLAMP_MIN);
|
||||||
|
attr.sched_util_min = min;
|
||||||
|
|
||||||
|
int ret = sched_setattr(tid, &attr, 0);
|
||||||
|
if (ret) {
|
||||||
|
ALOGW("sched_setattr failed for thread %d, err=%d", tid, errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void PowerSessionManager::updateHintMode(const std::string &mode, bool enabled) {
|
void PowerSessionManager::updateHintMode(const std::string &mode, bool enabled) {
|
||||||
ALOGV("PowerSessionManager::updateHintMode: mode: %s, enabled: %d", mode.c_str(), enabled);
|
ALOGV("PowerSessionManager::updateHintMode: mode: %s, enabled: %d", mode.c_str(), enabled);
|
||||||
if (enabled && mode.compare(0, 8, "REFRESH_") == 0) {
|
if (enabled && mode.compare(0, 8, "REFRESH_") == 0) {
|
||||||
|
@ -49,6 +91,22 @@ void PowerSessionManager::updateHintMode(const std::string &mode, bool enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PowerSessionManager::updateHintBoost(const std::string &boost, int32_t durationMs) {
|
||||||
|
ATRACE_CALL();
|
||||||
|
ALOGV("PowerSessionManager::updateHintBoost: boost: %s, durationMs: %d", boost.c_str(),
|
||||||
|
durationMs);
|
||||||
|
if (boost.compare("DISPLAY_UPDATE_IMMINENT") == 0) {
|
||||||
|
wakeSessions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerSessionManager::wakeSessions() {
|
||||||
|
std::lock_guard<std::mutex> guard(mLock);
|
||||||
|
for (PowerHintSession *s : mSessions) {
|
||||||
|
s->wakeup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int PowerSessionManager::getDisplayRefreshRate() {
|
int PowerSessionManager::getDisplayRefreshRate() {
|
||||||
return mDisplayRefreshRate;
|
return mDisplayRefreshRate;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +114,7 @@ int PowerSessionManager::getDisplayRefreshRate() {
|
||||||
void PowerSessionManager::addPowerSession(PowerHintSession *session) {
|
void PowerSessionManager::addPowerSession(PowerHintSession *session) {
|
||||||
std::lock_guard<std::mutex> guard(mLock);
|
std::lock_guard<std::mutex> guard(mLock);
|
||||||
for (auto t : session->getTidList()) {
|
for (auto t : session->getTidList()) {
|
||||||
|
mTidSessionListMap[t].insert(session);
|
||||||
if (mTidRefCountMap.find(t) == mTidRefCountMap.end()) {
|
if (mTidRefCountMap.find(t) == mTidRefCountMap.end()) {
|
||||||
if (!SetTaskProfiles(t, {"ResetUclampGrp"})) {
|
if (!SetTaskProfiles(t, {"ResetUclampGrp"})) {
|
||||||
ALOGW("Failed to set ResetUclampGrp task profile for tid:%d", t);
|
ALOGW("Failed to set ResetUclampGrp task profile for tid:%d", t);
|
||||||
|
@ -80,6 +139,7 @@ void PowerSessionManager::removePowerSession(PowerHintSession *session) {
|
||||||
ALOGE("Unexpected Error! Failed to look up tid:%d in TidRefCountMap", t);
|
ALOGE("Unexpected Error! Failed to look up tid:%d in TidRefCountMap", t);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
mTidSessionListMap[t].erase(session);
|
||||||
mTidRefCountMap[t]--;
|
mTidRefCountMap[t]--;
|
||||||
if (mTidRefCountMap[t] <= 0) {
|
if (mTidRefCountMap[t] <= 0) {
|
||||||
if (!SetTaskProfiles(t, {"NoResetUclampGrp"})) {
|
if (!SetTaskProfiles(t, {"NoResetUclampGrp"})) {
|
||||||
|
@ -91,6 +151,25 @@ void PowerSessionManager::removePowerSession(PowerHintSession *session) {
|
||||||
mSessions.erase(session);
|
mSessions.erase(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PowerSessionManager::setUclampMin(PowerHintSession *session, int val) {
|
||||||
|
std::lock_guard<std::mutex> guard(mLock);
|
||||||
|
setUclampMinLocked(session, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerSessionManager::setUclampMinLocked(PowerHintSession *session, int val) {
|
||||||
|
for (auto t : session->getTidList()) {
|
||||||
|
// Get thex max uclamp.min across sessions which include the tid.
|
||||||
|
int tidMax = 0;
|
||||||
|
for (PowerHintSession *s : mTidSessionListMap[t]) {
|
||||||
|
if (!s->isActive() || s->isStale())
|
||||||
|
continue;
|
||||||
|
tidMax = std::max(tidMax, s->getUclampMin());
|
||||||
|
}
|
||||||
|
val = std::max(val, tidMax);
|
||||||
|
set_uclamp_min(t, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<bool> PowerSessionManager::isAnyAppSessionActive() {
|
std::optional<bool> PowerSessionManager::isAnyAppSessionActive() {
|
||||||
std::lock_guard<std::mutex> guard(mLock);
|
std::lock_guard<std::mutex> guard(mLock);
|
||||||
bool active = false;
|
bool active = false;
|
||||||
|
|
|
@ -45,10 +45,13 @@ class PowerSessionManager : public MessageHandler {
|
||||||
public:
|
public:
|
||||||
// current hint info
|
// current hint info
|
||||||
void updateHintMode(const std::string &mode, bool enabled);
|
void updateHintMode(const std::string &mode, bool enabled);
|
||||||
|
void updateHintBoost(const std::string &boost, int32_t durationMs);
|
||||||
int getDisplayRefreshRate();
|
int getDisplayRefreshRate();
|
||||||
// monitoring session status
|
// monitoring session status
|
||||||
void addPowerSession(PowerHintSession *session);
|
void addPowerSession(PowerHintSession *session);
|
||||||
void removePowerSession(PowerHintSession *session);
|
void removePowerSession(PowerHintSession *session);
|
||||||
|
void setUclampMin(PowerHintSession *session, int min);
|
||||||
|
void setUclampMinLocked(PowerHintSession *session, int min);
|
||||||
|
|
||||||
void handleMessage(const Message &message) override;
|
void handleMessage(const Message &message) override;
|
||||||
|
|
||||||
|
@ -59,21 +62,27 @@ class PowerSessionManager : public MessageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void wakeSessions();
|
||||||
std::optional<bool> isAnyAppSessionActive();
|
std::optional<bool> isAnyAppSessionActive();
|
||||||
void disableSystemTopAppBoost();
|
void disableSystemTopAppBoost();
|
||||||
void enableSystemTopAppBoost();
|
void enableSystemTopAppBoost();
|
||||||
const std::string kDisableBoostHintName;
|
const std::string kDisableBoostHintName;
|
||||||
|
|
||||||
std::unordered_set<PowerHintSession *> mSessions; // protected by mLock
|
std::unordered_set<PowerHintSession *> mSessions; // protected by mLock
|
||||||
std::unordered_map<int, int> mTidRefCountMap; // protected by mLock
|
std::unordered_map<int, int> mTidRefCountMap; // protected by mLock
|
||||||
|
std::unordered_map<int, std::unordered_set<PowerHintSession *>> mTidSessionListMap;
|
||||||
|
bool mActive; // protected by mLock
|
||||||
|
/**
|
||||||
|
* mLock to pretect the above data objects opertions.
|
||||||
|
**/
|
||||||
std::mutex mLock;
|
std::mutex mLock;
|
||||||
int mDisplayRefreshRate;
|
int mDisplayRefreshRate;
|
||||||
bool mActive; // protected by mLock
|
|
||||||
// Singleton
|
// Singleton
|
||||||
PowerSessionManager()
|
PowerSessionManager()
|
||||||
: kDisableBoostHintName(::android::base::GetProperty(kPowerHalAdpfDisableTopAppBoost,
|
: kDisableBoostHintName(::android::base::GetProperty(kPowerHalAdpfDisableTopAppBoost,
|
||||||
"ADPF_DISABLE_TA_BOOST")),
|
"ADPF_DISABLE_TA_BOOST")),
|
||||||
mDisplayRefreshRate(60),
|
mActive(false),
|
||||||
mActive(false) {}
|
mDisplayRefreshRate(60) {}
|
||||||
PowerSessionManager(PowerSessionManager const &) = delete;
|
PowerSessionManager(PowerSessionManager const &) = delete;
|
||||||
void operator=(PowerSessionManager const &) = delete;
|
void operator=(PowerSessionManager const &) = delete;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue