[go: nahoru, domu]

blob: 20e64bf73c4d0aff93a97c43ca2da8f974b79108 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_TRACK_EVENT_THREAD_LOCAL_EVENT_SINK_H_
#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_TRACK_EVENT_THREAD_LOCAL_EVENT_SINK_H_
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include "base/trace_event/trace_event.h"
#include "base/component_export.h"
#include "base/threading/thread_id_name_manager.h"
#include "base/time/time.h"
#include "base/trace_event/typed_macros.h"
#include "base/trace_event/typed_macros_embedder_support.h"
#include "services/tracing/public/cpp/perfetto/interning_index.h"
#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h"
#include "third_party/perfetto/include/perfetto/protozero/message_handle.h"
#include "third_party/perfetto/include/perfetto/tracing/event_context.h"
#include "third_party/perfetto/protos/perfetto/trace/interned_data/interned_data.pbzero.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/counter_descriptor.pbzero.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/track_event.pbzero.h"
namespace tracing {
// ThreadLocalEventSink that emits TrackEvent protos.
class COMPONENT_EXPORT(TRACING_CPP) TrackEventThreadLocalEventSink
: public base::ThreadIdNameManager::Observer,
public base::trace_event::TrackEventHandle::CompletionListener,
public base::trace_event::TracePacketHandle::CompletionListener {
public:
TrackEventThreadLocalEventSink(
std::unique_ptr<perfetto::TraceWriter> trace_writer,
uint32_t session_id,
bool disable_interning,
bool proto_writer_filtering_enabled);
TrackEventThreadLocalEventSink(const TrackEventThreadLocalEventSink&) =
delete;
TrackEventThreadLocalEventSink& operator=(
const TrackEventThreadLocalEventSink&) = delete;
~TrackEventThreadLocalEventSink() override;
// Resets emitted incremental state on all threads and causes incremental data
// (e.g. interning index entries and a ThreadDescriptor) to be emitted again.
static void ClearIncrementalState();
void AddLegacyTraceEvent(base::trace_event::TraceEvent* trace_event,
base::trace_event::TraceEventHandle* handle);
base::trace_event::TrackEventHandle AddTypedTraceEvent(
base::trace_event::TraceEvent* trace_event);
base::trace_event::TracePacketHandle AddTracePacket();
void AddEmptyPacket();
void UpdateDuration(const unsigned char* category_group_enabled,
const char* name,
base::trace_event::TraceEventHandle handle,
int thread_id,
bool explicit_timestamps,
const base::TimeTicks& now,
const base::ThreadTicks& thread_now);
void Flush();
uint32_t session_id() const { return session_id_; }
// ThreadIdNameManager::Observer implementation:
void OnThreadNameChanged(const char* name) override;
// base::trace_event::TrackEventHandle::CompletionListener implementation:
void OnTrackEventCompleted() override;
// base::trace_event::TracePacketHandle::CompletionListener implementation:
void OnTracePacketCompleted() override;
private:
static constexpr size_t kMaxCompleteEventDepth = 30;
enum class PacketType { kDefault, kEmpty };
perfetto::TraceWriter::TracePacketHandle NewTracePacket(
PacketType = PacketType::kDefault);
// Emit any necessary descriptors that we haven't emitted yet and, if
// required, perform an incremental state reset.
void UpdateIncrementalStateIfNeeded(
base::trace_event::TraceEvent* trace_event);
// Fills in all the fields in |trace_packet| that can be directly deduced from
// |trace_event|. Also fills all updates needed to be emitted into the
// |InternedData| field into |pending_interning_updates_|. Returns a pointer
// to the prepared TrackEvent proto, on which the caller may set further
// fields.
perfetto::protos::pbzero::TrackEvent* PrepareTrackEvent(
base::trace_event::TraceEvent* trace_event,
base::trace_event::TraceEventHandle* handle,
protozero::MessageHandle<perfetto::protos::pbzero::TracePacket>*
trace_packet);
void EmitThreadTrackDescriptor(base::trace_event::TraceEvent* trace_event,
base::TimeTicks timestamp,
const char* maybe_new_name = nullptr);
void EmitCounterTrackDescriptor(
base::TimeTicks timestamp,
uint64_t thread_track_uuid,
uint64_t counter_track_uuid_bit,
perfetto::protos::pbzero::CounterDescriptor::BuiltinCounterType
counter_type,
uint64_t unit_multiplier = 0u);
void DoResetIncrementalState(base::trace_event::TraceEvent* trace_event,
bool explicit_timestamp);
void SetPacketTimestamp(
protozero::MessageHandle<perfetto::protos::pbzero::TracePacket>*
trace_packet,
base::TimeTicks timestamp,
bool force_absolute_timestamp = false);
// Add a copy of this string to |copied_strings_| and return a pointer which
// is valid until |copied_strings_| are cleared.
const char* CopyString(const std::string& value);
// Write interned data (both from |incremental_state_| and interned indexes
// into the given packet.
void WriteInternedDataIntoTracePacket(
perfetto::protos::pbzero::TracePacket* packet);
// Track event interning state.
perfetto::internal::TrackEventIncrementalState incremental_state_;
std::vector<uint64_t> extra_emitted_track_descriptor_uuids_;
static std::atomic<uint32_t> incremental_state_reset_id_;
bool reset_incremental_state_ = true;
uint32_t last_incremental_state_reset_id_ = 0;
base::TimeTicks last_timestamp_;
base::ThreadTicks last_thread_time_;
base::ProcessId process_id_;
base::PlatformThreadId thread_id_;
std::string thread_name_;
perfetto::protos::pbzero::ChromeThreadDescriptor::ThreadType thread_type_ =
perfetto::protos::pbzero::ChromeThreadDescriptor::THREAD_UNSPECIFIED;
const bool privacy_filtering_enabled_;
std::unique_ptr<perfetto::TraceWriter> trace_writer_;
uint32_t session_id_;
bool disable_interning_;
uint32_t sink_id_;
bool last_packet_was_empty_ = true;
// Stores the trace packet handle for a typed TrackEvent until the TrackEvent
// was finalized after the code in //base filled its typed argument fields.
perfetto::TraceWriter::TracePacketHandle pending_trace_packet_;
};
} // namespace tracing
#endif // SERVICES_TRACING_PUBLIC_CPP_PERFETTO_TRACK_EVENT_THREAD_LOCAL_EVENT_SINK_H_