no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / mozglue / misc / AutoProfilerLabel.cpp
blob5fd820cc5ba25ba512807a9a446c03e1122a07c2
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/AutoProfilerLabel.h"
9 #include "mozilla/Assertions.h"
10 #include "mozilla/PlatformMutex.h"
12 namespace mozilla {
14 // RAII class that encapsulates all shared static data, and enforces locking
15 // when accessing this data.
16 class MOZ_RAII AutoProfilerLabelData {
17 public:
18 AutoProfilerLabelData() { sAPLMutex.Lock(); }
20 ~AutoProfilerLabelData() { sAPLMutex.Unlock(); }
22 AutoProfilerLabelData(const AutoProfilerLabelData&) = delete;
23 void operator=(const AutoProfilerLabelData&) = delete;
25 const ProfilerLabelEnter& EnterCRef() const { return sEnter; }
26 ProfilerLabelEnter& EnterRef() { return sEnter; }
28 const ProfilerLabelExit& ExitCRef() const { return sExit; }
29 ProfilerLabelExit& ExitRef() { return sExit; }
31 const uint32_t& GenerationCRef() const { return sGeneration; }
32 uint32_t& GenerationRef() { return sGeneration; }
34 static bool RacyIsProfilerPresent() { return !!sGeneration; }
36 private:
37 // Thin shell around mozglue PlatformMutex, for local internal use.
38 // Does not preserve behavior in JS record/replay.
39 class Mutex : private mozilla::detail::MutexImpl {
40 public:
41 Mutex() = default;
42 void Lock() { mozilla::detail::MutexImpl::lock(); }
43 void Unlock() { mozilla::detail::MutexImpl::unlock(); }
46 // Mutex protecting access to the following static members.
47 static Mutex sAPLMutex MOZ_UNANNOTATED;
49 static ProfilerLabelEnter sEnter;
50 static ProfilerLabelExit sExit;
52 // Current "generation" of RegisterProfilerLabelEnterExit calls.
53 static uint32_t sGeneration;
56 /* static */ AutoProfilerLabelData::Mutex AutoProfilerLabelData::sAPLMutex;
57 /* static */ ProfilerLabelEnter AutoProfilerLabelData::sEnter = nullptr;
58 /* static */ ProfilerLabelExit AutoProfilerLabelData::sExit = nullptr;
59 /* static */ uint32_t AutoProfilerLabelData::sGeneration = 0;
61 void RegisterProfilerLabelEnterExit(ProfilerLabelEnter aEnter,
62 ProfilerLabelExit aExit) {
63 MOZ_ASSERT(!aEnter == !aExit, "Must provide both null or both non-null");
65 AutoProfilerLabelData data;
66 MOZ_ASSERT(!aEnter != !data.EnterRef(),
67 "Must go from null to non-null, or from non-null to null");
68 data.EnterRef() = aEnter;
69 data.ExitRef() = aExit;
70 ++data.GenerationRef();
73 bool IsProfilerPresent() {
74 return AutoProfilerLabelData::RacyIsProfilerPresent();
77 ProfilerLabel ProfilerLabelBegin(const char* aLabelName,
78 const char* aDynamicString, void* aSp) {
79 const AutoProfilerLabelData data;
80 void* entryContext = (data.EnterCRef())
81 ? data.EnterCRef()(aLabelName, aDynamicString, aSp)
82 : nullptr;
83 uint32_t generation = data.GenerationCRef();
85 return std::make_tuple(entryContext, generation);
88 void ProfilerLabelEnd(const ProfilerLabel& aLabel) {
89 if (!IsValidProfilerLabel(aLabel)) {
90 return;
93 const AutoProfilerLabelData data;
94 if (data.ExitCRef() && (std::get<1>(aLabel) == data.GenerationCRef())) {
95 data.ExitCRef()(std::get<0>(aLabel));
99 AutoProfilerLabel::AutoProfilerLabel(const char* aLabel,
100 const char* aDynamicString) {
101 std::tie(mEntryContext, mGeneration) =
102 ProfilerLabelBegin(aLabel, aDynamicString, this);
105 AutoProfilerLabel::~AutoProfilerLabel() {
106 ProfilerLabelEnd(std::make_tuple(mEntryContext, mGeneration));
109 } // namespace mozilla