1 /* 2 * Copyright 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <algorithm> 20 #include <chrono> 21 #include <memory> 22 #include <ostream> 23 #include <unordered_map> 24 25 #include "AdpfTypes.h" 26 #include "PhysicalQuantityTypes.h" 27 28 namespace aidl { 29 namespace google { 30 namespace hardware { 31 namespace power { 32 namespace impl { 33 namespace pixel { 34 35 // -------------------------------------------------------- 36 // Hold a min and max for acceptable uclamp values 37 struct UclampRange { 38 int uclampMin{kUclampMin}; 39 int uclampMax{kUclampMax}; 40 }; 41 42 // -------------------------------------------------------- 43 // Hold the common timing state of the of acceptable votes: 44 // is active status, time duration info, and helper methods for consistent use 45 class VoteRange { 46 public: 47 VoteRange() = default; 48 VoteRange(VoteRange const &) = default; 49 VoteRange(VoteRange &&) = default; 50 VoteRange &operator=(VoteRange const &) = default; 51 VoteRange &operator=(VoteRange &&) = default; 52 virtual ~VoteRange() = default; 53 VoteRange(bool active,std::chrono::steady_clock::time_point startTime,std::chrono::nanoseconds durationNs)54 VoteRange(bool active, std::chrono::steady_clock::time_point startTime, 55 std::chrono::nanoseconds durationNs) 56 : mActive(active), mStartTime(startTime), mDurationNs(durationNs) {} 57 58 // Returns true if this vote range is active, false if it is not active active()59 bool active() const { return mActive; } 60 61 // Returns the start time of this vote range startTime()62 std::chrono::steady_clock::time_point startTime() const { return mStartTime; } 63 64 // Returns the duration in nanoseconds of the vote range durationNs()65 std::chrono::nanoseconds durationNs() const { return mDurationNs; } 66 67 // Set the is active flag to bool param setActive(bool active)68 void setActive(bool active) { mActive = active; } 69 70 // Update the vote duration updateDuration(std::chrono::nanoseconds durationNs)71 void updateDuration(std::chrono::nanoseconds durationNs) { mDurationNs = durationNs; } 72 73 // Return true if time point parameter in range of startTime to startTime+duration isTimeInRange(std::chrono::steady_clock::time_point t)74 inline bool isTimeInRange(std::chrono::steady_clock::time_point t) const { 75 return mActive && ((mStartTime <= t) && ((mStartTime + mDurationNs) >= t)); 76 } 77 78 private: 79 bool mActive{true}; 80 std::chrono::steady_clock::time_point mStartTime{}; 81 std::chrono::nanoseconds mDurationNs{}; 82 }; 83 84 struct CpuVote final : VoteRange { 85 CpuVote() = default; CpuVotefinal86 CpuVote(bool active, std::chrono::steady_clock::time_point startTime, 87 std::chrono::nanoseconds durationNs, int uclamp_min, int uclamp_max) 88 : VoteRange(active, startTime, durationNs), mUclampRange{uclamp_min, uclamp_max} {} 89 UclampRange mUclampRange; 90 }; 91 92 struct GpuVote final : VoteRange { 93 GpuVote() = default; GpuVotefinal94 GpuVote(bool active, std::chrono::steady_clock::time_point startTime, 95 std::chrono::nanoseconds durationNs, Cycles capacity) 96 : VoteRange(active, startTime, durationNs), mCapacity(capacity) {} 97 Cycles mCapacity; 98 }; 99 100 // Helper for logging 101 std::ostream &operator<<(std::ostream &o, const VoteRange &vr); 102 103 // -------------------------------------------------------- 104 // Thread safe collection of votes that can be used to get 105 // a clamped range 106 class Votes { 107 public: 108 Votes(); 109 110 // Add a vote and associate with vote id, overwrites existing vote. 111 // ADPF_VOTE_GPU_CAPACITY is an invalid value and will be ignored. 112 // For this vote, set_gpu_capacity_node should be used. 113 void add(int, CpuVote const &vote); 114 void add(int, GpuVote const &vote); 115 116 // Update the duration of a vote given a vote id 117 void updateDuration(int voteId, std::chrono::nanoseconds durationNs); 118 119 // Given input UclampRange, and a time point now, increase the min and 120 // decrease max if this VoteRange is in range, return UclampRange with 121 // the largest min and the smallest max 122 void getUclampRange(UclampRange &uclampRange, std::chrono::steady_clock::time_point t) const; 123 124 std::optional<Cycles> getGpuCapacityRequest(std::chrono::steady_clock::time_point t) const; 125 // Return true if any vote has timed out, otherwise return false 126 bool anyTimedOut(std::chrono::steady_clock::time_point t) const; 127 128 // Return true if all votes have timed out, otherwise return false 129 bool allTimedOut(std::chrono::steady_clock::time_point t) const; 130 131 // Remove vote based on vote vote id, return true if remove was successful, 132 // false if remove failed for example no vote with that id exists 133 bool remove(int voteId); 134 135 // Turn on/off vote 136 bool setUseVote(int voteId, bool active); 137 138 // Return number of votes 139 size_t size() const; 140 141 bool voteIsActive(int voteId) const; 142 143 std::chrono::steady_clock::time_point voteTimeout(int voteId) const; 144 145 private: 146 std::unordered_map<int, CpuVote> mCpuVotes; 147 std::unordered_map<int, GpuVote> mGpuVotes; 148 }; 149 150 } // namespace pixel 151 } // namespace impl 152 } // namespace power 153 } // namespace hardware 154 } // namespace google 155 } // namespace aidl 156