1 /* 2 * Copyright (C) 2019 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_PROCESSOR_IMPORTERS_FUCHSIA_FUCHSIA_TRACE_TOKENIZER_H_ 18 #define SRC_TRACE_PROCESSOR_IMPORTERS_FUCHSIA_FUCHSIA_TRACE_TOKENIZER_H_ 19 20 #include "src/trace_processor/importers/common/chunked_trace_reader.h" 21 #include "src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h" 22 #include "src/trace_processor/importers/proto/proto_trace_reader.h" 23 #include "src/trace_processor/storage/trace_storage.h" 24 #include "src/trace_processor/types/task_state.h" 25 26 namespace perfetto { 27 namespace trace_processor { 28 29 class TraceProcessorContext; 30 31 // The Fuchsia trace format is documented at 32 // https://fuchsia.googlesource.com/fuchsia/+/HEAD/docs/development/tracing/trace-format/README.md 33 class FuchsiaTraceTokenizer : public ChunkedTraceReader { 34 public: 35 static constexpr TraceType kTraceType = TraceType::kFuchsiaTraceType; 36 explicit FuchsiaTraceTokenizer(TraceProcessorContext*); 37 ~FuchsiaTraceTokenizer() override; 38 39 // ChunkedTraceReader implementation 40 util::Status Parse(TraceBlobView) override; 41 void NotifyEndOfFile() override; 42 43 private: 44 struct ProviderInfo { 45 std::string name; 46 47 std::unordered_map<uint64_t, StringId> string_table; 48 std::unordered_map<uint64_t, FuchsiaThreadInfo> thread_table; 49 50 // Returns a StringId for the given FXT string ref id. GetStringProviderInfo51 StringId GetString(uint64_t string_ref) { 52 auto search = string_table.find(string_ref); 53 if (search != string_table.end()) { 54 return search->second; 55 } 56 return kNullStringId; 57 } 58 59 // Returns a FuchsiaThreadInfo for the given FXT thread ref id. GetThreadProviderInfo60 FuchsiaThreadInfo GetThread(uint64_t thread_ref) { 61 auto search = thread_table.find(thread_ref); 62 if (search != thread_table.end()) { 63 return search->second; 64 } 65 return {0, 0}; 66 } 67 68 uint64_t ticks_per_second = 1000000000; 69 }; 70 71 // Tracks the state for updating sched slice and thread state tables. 72 struct Thread { ThreadThread73 explicit Thread(uint64_t tid) : info{0, tid} {} 74 75 FuchsiaThreadInfo info; 76 int64_t last_ts{0}; 77 std::optional<tables::SchedSliceTable::RowNumber> last_slice_row; 78 std::optional<tables::ThreadStateTable::RowNumber> last_state_row; 79 }; 80 81 void SwitchFrom(Thread* thread, 82 int64_t ts, 83 uint32_t cpu, 84 uint32_t thread_state); 85 void SwitchTo(Thread* thread, int64_t ts, uint32_t cpu, int32_t weight); 86 void Wake(Thread* thread, int64_t ts, uint32_t cpu); 87 88 // Allocates or returns an existing Thread instance for the given tid. GetThread(uint64_t tid)89 Thread& GetThread(uint64_t tid) { 90 auto search = threads_.find(tid); 91 if (search != threads_.end()) { 92 return search->second; 93 } 94 auto result = threads_.emplace(tid, tid); 95 return result.first->second; 96 } 97 98 void ParseRecord(TraceBlobView); 99 void RegisterProvider(uint32_t, std::string); 100 StringId IdForOutgoingThreadState(uint32_t state); 101 102 TraceProcessorContext* const context_; 103 std::vector<uint8_t> leftover_bytes_; 104 105 // Proto reader creates state that the blobs it emits reference, so the 106 // proto_reader needs to live for as long as the tokenizer. 107 ProtoTraceReader proto_reader_; 108 std::vector<uint8_t> proto_trace_data_; 109 110 std::unordered_map<uint32_t, std::unique_ptr<ProviderInfo>> providers_; 111 ProviderInfo* current_provider_; 112 113 // Interned string ids for the relevant thread states. 114 StringId running_string_id_; 115 StringId runnable_string_id_; 116 StringId preempted_string_id_; 117 StringId waking_string_id_; 118 StringId blocked_string_id_; 119 StringId suspended_string_id_; 120 StringId exit_dying_string_id_; 121 StringId exit_dead_string_id_; 122 123 // Interned string ids for record arguments. 124 StringId incoming_weight_id_; 125 StringId outgoing_weight_id_; 126 StringId weight_id_; 127 StringId process_id_; 128 129 // Map from tid to Thread. 130 std::unordered_map<uint64_t, Thread> threads_; 131 }; 132 133 } // namespace trace_processor 134 } // namespace perfetto 135 136 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_FUCHSIA_FUCHSIA_TRACE_TOKENIZER_H_ 137