Currently PowerHAL does not distinguish between system processes and apps when deciding whether to apply universal boost. This patch distinguishes system sessions and app sessions and ignores system ones, making the disabling of universal boost dependent on the presence of app hint sessions. Bug: b/230511824 Test: manual Change-Id: I08dea29b3a45f2ba69ed99a9f188fa83ba143423
145 lines
4.5 KiB
C++
145 lines
4.5 KiB
C++
/*
|
|
* Copyright 2021 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <aidl/android/hardware/power/BnPowerHintSession.h>
|
|
#include <aidl/android/hardware/power/WorkDuration.h>
|
|
#include <utils/Looper.h>
|
|
#include <utils/Thread.h>
|
|
|
|
#include <mutex>
|
|
#include <unordered_map>
|
|
|
|
namespace aidl {
|
|
namespace google {
|
|
namespace hardware {
|
|
namespace power {
|
|
namespace impl {
|
|
namespace pixel {
|
|
|
|
using aidl::android::hardware::power::BnPowerHintSession;
|
|
using aidl::android::hardware::power::WorkDuration;
|
|
using ::android::Message;
|
|
using ::android::MessageHandler;
|
|
using ::android::sp;
|
|
using std::chrono::milliseconds;
|
|
using std::chrono::nanoseconds;
|
|
using std::chrono::steady_clock;
|
|
using std::chrono::time_point;
|
|
|
|
static const int32_t kMaxUclampValue = 1024;
|
|
struct AppHintDesc {
|
|
AppHintDesc(int32_t tgid, int32_t uid, std::vector<int> threadIds)
|
|
: tgid(tgid),
|
|
uid(uid),
|
|
threadIds(std::move(threadIds)),
|
|
duration(0LL),
|
|
current_min(0),
|
|
transitioanl_min(0),
|
|
is_active(true),
|
|
update_count(0),
|
|
integral_error(0),
|
|
previous_error(0),
|
|
work_period(0),
|
|
last_start(0) {}
|
|
std::string toString() const;
|
|
const int32_t tgid;
|
|
const int32_t uid;
|
|
const std::vector<int> threadIds;
|
|
nanoseconds duration;
|
|
int current_min;
|
|
int transitioanl_min;
|
|
// status
|
|
std::atomic<bool> is_active;
|
|
// pid
|
|
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 {
|
|
public:
|
|
explicit PowerHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds,
|
|
int64_t durationNanos);
|
|
~PowerHintSession();
|
|
ndk::ScopedAStatus close() override;
|
|
ndk::ScopedAStatus pause() override;
|
|
ndk::ScopedAStatus resume() override;
|
|
ndk::ScopedAStatus updateTargetWorkDuration(int64_t targetDurationNanos) override;
|
|
ndk::ScopedAStatus reportActualWorkDuration(
|
|
const std::vector<WorkDuration> &actualDurations) override;
|
|
bool isActive();
|
|
bool isStale();
|
|
// Is this hint session for a user application
|
|
bool isAppSession();
|
|
const std::vector<int> &getTidList() const;
|
|
int restoreUclamp();
|
|
|
|
private:
|
|
class HintTimerHandler : public MessageHandler {
|
|
public:
|
|
enum HintTimerState {
|
|
STALE,
|
|
MONITORING,
|
|
EARLY_BOOST,
|
|
};
|
|
HintTimerHandler(PowerHintSession *session)
|
|
: mSession(session),
|
|
mState(STALE),
|
|
mLastUpdatedTime(steady_clock::now()),
|
|
mIsSessionDead(false) {}
|
|
~HintTimerHandler();
|
|
void handleMessage(const Message &message) override;
|
|
// Update HintTimer by actual work duration.
|
|
void updateHintTimer(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;
|
|
bool mIsSessionDead;
|
|
};
|
|
|
|
private:
|
|
void setStale();
|
|
void updateUniveralBoostMode();
|
|
int setUclamp(int32_t min, bool update = true);
|
|
std::string getIdString() const;
|
|
AppHintDesc *mDescriptor = nullptr;
|
|
sp<HintTimerHandler> mHintTimerHandler;
|
|
sp<MessageHandler> mPowerManagerHandler;
|
|
std::mutex mLock;
|
|
std::atomic<bool> mSessionClosed = false;
|
|
};
|
|
|
|
} // namespace pixel
|
|
} // namespace impl
|
|
} // namespace power
|
|
} // namespace hardware
|
|
} // namespace google
|
|
} // namespace aidl
|