Source code

Revision control

Copy as Markdown

Other Tools

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef FlowMarkers_h
#define FlowMarkers_h
#include "mozilla/BaseProfilerMarkers.h"
#include "mozilla/ProfilerLabels.h"
#include "mozilla/ProfilerMarkers.h"
#include "nsString.h"
#include "ETWTools.h"
namespace geckoprofiler::markers {
// These are convenience marker types for ad-hoc instrumentation.
// It's better to not use them and use a meaningful name for the flow.
class FlowMarker : public mozilla::BaseMarkerType<FlowMarker> {
public:
static constexpr const char* Name = "FlowMarker";
using MS = mozilla::MarkerSchema;
static constexpr MS::PayloadField PayloadFields[] = {
{"flow", MS::InputType::Uint64, "Flow", MS::Format::Flow,
MS::PayloadFlags::Searchable}};
static constexpr MS::Location Locations[] = {MS::Location::MarkerChart,
MS::Location::MarkerTable};
static constexpr const char* AllLabels =
"{marker.name} (flow={marker.data.flow})";
static constexpr MS::ETWMarkerGroup Group = MS::ETWMarkerGroup::Generic;
static void StreamJSONMarkerData(
mozilla::baseprofiler::SpliceableJSONWriter& aWriter, Flow aFlow) {
aWriter.FlowProperty("flow", aFlow);
}
};
class TerminatingFlowMarker
: public mozilla::BaseMarkerType<TerminatingFlowMarker> {
public:
static constexpr const char* Name = "TerminatingFlowMarker";
using MS = mozilla::MarkerSchema;
static constexpr MS::PayloadField PayloadFields[] = {
{"terminatingFlow", MS::InputType::Uint64, "Terminating Flow",
MS::Format::TerminatingFlow, MS::PayloadFlags::Searchable}};
static constexpr MS::Location Locations[] = {MS::Location::MarkerChart,
MS::Location::MarkerTable};
static constexpr const char* AllLabels =
"{marker.name} (terminatingFlow={marker.data.terminatingFlow})";
static constexpr MS::ETWMarkerGroup Group = MS::ETWMarkerGroup::Generic;
static void StreamJSONMarkerData(
mozilla::baseprofiler::SpliceableJSONWriter& aWriter, Flow aFlow) {
aWriter.FlowProperty("terminatingFlow", aFlow);
}
};
} // namespace geckoprofiler::markers
namespace mozilla {
class FlowStackMarker : public BaseMarkerType<FlowStackMarker> {
public:
static constexpr const char* Name = "FlowStackMarker";
using MS = MarkerSchema;
static constexpr MS::PayloadField PayloadFields[] = {
{"flow", MS::InputType::Uint64, "Flow", MS::Format::Flow,
MS::PayloadFlags::Searchable}};
static constexpr MS::Location Locations[] = {MS::Location::MarkerChart,
MS::Location::MarkerTable};
static constexpr const char* AllLabels =
"{marker.name} (flow={marker.data.flow})";
static constexpr MS::ETWMarkerGroup Group = MS::ETWMarkerGroup::Generic;
static constexpr bool IsStackBased = true;
static void StreamJSONMarkerData(
mozilla::baseprofiler::SpliceableJSONWriter& aWriter, Flow aFlow) {
aWriter.FlowProperty("flow", aFlow);
}
};
class TerminatingFlowStackMarker
: public BaseMarkerType<TerminatingFlowStackMarker> {
public:
static constexpr const char* Name = "TerminatingFlowStackMarker";
using MS = MarkerSchema;
static constexpr MS::PayloadField PayloadFields[] = {
{"flow", MS::InputType::Uint64, "Flow", MS::Format::TerminatingFlow,
MS::PayloadFlags::Searchable}};
static constexpr MS::Location Locations[] = {MS::Location::MarkerChart,
MS::Location::MarkerTable};
static constexpr const char* AllLabels =
"{marker.name} (flow={marker.data.flow})";
static constexpr MS::ETWMarkerGroup Group = MS::ETWMarkerGroup::Generic;
static constexpr bool IsStackBased = true;
static void StreamJSONMarkerData(
mozilla::baseprofiler::SpliceableJSONWriter& aWriter, Flow aFlow) {
aWriter.FlowProperty("flow", aFlow);
}
};
class FlowTextMarker : public BaseMarkerType<FlowTextMarker> {
public:
static constexpr const char* Name = "FlowTextMarker";
using MS = MarkerSchema;
static constexpr MS::PayloadField PayloadFields[] = {
{"name", MS::InputType::CString, "Details", MS::Format::String,
MS::PayloadFlags::Searchable},
{"flow", MS::InputType::Uint64, "Flow", MS::Format::Flow,
MS::PayloadFlags::Searchable}};
static constexpr MS::Location Locations[] = {MS::Location::MarkerChart,
MS::Location::MarkerTable};
static constexpr const char* TableLabel =
"{marker.name} - {marker.data.name}(flow={marker.data.flow})";
static constexpr const char* ChartLabel = "{marker.name}";
static constexpr MS::ETWMarkerGroup Group = MS::ETWMarkerGroup::Generic;
static void StreamJSONMarkerData(
mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
const ProfilerString8View& aText, Flow aFlow) {
aWriter.StringProperty("name", aText);
aWriter.FlowProperty("flow", aFlow);
}
};
class TerminatingFlowTextMarker
: public BaseMarkerType<TerminatingFlowTextMarker> {
public:
static constexpr const char* Name = "TerminatingFlowTextMarker";
static constexpr const char* Description =
"Generic text marker with terminating flow";
using MS = MarkerSchema;
static constexpr MS::PayloadField PayloadFields[] = {
{"name", MS::InputType::CString, "Details", MS::Format::String,
MS::PayloadFlags::Searchable},
{"terminatingFlow", MS::InputType::Uint64, "Terminating Flow",
MS::Format::TerminatingFlow, MS::PayloadFlags::Searchable}};
static constexpr MS::Location Locations[] = {MS::Location::MarkerChart,
MS::Location::MarkerTable};
static constexpr const char* TableLabel =
"{marker.name} - "
"{marker.data.name}(terminatingFlow={marker.data.terminatingFlow})";
static constexpr const char* ChartLabel = "{marker.name}";
static constexpr MS::ETWMarkerGroup Group = MS::ETWMarkerGroup::Generic;
static void StreamJSONMarkerData(
mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
const ProfilerString8View& aText, Flow aFlow) {
aWriter.StringProperty("name", aText);
aWriter.FlowProperty("terminatingFlow", aFlow);
}
};
class MOZ_RAII AutoProfilerFlowMarker {
public:
AutoProfilerFlowMarker(const char* aMarkerName,
const mozilla::MarkerCategory& aCategory, Flow aFlow)
: mMarkerName(aMarkerName), mCategory(aCategory), mFlow(aFlow) {
MOZ_ASSERT(mOptions.Timing().EndTime().IsNull(),
"AutoProfilerTextMarker options shouldn't have an end time");
if (profiler_is_active_and_unpaused() &&
mOptions.Timing().StartTime().IsNull()) {
mOptions.Set(mozilla::MarkerTiming::InstantNow());
}
}
~AutoProfilerFlowMarker() {
if (profiler_is_active_and_unpaused()) {
mOptions.TimingRef().SetIntervalEnd();
profiler_add_marker(
mozilla::ProfilerString8View::WrapNullTerminatedString(mMarkerName),
mCategory, std::move(mOptions), FlowStackMarker{}, mFlow);
}
}
public:
const char* mMarkerName;
mozilla::MarkerCategory mCategory;
mozilla::MarkerOptions mOptions;
Flow mFlow;
};
class MOZ_RAII AutoProfilerTerminatingFlowMarker {
public:
AutoProfilerTerminatingFlowMarker(const char* aMarkerName,
const mozilla::MarkerCategory& aCategory,
Flow aFlow)
: mMarkerName(aMarkerName), mCategory(aCategory), mFlow(aFlow) {
MOZ_ASSERT(mOptions.Timing().EndTime().IsNull(),
"AutoProfilerTextMarker options shouldn't have an end time");
if (profiler_is_active_and_unpaused() &&
mOptions.Timing().StartTime().IsNull()) {
mOptions.Set(mozilla::MarkerTiming::InstantNow());
}
}
~AutoProfilerTerminatingFlowMarker() {
if (profiler_is_active_and_unpaused()) {
mOptions.TimingRef().SetIntervalEnd();
profiler_add_marker(
mozilla::ProfilerString8View::WrapNullTerminatedString(mMarkerName),
mCategory, std::move(mOptions), TerminatingFlowStackMarker{}, mFlow);
}
}
public:
const char* mMarkerName;
mozilla::MarkerCategory mCategory;
mozilla::MarkerOptions mOptions;
Flow mFlow;
};
#define AUTO_PROFILER_FLOW_MARKER(markerName, categoryName, flow) \
AutoProfilerFlowMarker PROFILER_RAII( \
markerName, ::mozilla::baseprofiler::category::categoryName, flow)
#define AUTO_PROFILER_TERMINATING_FLOW_MARKER(markerName, categoryName, flow) \
AutoProfilerTerminatingFlowMarker PROFILER_RAII( \
markerName, ::mozilla::baseprofiler::category::categoryName, flow)
} // namespace mozilla
#endif // FlowMarkers_h