/* * 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 #include "AdpfTypes.h" #include "AppDescriptorTrace.h" #include "PowerSessionManager.h" #include "SessionRecords.h" namespace aidl { namespace google { namespace hardware { namespace power { namespace impl { namespace pixel { using aidl::android::hardware::power::BnPowerHintSession; 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; // The Power Hint Session is responsible for providing an // interface for creating, updating, and closing power hints // for a Session. Each sesion that is mapped to multiple // threads (or task ids). template > class PowerHintSession : public BnPowerHintSession, public Immobile { public: explicit PowerHintSession(int32_t tgid, int32_t uid, const std::vector &threadIds, int64_t durationNanos, SessionTag tag); ~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 &actualDurations) override; ndk::ScopedAStatus sendHint(SessionHint hint) override; ndk::ScopedAStatus setMode(SessionMode mode, bool enabled) override; ndk::ScopedAStatus setThreads(const std::vector &threadIds) override; ndk::ScopedAStatus getSessionConfig(SessionConfig *_aidl_return) override; void dumpToStream(std::ostream &stream); SessionTag getSessionTag() const; private: // In practice this lock should almost never get contested, but it's necessary for FMQ std::mutex mPowerHintSessionLock; bool isTimeout() REQUIRES(mPowerHintSessionLock); // Is hint session for a user application bool isAppSession() REQUIRES(mPowerHintSessionLock); void tryToSendPowerHint(std::string hint) REQUIRES(mPowerHintSessionLock); void updatePidControlVariable(int pidControlVariable, bool updateVote = true) REQUIRES(mPowerHintSessionLock); int64_t convertWorkDurationToBoostByPid(const std::vector &actualDurations) REQUIRES(mPowerHintSessionLock); bool updateHeuristicBoost() REQUIRES(mPowerHintSessionLock); // Data PowerSessionManagerT *mPSManager; const int64_t mSessionId = 0; const std::string mIdString; std::shared_ptr mDescriptor GUARDED_BY(mPowerHintSessionLock); // Trace strings, this is thread safe since only assigned during construction std::shared_ptr mAppDescriptorTrace; time_point mLastUpdatedTime GUARDED_BY(mPowerHintSessionLock); bool mSessionClosed GUARDED_BY(mPowerHintSessionLock) = false; // Are cpu load change related hints are supported std::unordered_map> mSupportedHints GUARDED_BY(mPowerHintSessionLock); // Use the value of the last enum in enum_range +1 as array size std::array()> mModes GUARDED_BY(mPowerHintSessionLock){}; // Tag labeling what kind of session this is const SessionTag mTag; std::unique_ptr mSessionRecords GUARDED_BY(mPowerHintSessionLock) = nullptr; bool mHeuristicBoostActive GUARDED_BY(mPowerHintSessionLock){false}; }; } // namespace pixel } // namespace impl } // namespace power } // namespace hardware } // namespace google } // namespace aidl