summaryrefslogtreecommitdiff
path: root/power-libperfmgr/aidl/SessionTaskMap.h
blob: 35e7b85acb69ebb14ee3c01ffb8609a3ff0eea38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Copyright 2023 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 <unordered_map>
#include <vector>

#include "SessionValueEntry.h"

namespace aidl {
namespace google {
namespace hardware {
namespace power {
namespace impl {
namespace pixel {

/**
 * Map session id to a value and link to many task ids
 * Maintain consistency between mappings
 * e.g.
 *  Sessions[sid1] -> SessionValueEntry1, [tid1, tid2]
 *  Tasks[tid1] -> [sid1]
 *  Tasks[tid2] -> [sid1]
 *  ...
 *  Sessions[sid2] -> SessionValueEntry2, [tid2, tid3]
 *  Tasks[tid1] -> [sid1]
 *  Tasks[tid2] -> [sid1, sid2]
 *  Tasks[tid3] -> [sid2]
 */
class SessionTaskMap {
  public:
    // Add a session with associated tasks to mapping
    bool add(int64_t sessionId, const SessionValueEntry &sv, const std::vector<pid_t> &taskIds);

    // Add a vote to a session
    void addVote(int64_t sessionId, int voteId, int uclampMin, int uclampMax,
                 std::chrono::steady_clock::time_point startTime,
                 std::chrono::nanoseconds durationNs);

    // Find session id and run callback on session value, linked tasks
    std::shared_ptr<SessionValueEntry> findSession(int64_t sessionId);

    void getTaskVoteRange(pid_t taskId, std::chrono::steady_clock::time_point timeNow,
                          int *uclampMin, int *uclampmax) const;

    // Find session ids given a task id if it exists
    std::vector<int64_t> getSessionIds(pid_t taskId) const;

    // Get a vec of tasks associated with a session
    std::vector<pid_t> &getTaskIds(int64_t sessionId);

    // Return true if any app session is active, false otherwise
    bool isAnyAppSessionActive(std::chrono::steady_clock::time_point timePoint) const;

    // Remove a session based on session id
    bool remove(int64_t sessionId);

    // Maintain value of session, remove old task mapping add new
    bool replace(int64_t sessionId, const std::vector<pid_t> &taskIds,
                 std::vector<pid_t> *addedThreads, std::vector<pid_t> *removedThreads);

    size_t sizeSessions() const;

    size_t sizeTasks() const;

    // Given task id, for each linked-to session id call fn
    template <typename FN>
    void forEachSessionInTask(pid_t taskId, FN fn) const {
        auto taskSessItr = mTasks.find(taskId);
        if (taskSessItr == mTasks.end()) {
            return;
        }
        for (const auto session : taskSessItr->second) {
            auto sessionItr = mSessions.find(session->sessionId);
            if (sessionItr == mSessions.end()) {
                continue;
            }
            fn(sessionItr->first, *(sessionItr->second.val));
        }
    }

    // Iterate over all entries in session map and run callback fn
    // fn takes int64_t session id, session entry val, linked task ids
    template <typename FN>
    void forEachSessionValTasks(FN fn) const {
        for (const auto &e : mSessions) {
            fn(e.first, *(e.second.val), e.second.linkedTasks);
        }
    }

    // Returns string id of session
    const std::string &idString(int64_t sessionId) const;

    // Returns true if session id is an app session id
    bool isAppSession(int64_t sessionId) const;

    // Remove dead task-session map entry
    bool removeDeadTaskSessionMap(int64_t sessionId, pid_t taskId);

  private:
    // Internal struct to hold per-session data and linked tasks
    struct ValEntry {
        std::shared_ptr<SessionValueEntry> val;
        std::vector<pid_t> linkedTasks;
    };
    // Map session id to value
    std::unordered_map<int64_t, ValEntry> mSessions;
    // Map task id to set of session ids
    std::unordered_map<pid_t, std::vector<std::shared_ptr<SessionValueEntry>>> mTasks;
};

}  // namespace pixel
}  // namespace impl
}  // namespace power
}  // namespace hardware
}  // namespace google
}  // namespace aidl