1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif
#ifndef BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
#define BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
#include <stdint.h>
#include <iosfwd>
#include <string>
#include "base/base_export.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/process/process_handle.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/trace_event/common/trace_event_common.h"
#include "base/trace_event/trace_arguments.h"
namespace base::trace_event {
using ArgumentNameFilterPredicate =
base::RepeatingCallback<bool(const char* arg_name)>;
using ArgumentFilterPredicate =
base::RepeatingCallback<bool(const char* category_group_name,
const char* event_name,
ArgumentNameFilterPredicate*)>;
using MetadataFilterPredicate =
base::RepeatingCallback<bool(const std::string& metadata_name)>;
struct TraceEventHandle {
uint64_t dummy;
};
class BASE_EXPORT TraceEvent {
public:
TraceEvent();
TraceEvent(PlatformThreadId thread_id,
TimeTicks timestamp,
ThreadTicks thread_timestamp,
char phase,
const unsigned char* category_group_enabled,
const char* name,
const char* scope,
unsigned long long id,
TraceArguments* args,
unsigned int flags);
TraceEvent(const TraceEvent&) = delete;
TraceEvent& operator=(const TraceEvent&) = delete;
~TraceEvent();
// Allow move operations.
TraceEvent(TraceEvent&&) noexcept;
TraceEvent& operator=(TraceEvent&&) noexcept;
// Reset instance to empty state.
void Reset();
// Reset instance to new state. This is equivalent but slightly more
// efficient than doing a move assignment, since it avoids creating
// temporary copies. I.e. compare these two statements:
//
// event = TraceEvent(thread_id, ....); // Create and destroy temporary.
// event.Reset(thread_id, ...); // Direct re-initialization.
//
void Reset(PlatformThreadId thread_id,
TimeTicks timestamp,
ThreadTicks thread_timestamp,
char phase,
const unsigned char* category_group_enabled,
const char* name,
const char* scope,
unsigned long long id,
TraceArguments* args,
unsigned int flags);
void UpdateDuration(const TimeTicks& now, const ThreadTicks& thread_now);
// Serialize event data to JSON
void AppendAsJSON(
std::string* out,
const ArgumentFilterPredicate& argument_filter_predicate) const;
void AppendPrettyPrinted(std::ostringstream* out) const;
TimeTicks timestamp() const { return timestamp_; }
ThreadTicks thread_timestamp() const { return thread_timestamp_; }
char phase() const { return phase_; }
PlatformThreadId thread_id() const { return thread_id_; }
ProcessId process_id() const { return process_id_; }
TimeDelta duration() const { return duration_; }
TimeDelta thread_duration() const { return thread_duration_; }
const char* scope() const { return scope_; }
unsigned long long id() const { return id_; }
unsigned int flags() const { return flags_; }
const unsigned char* category_group_enabled() const {
return category_group_enabled_;
}
const char* name() const { return name_; }
size_t arg_size() const { return args_.size(); }
unsigned char arg_type(size_t index) const { return args_.types()[index]; }
const char* arg_name(size_t index) const { return args_.names()[index]; }
const TraceValue& arg_value(size_t index) const {
return args_.values()[index];
}
ConvertableToTraceFormat* arg_convertible_value(size_t index) {
return (arg_type(index) == TRACE_VALUE_TYPE_CONVERTABLE)
? arg_value(index).as_convertable
: nullptr;
}
private:
void InitArgs(TraceArguments* args);
// Note: these are ordered by size (largest first) for optimal packing.
TimeTicks timestamp_ = TimeTicks();
ThreadTicks thread_timestamp_ = ThreadTicks();
TimeDelta duration_ = TimeDelta::FromInternalValue(-1);
TimeDelta thread_duration_ = TimeDelta();
// scope_ and id_ can be used to store phase-specific data.
// The following should be default-initialized to the expression
// trace_event_internal::kGlobalScope, which is nullptr, but its definition
// cannot be included here due to cyclical header dependencies.
// The equivalence is checked with a static_assert() in trace_event_impl.cc.
const char* scope_ = nullptr;
unsigned long long id_ = 0u;
raw_ptr<const unsigned char> category_group_enabled_ = nullptr;
const char* name_ = nullptr;
StringStorage parameter_copy_storage_;
TraceArguments args_;
// Depending on TRACE_EVENT_FLAG_HAS_PROCESS_ID the event will have either:
// tid: thread_id_, pid: current_process_id (default case).
// tid: -1, pid: process_id_ (when flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID).
union {
PlatformThreadId thread_id_ = kInvalidThreadId;
ProcessId process_id_;
};
unsigned int flags_ = 0;
char phase_ = TRACE_EVENT_PHASE_BEGIN;
};
} // namespace base::trace_event
#endif // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
|