ProfilerUtils.cpp (4766B)
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/. */ 6 7 // This file implements functions from BaseProfilerUtils.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. 11 12 #include "mozilla/BaseProfilerUtils.h" 13 14 // --------------------------------------------- WASI process & thread ids 15 #if defined(__wasi__) 16 17 namespace mozilla::baseprofiler { 18 19 // WASI is single-process and single-thread for now. 20 21 BaseProfilerProcessId profiler_current_process_id() { 22 return BaseProfilerProcessId::FromNativeId(1u); 23 } 24 25 BaseProfilerThreadId profiler_current_thread_id() { 26 return BaseProfilerThreadId::FromNativeId(1u); 27 } 28 29 } // namespace mozilla::baseprofiler 30 31 // --------------------------------------------- Windows process & thread ids 32 #elif defined(XP_WIN) 33 34 # include <process.h> 35 # include <processthreadsapi.h> 36 37 namespace mozilla::baseprofiler { 38 39 BaseProfilerProcessId profiler_current_process_id() { 40 return BaseProfilerProcessId::FromNativeId(_getpid()); 41 } 42 43 BaseProfilerThreadId profiler_current_thread_id() { 44 static_assert(std::is_same_v<BaseProfilerThreadId::NativeType, 45 decltype(GetCurrentThreadId())>, 46 "BaseProfilerThreadId::NativeType must be exactly the type " 47 "returned by GetCurrentThreadId()"); 48 return BaseProfilerThreadId::FromNativeId(GetCurrentThreadId()); 49 } 50 51 } // namespace mozilla::baseprofiler 52 53 // --------------------------------------------- Non-Windows process id 54 #else 55 // All non-Windows platforms are assumed to be POSIX, which has getpid(). 56 57 # include <unistd.h> 58 59 namespace mozilla::baseprofiler { 60 61 BaseProfilerProcessId profiler_current_process_id() { 62 return BaseProfilerProcessId::FromNativeId(getpid()); 63 } 64 65 } // namespace mozilla::baseprofiler 66 67 // --------------------------------------------- Non-Windows thread id 68 // ------------------------------------------------------- macOS 69 # if defined(XP_MACOSX) 70 71 # include <pthread.h> 72 73 namespace mozilla::baseprofiler { 74 75 BaseProfilerThreadId profiler_current_thread_id() { 76 uint64_t tid; 77 if (pthread_threadid_np(nullptr, &tid) != 0) { 78 return BaseProfilerThreadId{}; 79 } 80 return BaseProfilerThreadId::FromNativeId(tid); 81 } 82 83 } // namespace mozilla::baseprofiler 84 85 // ------------------------------------------------------- Android 86 // Test Android before Linux, because Linux includes Android. 87 # elif defined(__ANDROID__) || defined(ANDROID) 88 89 namespace mozilla::baseprofiler { 90 91 BaseProfilerThreadId profiler_current_thread_id() { 92 return BaseProfilerThreadId::FromNativeId(gettid()); 93 } 94 95 } // namespace mozilla::baseprofiler 96 97 // ------------------------------------------------------- Linux 98 # elif defined(XP_LINUX) 99 100 # include <sys/syscall.h> 101 102 namespace mozilla::baseprofiler { 103 104 BaseProfilerThreadId profiler_current_thread_id() { 105 static thread_local pid_t tid; 106 if (!tid) { 107 // glibc doesn't provide a wrapper for gettid() until 2.30 108 tid = static_cast<pid_t>(syscall(SYS_gettid)); 109 } 110 return BaseProfilerThreadId::FromNativeId(tid); 111 } 112 113 } // namespace mozilla::baseprofiler 114 115 // ------------------------------------------------------- FreeBSD 116 # elif defined(XP_FREEBSD) 117 118 # include <sys/thr.h> 119 120 namespace mozilla::baseprofiler { 121 122 BaseProfilerThreadId profiler_current_thread_id() { 123 long id; 124 if (thr_self(&id) != 0) { 125 return BaseProfilerThreadId{}; 126 } 127 return BaseProfilerThreadId::FromNativeId(id); 128 } 129 130 } // namespace mozilla::baseprofiler 131 132 // ------------------------------------------------------- Others 133 # else 134 135 namespace mozilla::baseprofiler { 136 137 BaseProfilerThreadId profiler_current_thread_id() { 138 return BaseProfilerThreadId::FromNativeId(std::this_thread::get_id()); 139 } 140 141 } // namespace mozilla::baseprofiler 142 143 # endif 144 #endif // End of non-XP_WIN. 145 146 // --------------------------------------------- Platform-agnostic definitions 147 148 namespace mozilla::baseprofiler { 149 150 static BaseProfilerThreadId scBaseProfilerMainThreadId{}; 151 152 void profiler_init_main_thread_id() { 153 if (!scBaseProfilerMainThreadId.IsSpecified()) { 154 scBaseProfilerMainThreadId = profiler_current_thread_id(); 155 } 156 } 157 158 BaseProfilerThreadId profiler_main_thread_id() { 159 return scBaseProfilerMainThreadId; 160 } 161 162 bool profiler_is_main_thread() { 163 return profiler_current_thread_id() == scBaseProfilerMainThreadId; 164 } 165 166 } // namespace mozilla::baseprofiler