aboutsummaryrefslogtreecommitdiff
path: root/src/trace_processor/importers/ftrace/ftrace_tokenizer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/trace_processor/importers/ftrace/ftrace_tokenizer.cc')
-rw-r--r--src/trace_processor/importers/ftrace/ftrace_tokenizer.cc212
1 files changed, 0 insertions, 212 deletions
diff --git a/src/trace_processor/importers/ftrace/ftrace_tokenizer.cc b/src/trace_processor/importers/ftrace/ftrace_tokenizer.cc
deleted file mode 100644
index 4319e2df3..000000000
--- a/src/trace_processor/importers/ftrace/ftrace_tokenizer.cc
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_processor/importers/ftrace/ftrace_tokenizer.h"
-
-#include "perfetto/base/logging.h"
-#include "perfetto/protozero/proto_decoder.h"
-#include "perfetto/protozero/proto_utils.h"
-#include "src/trace_processor/stats.h"
-#include "src/trace_processor/trace_sorter.h"
-#include "src/trace_processor/trace_storage.h"
-
-#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
-#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-using protozero::ProtoDecoder;
-using protozero::proto_utils::MakeTagLengthDelimited;
-using protozero::proto_utils::MakeTagVarInt;
-using protozero::proto_utils::ParseVarInt;
-
-PERFETTO_ALWAYS_INLINE
-void FtraceTokenizer::TokenizeFtraceBundle(TraceBlobView bundle) {
- protos::pbzero::FtraceEventBundle::Decoder decoder(bundle.data(),
- bundle.length());
-
- if (PERFETTO_UNLIKELY(!decoder.has_cpu())) {
- PERFETTO_ELOG("CPU field not found in FtraceEventBundle");
- context_->storage->IncrementStats(stats::ftrace_bundle_tokenizer_errors);
- return;
- }
-
- uint32_t cpu = decoder.cpu();
- if (PERFETTO_UNLIKELY(cpu > base::kMaxCpus)) {
- PERFETTO_ELOG("CPU larger than kMaxCpus (%u > %zu)", cpu, base::kMaxCpus);
- return;
- }
-
- if (decoder.has_compact_sched()) {
- TokenizeFtraceCompactSched(cpu, decoder.compact_sched().data,
- decoder.compact_sched().size);
- }
-
- for (auto it = decoder.event(); it; ++it) {
- protozero::ConstBytes event = *it;
- size_t off = bundle.offset_of(event.data);
- TokenizeFtraceEvent(cpu, bundle.slice(off, event.size));
- }
- context_->sorter->FinalizeFtraceEventBatch(cpu);
-}
-
-PERFETTO_ALWAYS_INLINE
-void FtraceTokenizer::TokenizeFtraceEvent(uint32_t cpu, TraceBlobView event) {
- constexpr auto kTimestampFieldNumber =
- protos::pbzero::FtraceEvent::kTimestampFieldNumber;
- const uint8_t* data = event.data();
- const size_t length = event.length();
- ProtoDecoder decoder(data, length);
- uint64_t raw_timestamp = 0;
- bool timestamp_found = false;
-
- // Speculate on the fact that the timestamp is often the 1st field of the
- // event.
- constexpr auto timestampFieldTag = MakeTagVarInt(kTimestampFieldNumber);
- if (PERFETTO_LIKELY(length > 10 && data[0] == timestampFieldTag)) {
- // Fastpath.
- const uint8_t* next = ParseVarInt(data + 1, data + 11, &raw_timestamp);
- timestamp_found = next != data + 1;
- decoder.Reset(next);
- } else {
- // Slowpath.
- if (auto ts_field = decoder.FindField(kTimestampFieldNumber)) {
- timestamp_found = true;
- raw_timestamp = ts_field.as_uint64();
- }
- }
-
- if (PERFETTO_UNLIKELY(!timestamp_found)) {
- PERFETTO_ELOG("Timestamp field not found in FtraceEvent");
- context_->storage->IncrementStats(stats::ftrace_bundle_tokenizer_errors);
- return;
- }
-
- int64_t timestamp = static_cast<int64_t>(raw_timestamp);
-
- // We don't need to parse this packet, just push it to be sorted with
- // the timestamp.
- context_->sorter->PushFtraceEvent(cpu, timestamp, std::move(event));
-}
-
-PERFETTO_ALWAYS_INLINE
-void FtraceTokenizer::TokenizeFtraceCompactSched(uint32_t cpu,
- const uint8_t* data,
- size_t size) {
- protos::pbzero::FtraceEventBundle::CompactSched::Decoder compact_sched(data,
- size);
- // Build the interning table for comm fields.
- std::vector<StringId> string_table;
- string_table.reserve(512);
- for (auto it = compact_sched.intern_table(); it; it++) {
- StringId value = context_->storage->InternString(*it);
- string_table.push_back(value);
- }
-
- TokenizeFtraceCompactSchedSwitch(cpu, compact_sched, string_table);
- TokenizeFtraceCompactSchedWaking(cpu, compact_sched, string_table);
-}
-
-void FtraceTokenizer::TokenizeFtraceCompactSchedSwitch(
- uint32_t cpu,
- const protos::pbzero::FtraceEventBundle::CompactSched::Decoder& compact,
- const std::vector<StringId>& string_table) {
- // Accumulator for timestamp deltas.
- int64_t timestamp_acc = 0;
-
- // The events' fields are stored in a structure-of-arrays style, using packed
- // repeated fields. Walk each repeated field in step to recover individual
- // events.
- bool parse_error = false;
- auto timestamp_it = compact.switch_timestamp(&parse_error);
- auto pstate_it = compact.switch_prev_state(&parse_error);
- auto npid_it = compact.switch_next_pid(&parse_error);
- auto nprio_it = compact.switch_next_prio(&parse_error);
- auto comm_it = compact.switch_next_comm_index(&parse_error);
- for (; timestamp_it && pstate_it && npid_it && nprio_it && comm_it;
- ++timestamp_it, ++pstate_it, ++npid_it, ++nprio_it, ++comm_it) {
- InlineSchedSwitch event{};
-
- // delta-encoded timestamp
- timestamp_acc += static_cast<int64_t>(*timestamp_it);
- int64_t event_timestamp = timestamp_acc;
-
- // index into the interned string table
- PERFETTO_DCHECK(*comm_it < string_table.size());
- event.next_comm = string_table[*comm_it];
-
- event.prev_state = *pstate_it;
- event.next_pid = *npid_it;
- event.next_prio = *nprio_it;
-
- context_->sorter->PushInlineFtraceEvent(cpu, event_timestamp,
- InlineEvent::SchedSwitch(event));
- }
-
- // Check that all packed buffers were decoded correctly, and fully.
- bool sizes_match =
- !timestamp_it && !pstate_it && !npid_it && !nprio_it && !comm_it;
- if (parse_error || !sizes_match)
- context_->storage->IncrementStats(stats::compact_sched_has_parse_errors);
-}
-
-void FtraceTokenizer::TokenizeFtraceCompactSchedWaking(
- uint32_t cpu,
- const protos::pbzero::FtraceEventBundle::CompactSched::Decoder& compact,
- const std::vector<StringId>& string_table) {
- // Accumulator for timestamp deltas.
- int64_t timestamp_acc = 0;
-
- // The events' fields are stored in a structure-of-arrays style, using packed
- // repeated fields. Walk each repeated field in step to recover individual
- // events.
- bool parse_error = false;
- auto timestamp_it = compact.waking_timestamp(&parse_error);
- auto pid_it = compact.waking_pid(&parse_error);
- auto tcpu_it = compact.waking_target_cpu(&parse_error);
- auto prio_it = compact.waking_prio(&parse_error);
- auto comm_it = compact.waking_comm_index(&parse_error);
-
- for (; timestamp_it && pid_it && tcpu_it && prio_it && comm_it;
- ++timestamp_it, ++pid_it, ++tcpu_it, ++prio_it, ++comm_it) {
- InlineSchedWaking event{};
-
- // delta-encoded timestamp
- timestamp_acc += static_cast<int64_t>(*timestamp_it);
- int64_t event_timestamp = timestamp_acc;
-
- // index into the interned string table
- PERFETTO_DCHECK(*comm_it < string_table.size());
- event.comm = string_table[*comm_it];
-
- event.pid = *pid_it;
- event.target_cpu = *tcpu_it;
- event.prio = *prio_it;
-
- context_->sorter->PushInlineFtraceEvent(cpu, event_timestamp,
- InlineEvent::SchedWaking(event));
- }
-
- // Check that all packed buffers were decoded correctly, and fully.
- bool sizes_match =
- !timestamp_it && !pid_it && !tcpu_it && !prio_it && !comm_it;
- if (parse_error || !sizes_match)
- context_->storage->IncrementStats(stats::compact_sched_has_parse_errors);
-}
-
-} // namespace trace_processor
-} // namespace perfetto