tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 0f91735b3bd960f7bb9b720cc75a4bd99bf661ca
parent 4ffa205cca52b7c040a251578b963f260bca1a50
Author: Florian Quèze <florian@queze.net>
Date:   Mon, 20 Oct 2025 19:28:12 +0000

Bug 1992094 - Record thermal state as profiler markers on Mac, r=mstange,profiler-reviewers.

Differential Revision: https://phabricator.services.mozilla.com/D267216

Diffstat:
Atools/profiler/core/ProfilerThermalState-mac.mm | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtools/profiler/core/platform.cpp | 12++++++++++++
Mtools/profiler/moz.build | 3+++
3 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/tools/profiler/core/ProfilerThermalState-mac.mm b/tools/profiler/core/ProfilerThermalState-mac.mm @@ -0,0 +1,74 @@ +/* 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/. */ + +#include "mozilla/ProfilerMarkers.h" +#include "mozilla/ProfilerState.h" +#include <Foundation/Foundation.h> + +static nsLiteralCString ThermalStateToString(NSProcessInfoThermalState state) { + switch (state) { + case NSProcessInfoThermalStateNominal: + return "Nominal"_ns; + case NSProcessInfoThermalStateFair: + return "Fair"_ns; + case NSProcessInfoThermalStateSerious: + return "Serious"_ns; + case NSProcessInfoThermalStateCritical: + return "Critical"_ns; + default: + return "Unknown"_ns; + } +} + +static void AddThermalStateMarker() { + NSProcessInfoThermalState state = [[NSProcessInfo processInfo] thermalState]; + PROFILER_MARKER_TEXT( + "Thermal State", OTHER, + mozilla::MarkerOptions(mozilla::MarkerThreadId::MainThread()), + ThermalStateToString(state)); +} + +static id<NSObject> gThermalObserver = nil; + +static void ThermalStateCallback(ProfilingState aProfilingState) { + if (aProfilingState == ProfilingState::Started) { + if (gThermalObserver) { + return; // Already registered + } + + // Add marker for current thermal state + AddThermalStateMarker(); + + // Register for thermal state change notifications + gThermalObserver = [[NSNotificationCenter defaultCenter] + addObserverForName:NSProcessInfoThermalStateDidChangeNotification + object:nil + queue:nil + usingBlock:^(NSNotification* note) { + AddThermalStateMarker(); + }]; + } else if (aProfilingState == ProfilingState::Pausing) { + // Add marker but keep observer active + AddThermalStateMarker(); + } else if (aProfilingState == ProfilingState::Stopping) { + if (!gThermalObserver) { + return; + } + + // Add final marker for thermal state + AddThermalStateMarker(); + + [[NSNotificationCenter defaultCenter] removeObserver:gThermalObserver]; + gThermalObserver = nil; + } +} + +void profiler_register_thermal_state_observer() { + profiler_add_state_change_callback( + AllProfilingStates(), + [](ProfilingState aProfilingState) { + ThermalStateCallback(aProfilingState); + }, + 0); +} diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp @@ -297,6 +297,11 @@ void profiler_dump_and_stop(); // Forward declare the function to call when we need to start the profiler. void profiler_start_from_signal(); +#if defined(GP_OS_darwin) +// Forward declare thermal state observer function (macOS only) +void profiler_register_thermal_state_observer(); +#endif + mozilla::Atomic<int, mozilla::MemoryOrdering::Relaxed> gSkipSampling; #if defined(GP_OS_android) @@ -6160,6 +6165,13 @@ void profiler_init(void* aStackTop) { // so let's record it again now. profiler_mark_thread_awake(); +#if defined(GP_OS_darwin) + // Register thermal state observer callback on macOS (parent process only) + if (XRE_IsParentProcess()) { + profiler_register_thermal_state_observer(); + } +#endif + invoke_profiler_state_change_callbacks(ProfilingState::Started); // We do this with gPSMutex unlocked. The comment in profiler_stop() explains diff --git a/tools/profiler/moz.build b/tools/profiler/moz.build @@ -99,6 +99,9 @@ if CONFIG["MOZ_GECKO_PROFILER"]: "core/EHABIStackWalk.cpp", ] elif CONFIG["OS_TARGET"] == "Darwin": + UNIFIED_SOURCES += [ + "core/ProfilerThermalState-mac.mm", + ] if CONFIG["TARGET_CPU"] == "aarch64": UNIFIED_SOURCES += [ "core/PowerCounters-mac-arm64.cpp",