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 <unordered_map> 20 #include <vector> 21 22 #include "SessionValueEntry.h" 23 24 namespace aidl { 25 namespace google { 26 namespace hardware { 27 namespace power { 28 namespace impl { 29 namespace pixel { 30 31 /** 32 * Map session id to a value and link to many task ids 33 * Maintain consistency between mappings 34 * e.g. 35 * Sessions[sid1] -> SessionValueEntry1, [tid1, tid2] 36 * Tasks[tid1] -> [sid1] 37 * Tasks[tid2] -> [sid1] 38 * ... 39 * Sessions[sid2] -> SessionValueEntry2, [tid2, tid3] 40 * Tasks[tid1] -> [sid1] 41 * Tasks[tid2] -> [sid1, sid2] 42 * Tasks[tid3] -> [sid2] 43 */ 44 class SessionTaskMap { 45 public: 46 // Add a session with associated tasks to mapping 47 bool add(int64_t sessionId, const SessionValueEntry &sv, const std::vector<pid_t> &taskIds); 48 49 // Add a vote to a session 50 void addVote(int64_t sessionId, int voteId, int uclampMin, int uclampMax, 51 std::chrono::steady_clock::time_point startTime, 52 std::chrono::nanoseconds durationNs); 53 void addGpuVote(int64_t sessionId, int voteId, Cycles capacity, 54 std::chrono::steady_clock::time_point startTime, 55 std::chrono::nanoseconds durationNs); 56 57 // Find session id and run callback on session value, linked tasks 58 std::shared_ptr<SessionValueEntry> findSession(int64_t sessionId) const; 59 60 void getTaskVoteRange(pid_t taskId, std::chrono::steady_clock::time_point timeNow, 61 UclampRange &range, std::optional<int32_t> &uclampMaxEfficientBase, 62 std::optional<int32_t> &uclampMaxEfficientOffset) const; 63 Cycles getSessionsGpuCapacity(std::chrono::steady_clock::time_point time_point) const; 64 65 // Find session ids given a task id if it exists 66 std::vector<int64_t> getSessionIds(pid_t taskId) const; 67 68 // Get a vec of tasks associated with a session 69 std::vector<pid_t> &getTaskIds(int64_t sessionId); 70 71 // Return true if any app session is active, false otherwise 72 bool isAnyAppSessionActive(std::chrono::steady_clock::time_point timePoint) const; 73 74 // Remove a session based on session id 75 bool remove(int64_t sessionId); 76 77 // Maintain value of session, remove old task mapping add new 78 bool replace(int64_t sessionId, const std::vector<pid_t> &taskIds, 79 std::vector<pid_t> *addedThreads, std::vector<pid_t> *removedThreads); 80 81 size_t sizeSessions() const; 82 83 size_t sizeTasks() const; 84 85 // Given task id, for each linked-to session id call fn 86 template <typename FN> forEachSessionInTask(pid_t taskId,FN fn)87 void forEachSessionInTask(pid_t taskId, FN fn) const { 88 auto taskSessItr = mTasks.find(taskId); 89 if (taskSessItr == mTasks.end()) { 90 return; 91 } 92 for (const auto &session : taskSessItr->second) { 93 auto sessionItr = mSessions.find(session->sessionId); 94 if (sessionItr == mSessions.end()) { 95 continue; 96 } 97 fn(sessionItr->first, *(sessionItr->second.val)); 98 } 99 } 100 101 // Iterate over all entries in session map and run callback fn 102 // fn takes int64_t session id, session entry val, linked task ids 103 template <typename FN> forEachSessionValTasks(FN fn)104 void forEachSessionValTasks(FN fn) const { 105 for (const auto &e : mSessions) { 106 fn(e.first, *(e.second.val), e.second.linkedTasks); 107 } 108 } 109 110 // Returns string id of session 111 const std::string &idString(int64_t sessionId) const; 112 113 // Returns true if session id is an app session id 114 bool isAppSession(int64_t sessionId) const; 115 116 // Remove dead task-session map entry 117 bool removeDeadTaskSessionMap(int64_t sessionId, pid_t taskId); 118 119 private: 120 // Internal struct to hold per-session data and linked tasks 121 struct ValEntry { 122 std::shared_ptr<SessionValueEntry> val; 123 std::vector<pid_t> linkedTasks; 124 }; 125 // Map session id to value 126 std::unordered_map<int64_t, ValEntry> mSessions; 127 // Map task id to set of session ids 128 std::unordered_map<pid_t, std::vector<std::shared_ptr<SessionValueEntry>>> mTasks; 129 }; 130 131 } // namespace pixel 132 } // namespace impl 133 } // namespace power 134 } // namespace hardware 135 } // namespace google 136 } // namespace aidl 137