1 /*
2  * Copyright (C) 2017 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 #include "src/traced/probes/ftrace/ftrace_metadata.h"
18 
19 namespace perfetto {
20 
FtraceMetadata()21 FtraceMetadata::FtraceMetadata() {
22   // A lot of the time there will only be a small number of inodes.
23   inode_and_device.reserve(10);
24   // A sched_switch is 64 bytes, a page is 4096 bytes and we expect
25   // 2 pid's per sched_switch. 4096/64*2=128
26   pids.reserve(128);
27   // We expect to see only a small number of task rename events.
28   rename_pids.reserve(16);
29 }
30 
AddDevice(BlockDeviceID device_id)31 void FtraceMetadata::AddDevice(BlockDeviceID device_id) {
32   last_seen_device_id = device_id;
33 #if PERFETTO_DCHECK_IS_ON()
34   seen_device_id = true;
35 #endif
36 }
37 
AddInode(Inode inode_number)38 void FtraceMetadata::AddInode(Inode inode_number) {
39 #if PERFETTO_DCHECK_IS_ON()
40   PERFETTO_DCHECK(seen_device_id);
41 #endif
42   static int32_t cached_pid = 0;
43   if (!cached_pid)
44     cached_pid = getpid();
45 
46   PERFETTO_DCHECK(last_seen_common_pid);
47   PERFETTO_DCHECK(cached_pid == getpid());
48   // Ignore own scanning activity.
49   if (cached_pid != last_seen_common_pid) {
50     inode_and_device.push_back(
51         std::make_pair(inode_number, last_seen_device_id));
52   }
53 }
54 
AddCommonPid(int32_t pid)55 void FtraceMetadata::AddCommonPid(int32_t pid) {
56   last_seen_common_pid = pid;
57   AddPid(pid);
58 }
59 
AddPid(int32_t pid)60 void FtraceMetadata::AddPid(int32_t pid) {
61   // Speculative optimization aginst repated pid's while keeping
62   // faster insertion than a set.
63   if (!pids.empty() && pids.back() == pid)
64     return;
65   pids.push_back(pid);
66 }
67 
AddRenamePid(int32_t pid)68 void FtraceMetadata::AddRenamePid(int32_t pid) {
69   rename_pids.push_back(pid);
70 }
71 
FinishEvent()72 void FtraceMetadata::FinishEvent() {
73   last_seen_device_id = 0;
74 #if PERFETTO_DCHECK_IS_ON()
75   seen_device_id = false;
76 #endif
77   last_seen_common_pid = 0;
78 }
79 
Clear()80 void FtraceMetadata::Clear() {
81   inode_and_device.clear();
82   pids.clear();
83   rename_pids.clear();
84   overwrite_count = 0;
85   FinishEvent();
86 }
87 
88 }  // namespace perfetto
89