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_PARSER_H_ 18 #define SRC_TRACE_PROCESSOR_IMPORTERS_FUCHSIA_FUCHSIA_TRACE_PARSER_H_ 19 20 #include <cstdint> 21 #include <functional> 22 #include <optional> 23 #include <unordered_map> 24 #include <vector> 25 26 #include "perfetto/ext/base/string_view.h" 27 #include "src/trace_processor/importers/common/trace_parser.h" 28 #include "src/trace_processor/importers/fuchsia/fuchsia_record.h" 29 #include "src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h" 30 #include "src/trace_processor/storage/trace_storage.h" 31 #include "src/trace_processor/tables/sched_tables_py.h" 32 33 namespace perfetto::trace_processor { 34 35 class TraceProcessorContext; 36 37 class FuchsiaTraceParser : public FuchsiaRecordParser { 38 public: 39 explicit FuchsiaTraceParser(TraceProcessorContext*); 40 ~FuchsiaTraceParser() override; 41 42 // Tracks the state for updating sched slice and thread state tables. 43 struct Thread { ThreadThread44 explicit Thread(uint64_t tid) : info{0, tid} {} 45 46 FuchsiaThreadInfo info; 47 int64_t last_ts{0}; 48 std::optional<tables::SchedSliceTable::RowNumber> last_slice_row; 49 std::optional<tables::ThreadStateTable::RowNumber> last_state_row; 50 }; 51 52 void ParseFuchsiaRecord(int64_t timestamp, FuchsiaRecord fr) override; 53 54 // Allocates or returns an existing Thread instance for the given tid. GetThread(uint64_t tid)55 Thread& GetThread(uint64_t tid) { 56 auto search = threads_.find(tid); 57 if (search != threads_.end()) { 58 return search->second; 59 } 60 auto result = threads_.emplace(tid, tid); 61 return result.first->second; 62 } 63 64 struct Arg { 65 StringId name; 66 fuchsia_trace_utils::ArgValue value; 67 }; 68 69 // Utility to parse record arguments. Exposed here to provide consistent 70 // parsing between trace parsing and tokenization. 71 // 72 // Returns an empty optional on error, otherwise a vector containing zero or 73 // more arguments. 74 static std::optional<std::vector<Arg>> ParseArgs( 75 fuchsia_trace_utils::RecordCursor& cursor, 76 uint32_t n_args, 77 std::function<StringId(base::StringView string)> intern_string, 78 std::function<StringId(uint32_t index)> get_string); 79 80 private: 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 StringId IdForOutgoingThreadState(uint32_t state); 89 90 TraceProcessorContext* const context_; 91 92 // Interned string ids for record arguments. 93 const StringId weight_id_; 94 const StringId incoming_weight_id_; 95 const StringId outgoing_weight_id_; 96 97 // Interned string ids for the relevant thread states. 98 const StringId running_string_id_; 99 const StringId runnable_string_id_; 100 const StringId waking_string_id_; 101 const StringId blocked_string_id_; 102 const StringId suspended_string_id_; 103 const StringId exit_dying_string_id_; 104 const StringId exit_dead_string_id_; 105 106 // Map from tid to Thread. 107 std::unordered_map<uint64_t, Thread> threads_; 108 }; 109 110 } // namespace perfetto::trace_processor 111 112 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_FUCHSIA_FUCHSIA_TRACE_PARSER_H_ 113