/* * 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 #include #include #include #include #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 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 &sessionDescriptor, const std::shared_ptr &sessionTrace, const std::vector &threadIds); void removePowerSession(int64_t sessionId); // Replace current threads in session with threadIds void setThreadsFromPowerSession(int64_t sessionId, const std::vector &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 gpuFrequency() const; void registerSession(std::shared_ptr session, int64_t sessionId); void unregisterSession(int64_t sessionId); // Only for testing void clear(); std::shared_ptr getSession(int64_t sessionId); private: std::optional isAnyAppSessionActive(); void disableSystemTopAppBoost(); void enableSystemTopAppBoost(); const std::string kDisableBoostHintName; int mDisplayRefreshRate; // Rewrite specific mutable std::mutex mSessionTaskMapMutex; SessionTaskMap mSessionTaskMap; std::shared_ptr 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 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> const mGpuCapacityNode; std::mutex mSessionMapMutex; std::map> mSessionMap GUARDED_BY(mSessionMapMutex); }; } // namespace pixel } // namespace impl } // namespace power } // namespace hardware } // namespace google } // namespace aidl