Lalit Maganti | caed37e | 2018-06-01 03:03:08 +0100 | [diff] [blame] | 1 | /* |
| 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 | |
| 21 | namespace perfetto { |
| 22 | namespace trace_processor { |
| 23 | |
Isabelle Taylor | 47328cf | 2018-06-12 14:33:59 +0100 | [diff] [blame^] | 24 | TraceStorage::TraceStorage() { |
| 25 | // Upid 0 is reserved for invalid processes. |
| 26 | unique_processes_.emplace_back(); |
| 27 | } |
| 28 | |
Lalit Maganti | 35622b7 | 2018-06-06 12:03:11 +0100 | [diff] [blame] | 29 | TraceStorage::~TraceStorage() {} |
Lalit Maganti | caed37e | 2018-06-01 03:03:08 +0100 | [diff] [blame] | 30 | |
Lalit Maganti | 35622b7 | 2018-06-06 12:03:11 +0100 | [diff] [blame] | 31 | void 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 Maganti | caed37e | 2018-06-01 03:03:08 +0100 | [diff] [blame] | 39 | |
Lalit Maganti | 35622b7 | 2018-06-06 12:03:11 +0100 | [diff] [blame] | 40 | // 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 Taylor | 47328cf | 2018-06-12 14:33:59 +0100 | [diff] [blame^] | 62 | void 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 | |
| 85 | TraceStorage::UniqueProcessRange TraceStorage::UpidsForPid(uint32_t pid) { |
| 86 | return pids_.equal_range(pid); |
| 87 | } |
| 88 | |
Lalit Maganti | 35622b7 | 2018-06-06 12:03:11 +0100 | [diff] [blame] | 89 | TraceStorage::StringId TraceStorage::InternString(const char* data, |
| 90 | size_t length) { |
Lalit Maganti | caed37e | 2018-06-01 03:03:08 +0100 | [diff] [blame] | 91 | uint32_t hash = 0; |
Lalit Maganti | 3ad1a6a | 2018-06-07 17:54:27 +0100 | [diff] [blame] | 92 | for (size_t i = 0; i < length; ++i) { |
Lalit Maganti | 35622b7 | 2018-06-06 12:03:11 +0100 | [diff] [blame] | 93 | hash = static_cast<uint32_t>(data[i]) + (hash * 31); |
Lalit Maganti | caed37e | 2018-06-01 03:03:08 +0100 | [diff] [blame] | 94 | } |
Lalit Maganti | 35622b7 | 2018-06-06 12:03:11 +0100 | [diff] [blame] | 95 | 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 Maganti | 3ad1a6a | 2018-06-07 17:54:27 +0100 | [diff] [blame] | 99 | PERFETTO_DCHECK( |
| 100 | strncmp(string_pool_[id_it->second].c_str(), data, length) == 0); |
Lalit Maganti | 35622b7 | 2018-06-06 12:03:11 +0100 | [diff] [blame] | 101 | return id_it->second; |
Lalit Maganti | caed37e | 2018-06-01 03:03:08 +0100 | [diff] [blame] | 102 | } |
Lalit Maganti | 35622b7 | 2018-06-06 12:03:11 +0100 | [diff] [blame] | 103 | 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 Maganti | caed37e | 2018-06-01 03:03:08 +0100 | [diff] [blame] | 107 | } |
| 108 | |
| 109 | } // namespace trace_processor |
| 110 | } // namespace perfetto |