blob: 4827d9aadef8a78522f9eb21a7772a94041cdf48 [file] [log] [blame]
/*
* 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 <android-base/properties.h>
#include <perfmgr/HintManager.h>
#include <utils/Mutex.h>
#include <mutex>
#include <optional>
#include "AppHintDesc.h"
#include "BackgroundWorker.h"
#include "GpuCapacityNode.h"
#include "SessionTaskMap.h"
namespace aidl {
namespace google {
namespace hardware {
namespace power {
namespace impl {
namespace pixel {
using ::android::Thread;
constexpr char kPowerHalAdpfDisableTopAppBoost[] = "vendor.powerhal.adpf.disable.hint";
template <class HintManagerT = ::android::perfmgr::HintManager>
class PowerSessionManager : public Immobile {
public:
~PowerSessionManager() = default;
// Update the current hint info
void updateHintMode(const std::string &mode, bool enabled);
void updateHintBoost(const std::string &boost, int32_t durationMs);
int getDisplayRefreshRate();
// Add and remove power hint session
void addPowerSession(const std::string &idString,
const std::shared_ptr<AppHintDesc> &sessionDescriptor,
const std::shared_ptr<AppDescriptorTrace> &sessionTrace,
const std::vector<int32_t> &threadIds);
void removePowerSession(int64_t sessionId);
// Replace current threads in session with threadIds
void setThreadsFromPowerSession(int64_t sessionId, const std::vector<int32_t> &threadIds);
// Pause and resume power hint session
void pause(int64_t sessionId);
void resume(int64_t sessionId);
void updateUniversalBoostMode();
void dumpToFd(int fd);
void updateTargetWorkDuration(int64_t sessionId, AdpfVoteType voteId,
std::chrono::nanoseconds durationNs);
// Set vote for power hint session
void voteSet(int64_t sessionId, AdpfVoteType voteId, int uclampMin, int uclampMax,
std::chrono::steady_clock::time_point startTime,
std::chrono::nanoseconds durationNs);
void voteSet(int64_t sessionId, AdpfVoteType voteId, Cycles capacity,
std::chrono::steady_clock::time_point startTime,
std::chrono::nanoseconds durationNs);
void disableBoosts(int64_t sessionId);
void setPreferPowerEfficiency(int64_t sessionId, bool enabled);
// Singleton
static PowerSessionManager *getInstance() {
static PowerSessionManager instance{};
return &instance;
}
std::optional<Frequency> gpuFrequency() const;
void registerSession(std::shared_ptr<void> session, int64_t sessionId);
void unregisterSession(int64_t sessionId);
// Only for testing
void clear();
std::shared_ptr<void> getSession(int64_t sessionId);
private:
std::optional<bool> isAnyAppSessionActive();
void disableSystemTopAppBoost();
void enableSystemTopAppBoost();
const std::string kDisableBoostHintName;
int mDisplayRefreshRate;
// Rewrite specific
mutable std::mutex mSessionTaskMapMutex;
SessionTaskMap mSessionTaskMap;
std::shared_ptr<PriorityQueueWorkerPool> mPriorityQueueWorkerPool;
// Session timeout
struct EventSessionTimeout {
std::chrono::steady_clock::time_point timeStamp;
int64_t sessionId{0};
int voteId{0};
};
void handleEvent(const EventSessionTimeout &e);
TemplatePriorityQueueWorker<EventSessionTimeout> mEventSessionTimeoutWorker;
// Calculate uclamp range
void applyUclampLocked(int64_t sessionId, std::chrono::steady_clock::time_point timePoint)
REQUIRES(mSessionTaskMapMutex);
void applyGpuVotesLocked(int64_t sessionId, std::chrono::steady_clock::time_point timePoint)
REQUIRES(mSessionTaskMapMutex);
void applyCpuAndGpuVotes(int64_t sessionId, std::chrono::steady_clock::time_point timePoint);
// Force a session active or in-active, helper for other methods
void forceSessionActive(int64_t sessionId, bool isActive);
// Singleton
PowerSessionManager()
: kDisableBoostHintName(::android::base::GetProperty(kPowerHalAdpfDisableTopAppBoost,
"ADPF_DISABLE_TA_BOOST")),
mDisplayRefreshRate(60),
mPriorityQueueWorkerPool(new PriorityQueueWorkerPool(1, "adpf_handler")),
mEventSessionTimeoutWorker([&](auto e) { handleEvent(e); }, mPriorityQueueWorkerPool),
mGpuCapacityNode(createGpuCapacityNode()) {}
PowerSessionManager(PowerSessionManager const &) = delete;
PowerSessionManager &operator=(PowerSessionManager const &) = delete;
std::optional<std::unique_ptr<GpuCapacityNode>> const mGpuCapacityNode;
std::mutex mSessionMapMutex;
std::map<int, std::weak_ptr<void>> mSessionMap GUARDED_BY(mSessionMapMutex);
};
} // namespace pixel
} // namespace impl
} // namespace power
} // namespace hardware
} // namespace google
} // namespace aidl