xref: /aosp_15_r20/external/perfetto/src/trace_redaction/process_thread_timeline.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2024 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 #ifndef SRC_TRACE_REDACTION_PROCESS_THREAD_TIMELINE_H_
18 #define SRC_TRACE_REDACTION_PROCESS_THREAD_TIMELINE_H_
19 
20 #include <cstdint>
21 #include <limits>
22 #include <vector>
23 
24 namespace perfetto::trace_redaction {
25 
26 class ProcessThreadTimeline {
27  public:
28   // Opened and closed events are used to mark the start and end of lifespans.
29   struct Event {
30    public:
31     static constexpr auto kUnknownPid = std::numeric_limits<int32_t>::max();
32     static constexpr auto kUnknownUid = std::numeric_limits<uint64_t>::max();
33 
34     enum class Type { kInvalid, kOpen, kClose };
35 
36     bool operator==(const Event& o) const {
37       switch (type) {
38         case Type::kOpen:
39           return o.type == Type::kOpen && ts == o.ts && pid == o.pid &&
40                  ppid == o.ppid && uid == o.uid;
41 
42         case Type::kClose:
43           return o.type == Type::kClose && ts == o.ts && pid == o.pid;
44 
45         case Type::kInvalid:
46           return o.type == Type::kInvalid;
47       }
48 
49       return false;
50     }
51 
52     bool operator!=(const Event& o) const { return !(*this == o); }
53 
validEvent54     bool valid() const { return type != Type::kInvalid; }
55 
OpenEvent56     static Event Open(uint64_t ts, int32_t pid, int32_t ppid, uint64_t uid) {
57       return {Type::kOpen, ts, pid, ppid, uid};
58     }
59 
OpenEvent60     static Event Open(uint64_t ts, int32_t pid, int32_t ppid) {
61       return {Type::kOpen, ts, pid, ppid, kUnknownUid};
62     }
63 
CloseEvent64     static Event Close(uint64_t ts, int32_t pid) {
65       return {Type::kClose, ts, pid, kUnknownPid, kUnknownUid};
66     }
67 
68     Type type = Type::kInvalid;
69 
70     // The time when the event occured. Undefined when type is kInvalid.
71     uint64_t ts = 0;
72 
73     // The subject of the event. Undefined when type is kInvalid.
74     int32_t pid = kUnknownPid;
75 
76     // The parent of the subject. kUnknownPid if the parent is unknown.
77     // Undefined when type is kClose or kInvalid.
78     int32_t ppid = kUnknownPid;
79 
80     // The package containing the subject. kUnknownUid if the package is
81     // unknown. Undefined when type is kClose or kInvalid.
82     uint64_t uid = kUnknownUid;
83   };
84 
85   ProcessThreadTimeline() = default;
86 
87   ProcessThreadTimeline(const ProcessThreadTimeline&) = delete;
88   ProcessThreadTimeline& operator=(const ProcessThreadTimeline&) = delete;
89   ProcessThreadTimeline(ProcessThreadTimeline&&) = delete;
90   ProcessThreadTimeline& operator=(ProcessThreadTimeline&&) = delete;
91 
92   void Append(const Event& event);
93 
94   // REQUIRED: Sorts all events by pid, making it possible to locate the subset
95   // of events connected to a pid. Events are not sorted by time because the
96   // subset of events will, on average, be trivally small.
97   void Sort();
98 
99   // Returns true if a process/thread is connected to a package.
100   bool PidConnectsToUid(uint64_t ts, int32_t pid, uint64_t uid) const;
101 
102   // Get the opening event for a pid. If pid ends at ts, an opening event will
103   // still be returned.
104   const Event* GetOpeningEvent(uint64_t ts, int32_t pid) const;
105 
106   // SELECT MAX(ts), * FROM events WHERE pid=@pid AND type=@type AND ts<=@ts
107   const Event* QueryLeftMax(uint64_t ts,
108                             int32_t pid,
109                             ProcessThreadTimeline::Event::Type type) const;
110 
111  private:
112   enum class Mode {
113     // The timeline can safely be queried. If the timeline is in read mode, and
114     // a user writes to the timeline, the timeline will change to write mode.
115     kRead,
116 
117     // The timeline change be changed. If the timeline is not in write mode,
118     // reading from the timeline will throw an error. Sort() must be called to
119     // change the timeline from write to read mode.
120     kWrite
121   };
122 
123   std::vector<Event> events_;
124 
125   Mode mode_ = Mode::kRead;
126 };
127 
128 }  // namespace perfetto::trace_redaction
129 
130 #endif  // SRC_TRACE_REDACTION_PROCESS_THREAD_TIMELINE_H_
131