/* * 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