blob: 21bda02af2a0d723468fe9263c91befa34f14dcf [file] [log] [blame]
/*
* Copyright (C) 2021 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.
*/
#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
#include "perfetto/tracing/event_context.h"
#include "perfetto/tracing/track.h"
#include <functional>
namespace perfetto {
// A helper to add |flow_id| as a non-terminating flow id to TRACE_EVENT
// inline: TRACE_EVENT(..., perfetto::Flow::ProcessScoped(42));
class Flow {
public:
// |flow_id| which is local within a given process (e.g. atomic counter xor'ed
// with feature-specific value). This value is xor'ed with Perfetto's internal
// process track id to attempt to ensure that it's globally-unique.
static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
ProcessScoped(uint64_t flow_id) {
return Global(flow_id ^ Track::process_uuid);
}
// Same as above, but construct an id from a pointer.
// NOTE: After the object is destroyed, the value of |ptr| can be reused for a
// different object (in particular if the object is allocated on a stack).
// Please ensure that you emit a trace event with the flow id of
// perfetto::TerminatingFlow::FromPointer(this) from the destructor of the
// object to avoid accidental conflicts.
static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
FromPointer(void* ptr) {
return ProcessScoped(reinterpret_cast<uintptr_t>(ptr));
}
// Add the |flow_id|. The caller is responsible for ensuring that it's
// globally-unique (e.g. by generating a random value). This should be used
// only for flow events which cross the process boundary (e.g. IPCs).
static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
Global(uint64_t flow_id) {
return [flow_id](perfetto::EventContext& ctx) {
ctx.event()->add_flow_ids(flow_id);
};
}
// TODO(altimin): Remove once converting a single usage in Chromium.
explicit constexpr Flow(uint64_t flow_id) : flow_id_(flow_id) {}
void operator()(EventContext& ctx) { ctx.event()->add_flow_ids(flow_id_); }
private:
uint64_t flow_id_;
};
// A helper to add a given |flow_id| as a terminating flow to TRACE_EVENT
// inline.
class TerminatingFlow {
public:
// See `Flow::ProcessScoped(uint64_t)`.
static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
ProcessScoped(uint64_t flow_id) {
return Global(flow_id ^ Track::process_uuid);
}
// See `Flow::FromPointer(void*)`.
static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
FromPointer(void* ptr) {
return ProcessScoped(reinterpret_cast<uintptr_t>(ptr));
}
// See `Flow::Global(uint64_t)`.
static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
Global(uint64_t flow_id) {
return [flow_id](perfetto::EventContext& ctx) {
ctx.event()->add_terminating_flow_ids(flow_id);
};
}
};
} // namespace perfetto
#endif // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_