blob: b4a856cd0e32f90c77757c0c86807dcef6e5f6ad [file] [log] [blame]
Lalit Maganticaed37e2018-06-01 03:03:08 +01001/*
2 * Copyright (C) 2018 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/trace_processor/trace_storage.h"
18
19#include <string.h>
20
21namespace perfetto {
22namespace trace_processor {
23
Isabelle Taylor47328cf2018-06-12 14:33:59 +010024TraceStorage::TraceStorage() {
25 // Upid 0 is reserved for invalid processes.
26 unique_processes_.emplace_back();
27}
28
Lalit Maganti35622b72018-06-06 12:03:11 +010029TraceStorage::~TraceStorage() {}
Lalit Maganticaed37e2018-06-01 03:03:08 +010030
Lalit Maganti35622b72018-06-06 12:03:11 +010031void TraceStorage::PushSchedSwitch(uint32_t cpu,
32 uint64_t timestamp,
33 uint32_t prev_pid,
34 uint32_t prev_state,
35 const char* prev_comm,
36 size_t prev_comm_len,
37 uint32_t next_pid) {
38 SchedSwitchEvent* prev = &last_sched_per_cpu_[cpu];
Lalit Maganticaed37e2018-06-01 03:03:08 +010039
Lalit Maganti35622b72018-06-06 12:03:11 +010040 // If we had a valid previous event, then inform the storage about the
41 // slice.
42 if (prev->valid()) {
43 uint64_t duration = timestamp - prev->timestamp;
44 cpu_events_[cpu].AddSlice(prev->timestamp, duration, prev->prev_thread_id);
45 }
46
47 // If the this events previous pid does not match the previous event's next
48 // pid, make a note of this.
49 if (prev_pid != prev->next_pid) {
50 stats_.mismatched_sched_switch_tids_++;
51 }
52
53 // Update the map with the current event.
54 prev->cpu = cpu;
55 prev->timestamp = timestamp;
56 prev->prev_pid = prev_pid;
57 prev->prev_state = prev_state;
58 prev->prev_thread_id = InternString(prev_comm, prev_comm_len);
59 prev->next_pid = next_pid;
60}
61
Isabelle Taylor47328cf2018-06-12 14:33:59 +010062void TraceStorage::PushProcess(uint32_t pid,
63 const char* process_name,
64 size_t process_name_len) {
65 bool exists = false;
66 auto pids_pair = pids_.equal_range(pid);
67 auto proc_name_id = InternString(process_name, process_name_len);
68 if (pids_pair.first != pids_pair.second) {
69 UniquePid prev_upid = std::prev(pids_pair.second)->second;
70 // If the previous process with the same pid also has the same name,
71 // then no action needs to be taken.
72 exists = unique_processes_[prev_upid].process_name_id == proc_name_id;
73 }
74
75 if (!exists) {
76 pids_.emplace(pid, current_upid_++);
77 ProcessEntry new_process;
78 new_process.start_ns = 0;
79 new_process.end_ns = 0;
80 new_process.process_name_id = proc_name_id;
81 unique_processes_.emplace_back(std::move(new_process));
82 }
83}
84
85TraceStorage::UniqueProcessRange TraceStorage::UpidsForPid(uint32_t pid) {
86 return pids_.equal_range(pid);
87}
88
Lalit Maganti35622b72018-06-06 12:03:11 +010089TraceStorage::StringId TraceStorage::InternString(const char* data,
90 size_t length) {
Lalit Maganticaed37e2018-06-01 03:03:08 +010091 uint32_t hash = 0;
Lalit Maganti3ad1a6a2018-06-07 17:54:27 +010092 for (size_t i = 0; i < length; ++i) {
Lalit Maganti35622b72018-06-06 12:03:11 +010093 hash = static_cast<uint32_t>(data[i]) + (hash * 31);
Lalit Maganticaed37e2018-06-01 03:03:08 +010094 }
Lalit Maganti35622b72018-06-06 12:03:11 +010095 auto id_it = string_index_.find(hash);
96 if (id_it != string_index_.end()) {
97 // TODO(lalitm): check if this DCHECK happens and if so, then change hash
98 // to 64bit.
Lalit Maganti3ad1a6a2018-06-07 17:54:27 +010099 PERFETTO_DCHECK(
100 strncmp(string_pool_[id_it->second].c_str(), data, length) == 0);
Lalit Maganti35622b72018-06-06 12:03:11 +0100101 return id_it->second;
Lalit Maganticaed37e2018-06-01 03:03:08 +0100102 }
Lalit Maganti35622b72018-06-06 12:03:11 +0100103 string_pool_.emplace_back(data, length);
104 StringId string_id = string_pool_.size() - 1;
105 string_index_.emplace(hash, string_id);
106 return string_id;
Lalit Maganticaed37e2018-06-01 03:03:08 +0100107}
108
109} // namespace trace_processor
110} // namespace perfetto