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 // This file implements functions from ProfilerUtils.h on all platforms.
8 // Functions with platform-specific implementations are separated in #if blocks
9 // below, with each block being self-contained with all the #includes and
10 // definitions it needs, to keep platform code easier to maintain in isolation.
12 #include "mozilla/ProfilerUtils.h"
14 // --------------------------------------------- Windows process & thread ids
18 # include <processthreadsapi.h>
20 ProfilerProcessId
profiler_current_process_id() {
21 return ProfilerProcessId::FromNativeId(_getpid());
24 ProfilerThreadId
profiler_current_thread_id() {
25 static_assert(std::is_same_v
<ProfilerThreadId::NativeType
,
26 decltype(GetCurrentThreadId())>,
27 "ProfilerThreadId::NativeType must be exactly the type "
28 "returned by GetCurrentThreadId()");
29 return ProfilerThreadId::FromNativeId(GetCurrentThreadId());
32 // --------------------------------------------- Non-Windows process id
34 // All non-Windows platforms are assumed to be POSIX, which has getpid().
38 ProfilerProcessId
profiler_current_process_id() {
39 return ProfilerProcessId::FromNativeId(getpid());
42 // --------------------------------------------- Non-Windows thread id
43 // ------------------------------------------------------- macOS
44 # if defined(XP_MACOSX)
48 ProfilerThreadId
profiler_current_thread_id() {
50 if (pthread_threadid_np(nullptr, &tid
) != 0) {
51 return ProfilerThreadId
{};
53 return ProfilerThreadId::FromNativeId(tid
);
56 // ------------------------------------------------------- Android
57 // Test Android before Linux, because Linux includes Android.
58 # elif defined(__ANDROID__) || defined(ANDROID)
60 ProfilerThreadId
profiler_current_thread_id() {
61 return ProfilerThreadId::FromNativeId(gettid());
64 // ------------------------------------------------------- Linux
65 # elif defined(XP_LINUX)
67 # include <sys/syscall.h>
69 ProfilerThreadId
profiler_current_thread_id() {
70 static thread_local pid_t tid
;
72 // glibc doesn't provide a wrapper for gettid() until 2.30
73 tid
= static_cast<pid_t
>(syscall(SYS_gettid
));
75 return ProfilerThreadId::FromNativeId(tid
);
78 // ------------------------------------------------------- FreeBSD
79 # elif defined(XP_FREEBSD)
83 ProfilerThreadId
profiler_current_thread_id() {
85 if (thr_self(&id
) != 0) {
86 return ProfilerThreadId
{};
88 return ProfilerThreadId::FromNativeId(id
);
91 // ------------------------------------------------------- Others
94 ProfilerThreadId
profiler_current_thread_id() {
95 return ProfilerThreadId::FromNativeId(std::this_thread::get_id());
99 #endif // End of non-XP_WIN.
101 // --------------------------------------------- Platform-agnostic definitions
103 #include "MainThreadUtils.h"
104 #include "mozilla/Assertions.h"
106 static ProfilerThreadId scProfilerMainThreadId
;
108 void profiler_init_main_thread_id() {
109 MOZ_ASSERT(NS_IsMainThread());
110 mozilla::baseprofiler::profiler_init_main_thread_id();
111 if (!scProfilerMainThreadId
.IsSpecified()) {
112 scProfilerMainThreadId
= profiler_current_thread_id();
116 [[nodiscard
]] ProfilerThreadId
profiler_main_thread_id() {
117 return scProfilerMainThreadId
;
120 [[nodiscard
]] bool profiler_is_main_thread() {
121 return profiler_current_thread_id() == scProfilerMainThreadId
;