• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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