Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  Perfetto.h

  Sprache: C
 

/* 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 mozilla_Perfetto_h
#define mozilla_Perfetto_h

#ifdef MOZ_PERFETTO
#  include "mozilla/BaseProfilerMarkers.h"
#  include "mozilla/Flow.h"
#  include "mozilla/TimeStamp.h"
#  include "nsString.h"
#  include "nsPrintfCString.h"
#  include "perfetto/perfetto.h"

// Initialization is called when a content process is created.
// This can be called multiple times.
extern void InitPerfetto();

/* Perfetto Tracing:
 *
 * This file provides an interface to the perfetto tracing API.  The API from
 * the perfetto sdk can be used directly, but an additional set of macros
 * prefixed with PERFETTO_* have been defined to help minimize the use of
 * ifdef's.
 *
 * The common perfetto macros require a category and name at the very least.
 * These must be static strings, or wrapped with perfetto::DynamicString if
 * dynamic. If the string is static, but provided through a runtime pointer,
 * then it must be wrapped with perfetto::StaticString.
 *
 * You can also provide additional parameters such as a timestamp,
 * or a lambda to add additional information to the trace marker.
 * For more info, see https://perfetto.dev/docs/instrumentation/tracing-sdk
 *
 * Examples:
 *
 *  // Add a trace event to measure work inside a block,
 *  // using static strings only.
 *
 *  {
 *    PERFETTO_TRACE_EVENT("js", "JS::RunScript");
 *    run_script();
 *  }
 *
 *  // Add a trace event to measure work inside a block,
 *  // using a dynamic string.
 *
 *  void runScript(nsCString& scriptName)
 *  {
 *    PERFETTO_TRACE_EVENT("js", perfetto::DynamicString{scriptName.get()});
 *    run_script();
 *  }
 *
 *  // Add a trace event using a dynamic category and name.
 *
 *  void runScript(nsCString& categoryName, nsCString& scriptName)
 *  {
 *    perfetto::DynamicCategory category{category.get()};
 *    PERFETTO_TRACE_EVENT(category, perfetto::DynamicString{scriptName.get()});
 *    run_script();
 *  }
 *
 *  // Add a trace event to measure two arbitrary points of code.
 *  // Events in the same category must always be nested.
 *
 *  void startWork() {
 *    PERFETTO_TRACE_EVENT_BEGIN("js", "StartWork");
 *    ...
 *    PERFETTO_TRACE_EVENT_END("js");
 *  }
 *
 *  // Create a trace marker for an event that has already occurred
 *  // using previously saved timestamps.
 *
 *  void record_event(TimeStamp startTimeStamp, TimeStamp endTimeStamp)
 *  {
 *    PERFETTO_TRACE_EVENT_BEGIN("js", "Some Event", startTimeStamp);
 *    PERFETTO_TRACE_EVENT_END("js", endTimeStamp);
 *  }
 */


// Wrap the common trace event macros from perfetto so
// they can be called without #ifdef's.
#  define PERFETTO_TRACE_EVENT(...) TRACE_EVENT(__VA_ARGS__)
#  define PERFETTO_TRACE_EVENT_BEGIN(...) TRACE_EVENT_BEGIN(__VA_ARGS__)
#  define PERFETTO_TRACE_EVENT_END(...) TRACE_EVENT_END(__VA_ARGS__)
#  define PERFETTO_TRACE_EVENT_INSTANT(...) TRACE_EVENT_INSTANT(__VA_ARGS__)

namespace perfetto {
// Specialize custom timestamps for mozilla::TimeStamp.
template <>
struct TraceTimestampTraits<mozilla::TimeStamp> {
  static inline TraceTimestamp ConvertTimestampToTraceTimeNs(
      const mozilla::TimeStamp& timestamp) {
    return {protos::gen::BuiltinClock::BUILTIN_CLOCK_MONOTONIC,
            timestamp.RawClockMonotonicNanosecondsSinceBoot()};
  }
};
}  // namespace perfetto

// Categories can be added dynamically, but to minimize overhead
// all categories should be pre-defined here whenever possible.
PERFETTO_DEFINE_CATEGORIES(perfetto::Category("task"),
                           perfetto::Category("usertiming"));

using MS = mozilla::MarkerSchema;

// Primary template.  Assert if a payload type has not been specialized so we
// don't miss payload information.
template <typename T, typename Enable = void>
struct AddDebugAnnotationImpl {
  static void call(perfetto::EventContext& ctx, const charconst aKey,
                   const T& aValue) {
    static_assert(false,
                  "Unsupported payload type for perfetto debug annotations.");
  }
};

// Do nothing for these types.
template <>
struct AddDebugAnnotationImpl<mozilla::Nothing> {
  static void call(perfetto::EventContext& ctx, const charconst aKey,
                   const mozilla::Nothing& aValue) {}
};

template <>
struct AddDebugAnnotationImpl<std::nullptr_t> {
  static void call(perfetto::EventContext& ctx, const charconst aKey,
                   const std::nullptr_t& aValue) {}
};

// Specialize mozilla::Maybe<>
template <typename T>
struct AddDebugAnnotationImpl<mozilla::Maybe<T>> {
  static void call(perfetto::EventContext& ctx, const charconst aKey,
                   const mozilla::Maybe<T>& aValue) {
    if (aValue.isNothing()) {
      return;
    }
    AddDebugAnnotationImpl<T>::call(ctx, aKey, *aValue);
  }
};

// Specialize integral types.
template <typename T>
struct AddDebugAnnotationImpl<T, std::enable_if_t<std::is_integral_v<T>>> {
  static void call(perfetto::EventContext& ctx, const charconst aKey,
                   const T& aValue) {
    auto* arg = ctx.event()->add_debug_annotations();
    arg->set_name(aKey);

    if constexpr (std::is_same_v<T, bool>) {
      arg->set_bool_value(static_cast<uint64_t>(aValue));
    } else if constexpr (std::is_signed_v<T>) {
      arg->set_int_value(static_cast<uint64_t>(aValue));
    } else {
      static_assert(std::is_unsigned_v<T>);
      arg->set_uint_value(static_cast<uint64_t>(aValue));
    }
  }
};

// Specialize time durations.
template <>
struct AddDebugAnnotationImpl<
    mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>> {
  static void call(
      perfetto::EventContext& ctx, const charconst aKey,
      const mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>&
          aValue) {
    auto* arg = ctx.event()->add_debug_annotations();
    arg->set_name(aKey);
    arg->set_uint_value(static_cast<uint64_t>(aValue.ToMilliseconds()));
  }
};

template <>
struct AddDebugAnnotationImpl<Flow> {
  static void call(perfetto::EventContext& ctx, const charconst aKey,
                   const Flow& aValue) {
    AddDebugAnnotationImpl<uint64_t>::call(ctx, aKey, aValue.Id());
  }
};

// Specialize the various string representations.
#  define ADD_DEBUG_STRING_ANNOTATION_IMPL(templatetype, stringtype,        \
                                           paramtype, getter)               \
    template <templatetype>                                                 \
    struct AddDebugAnnotationImpl<stringtype> {                             \
      static void call(perfetto::EventContext& ctx, const charconst aKey, \
                       const paramtype aValue) {                            \
        auto* arg = ctx.event()->add_debug_annotations();                   \
        arg->set_name(aKey);                                                \
        arg->set_string_value(getter);                                      \
      }                                                                     \
    };

#  define ADD_DEBUG_STRING_ANNOTATION(type, getter) \
    ADD_DEBUG_STRING_ANNOTATION_IMPL(, type, type&, getter)

// ProfilerString8View may not be null-terminated, use the length-specified
// overload.
template <>
struct AddDebugAnnotationImpl<mozilla::ProfilerString8View> {
  static void call(perfetto::EventContext& ctx, const charconst aKey,
                   const mozilla::ProfilerString8View& aValue) {
    auto* arg = ctx.event()->add_debug_annotations();
    arg->set_name(aKey);
    auto sv = aValue.StringView();
    arg->set_string_value(sv.data(), sv.length());
  }
};
ADD_DEBUG_STRING_ANNOTATION_IMPL(size_t N, nsAutoCStringN<N>,
                                 nsAutoCStringN<N>&, aValue.get())
ADD_DEBUG_STRING_ANNOTATION(nsCString, aValue.get())
ADD_DEBUG_STRING_ANNOTATION(nsAutoCString, aValue.get())
ADD_DEBUG_STRING_ANNOTATION(nsTLiteralString<char>, aValue.get())
ADD_DEBUG_STRING_ANNOTATION(nsPrintfCString, aValue.get())
ADD_DEBUG_STRING_ANNOTATION(NS_ConvertUTF16toUTF8, aValue.get())
ADD_DEBUG_STRING_ANNOTATION(nsTDependentString<char>, aValue.get())

ADD_DEBUG_STRING_ANNOTATION(nsACString, nsAutoCString(aValue).get())
ADD_DEBUG_STRING_ANNOTATION(std::string, aValue)
ADD_DEBUG_STRING_ANNOTATION_IMPL(size_t N, char[N], char*, aValue)
ADD_DEBUG_STRING_ANNOTATION(mozilla::ProfilerString16View,
                            NS_ConvertUTF16toUTF8(aValue).get())
ADD_DEBUG_STRING_ANNOTATION(nsAString, NS_ConvertUTF16toUTF8(aValue).get())
ADD_DEBUG_STRING_ANNOTATION_IMPL(size_t N, nsAutoStringN<N>, nsAutoStringN<N>&,
                                 NS_ConvertUTF16toUTF8(aValue).get())
ADD_DEBUG_STRING_ANNOTATION_IMPL(, const nsAString&, nsAString&,
                                 NS_ConvertUTF16toUTF8(aValue).get())
ADD_DEBUG_STRING_ANNOTATION(nsString, NS_ConvertUTF16toUTF8(aValue).get())

// Main helper call that dispatches to proper specialization.
template <typename T>
void AddDebugAnnotation(perfetto::EventContext& ctx, const charconst aKey,
                        const T& aValue) {
  AddDebugAnnotationImpl<T>::call(ctx, aKey, aValue);
}

extern const char* ProfilerCategoryNames[];

// Main entry point from the gecko profiler for each marker.
template <typename MarkerType, typename... PayloadArguments>
void EmitPerfettoTrackEvent(const mozilla::ProfilerString8View& aName,
                            const mozilla::MarkerCategory& aCategory,
                            const mozilla::MarkerOptions& aOptions,
                            MarkerType aMarkerType,
                            const PayloadArguments&... aPayloadArguments) {
  mozilla::TimeStamp startTime, endTime;
  mozilla::MarkerTiming::Phase phase;

  if (aOptions.IsTimingUnspecified()) {
    startTime = mozilla::TimeStamp::Now();
    phase = mozilla::MarkerTiming::Phase::Instant;
  } else {
    startTime = aOptions.Timing().StartTime();
    endTime = aOptions.Timing().EndTime();
    phase = aOptions.Timing().MarkerPhase();
  }

  auto nameSv = aName.StringView();
  const char* nameStr = nameSv.data();
  if (!nameStr) {
    return;
  }

  // Create a dynamic category for the marker.
  const char* categoryName =
      ProfilerCategoryNames[static_cast<uint32_t>(aCategory.GetCategory())];
  perfetto::DynamicCategory category{categoryName};
  perfetto::DynamicString name{nameStr, nameSv.length()};

  // If the Marker has payload fields, we can annotate them in the perfetto
  // track event. Otherwise, we define an empty lambda which does nothing.
  std::function<void(perfetto::EventContext)> annotateTrackEvent =
      [&](perfetto::EventContext ctx) {};
  if constexpr (mozilla::MarkerHasTranslator<MarkerType>::value) {
    // NOP
    // TODO - Bug 2037782
  } else if constexpr (mozilla::MarkerHasPayloadFields<MarkerType>::value) {
    annotateTrackEvent = [&](perfetto::EventContext ctx) {
      static_assert(
          sizeof...(PayloadArguments) ==
              std::extent_v<decltype(MarkerType::PayloadFields)>,
          "Number and type of fields must be equal to number and type of "
          "payload arguments. If this is not the case a "
          "TranslateMarkerInputToSchema function must be defined.");
      size_t i = 0;
      auto processArgument = [&](const auto& payloadArg) {
        AddDebugAnnotation(ctx, MarkerType::PayloadFields[i++].Key, payloadArg);
      };
      (processArgument(aPayloadArguments), ...);
    };
  }

  // Create a unique id for each marker so it has it's own track.
  mozilla::HashNumber hash =
      mozilla::HashStringKnownLength(nameStr, nameSv.length());

  switch (phase) {
    case mozilla::MarkerTiming::Phase::Interval: {
      hash = mozilla::AddToHash(
          hash, startTime.RawClockMonotonicNanosecondsSinceBoot());
      hash = mozilla::AddToHash(
          hash, endTime.RawClockMonotonicNanosecondsSinceBoot());
      perfetto::Track track(hash);

      PERFETTO_TRACE_EVENT_BEGIN(category, name, track, startTime);
      PERFETTO_TRACE_EVENT_END(category, track, endTime, annotateTrackEvent);
    } break;
    case mozilla::MarkerTiming::Phase::Instant: {
      PERFETTO_TRACE_EVENT_INSTANT(category, name, startTime);
    } break;
    case mozilla::MarkerTiming::Phase::IntervalStart: {
      PERFETTO_TRACE_EVENT_BEGIN(category, name, perfetto::Track(hash),
                                 startTime);
    } break;
    case mozilla::MarkerTiming::Phase::IntervalEnd: {
      PERFETTO_TRACE_EVENT_END(category, perfetto::Track(hash), endTime,
                               annotateTrackEvent);
    } break;
  }
}

#else  // !defined(MOZ_PERFETTO)
#  define PERFETTO_TRACE_EVENT(...) \
    do {                            \
    } while (0)
#  define PERFETTO_TRACE_EVENT_BEGIN(...) \
    do {                                  \
    } while (0)
#  define PERFETTO_TRACE_EVENT_END(...) \
    do {                                \
    } while (0)
#  define PERFETTO_TRACE_EVENT_INSTANT(...) \
    do {                                    \
    } while (0)
inline void InitPerfetto() {}
#endif  // MOZ_PERFETTO

#endif  // mozilla_Perfetto_h

Messung V0.5 in Prozent
C=91 H=99 G=94

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002