/* * Copyright (C) 2018 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 <algorithm> #include <cstddef> #include <cstdint> #include <cstdlib> #include <cstring> #include <limits> #include <memory> #include <utility> #include "perfetto/base/compiler.h" #include "perfetto/base/logging.h" #include "perfetto/public/compiler.h" #include "src/trace_processor/importers/android_bugreport/android_log_event.h" #include "src/trace_processor/importers/common/parser_types.h" #include "src/trace_processor/importers/common/trace_parser.h" #include "src/trace_processor/importers/fuchsia/fuchsia_record.h" #include "src/trace_processor/importers/perf/record.h" #include "src/trace_processor/sorter/trace_sorter.h" #include "src/trace_processor/sorter/trace_token_buffer.h" #include "src/trace_processor/storage/stats.h" #include "src/trace_processor/types/trace_processor_context.h" #include "src/trace_processor/util/bump_allocator.h" namespace perfetto::trace_processor { TraceSorter::TraceSorter(TraceProcessorContext* context, SortingMode sorting_mode) : … { … } TraceSorter::~TraceSorter() { … } void TraceSorter::Queue::Sort() { … } // Removes all the events in |queues_| that are earlier than the given // packet index and moves them to the next parser stages, respecting global // timestamp order. This function is a "extract min from N sorted queues", with // some little cleverness: we know that events tend to be bursty, so events are // not going to be randomly distributed on the N |queues_|. // Upon each iteration this function finds the first two queues (if any) that // have the oldest events, and extracts events from the 1st until hitting the // min_ts of the 2nd. Imagine the queues are as follows: // // q0 {min_ts: 10 max_ts: 30} // q1 {min_ts:5 max_ts: 35} // q2 {min_ts: 12 max_ts: 40} // // We know that we can extract all events from q1 until we hit ts=10 without // looking at any other queue. After hitting ts=10, we need to re-look to all of // them to figure out the next min-event. // There are more suitable data structures to do this (e.g. keeping a min-heap // to avoid re-scanning all the queues all the times) but doesn't seem worth it. // With Android traces (that have 8 CPUs) this function accounts for ~1-3% cpu // time in a profiler. void TraceSorter::SortAndExtractEventsUntilAllocId( BumpAllocator::AllocId limit_alloc_id) { … } void TraceSorter::ParseTracePacket(TraceProcessorContext& context, const TimestampedEvent& event) { … } void TraceSorter::ParseEtwPacket(TraceProcessorContext& context, uint32_t cpu, const TimestampedEvent& event) { … } void TraceSorter::ParseFtracePacket(TraceProcessorContext& context, uint32_t cpu, const TimestampedEvent& event) { … } void TraceSorter::ExtractAndDiscardTokenizedObject( const TimestampedEvent& event) { … } void TraceSorter::MaybeExtractEvent(size_t min_machine_idx, size_t queue_idx, const TimestampedEvent& event) { … } } // namespace perfetto::trace_processor