Bug 1549232 - Only use profiler_current_{process,thread}_id in the Gecko Profiler instead of alternatives - r=mstange
authorGerald Squelart <gsquelart@mozilla.com>
Thu, 09 May 2019 18:26:15 +0000
changeset 532150 3ddac071d565fb30846e19708adb4d302a487466
parent 532149 43a787dd45535c9ac25e7a8f8f11cd18d577f522
child 532151 a42caa9f04fc41044437ac56eab6f6086c841d9f
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1549232
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1549232 - Only use profiler_current_{process,thread}_id in the Gecko Profiler instead of alternatives - r=mstange There were many inconsistent ways to retrieve process/thread ids in the profiler. Now we have only one platform-dependent implementation each: profiler_current_process_id() and profiler_current_thread_id(). Note that this removes the need for the small `class Thread` in platform.h. However memory_hooks.cpp still needs to be built non-unified, because of the required order of #includes (replace_malloc.h before replace_malloc_bridge.h), which could be disturbed by other cpp's. Differential Revision: https://phabricator.services.mozilla.com/D29977
tools/profiler/core/ProfiledThreadData.cpp
tools/profiler/core/platform-linux-android.cpp
tools/profiler/core/platform-macos.cpp
tools/profiler/core/platform-win32.cpp
tools/profiler/core/platform.cpp
tools/profiler/core/platform.h
tools/profiler/core/shared-libraries-linux.cc
tools/profiler/lul/LulMain.cpp
tools/profiler/lul/platform-linux-lul.cpp
tools/profiler/moz.build
tools/profiler/public/GeckoProfiler.h
tools/profiler/tasktracer/GeckoTaskTracer.cpp
tools/profiler/tests/gtest/GeckoProfiler.cpp
--- a/tools/profiler/core/ProfiledThreadData.cpp
+++ b/tools/profiler/core/ProfiledThreadData.cpp
@@ -11,23 +11,16 @@
 
 #include "js/TraceLoggerAPI.h"
 #include "mozilla/dom/ContentChild.h"
 
 #if defined(GP_OS_darwin)
 #  include <pthread.h>
 #endif
 
-#ifdef XP_WIN
-#  include <process.h>
-#  define getpid _getpid
-#else
-#  include <unistd.h>  // for getpid()
-#endif
-
 ProfiledThreadData::ProfiledThreadData(ThreadInfo* aThreadInfo,
                                        nsIEventTarget* aEventTarget,
                                        bool aIncludeResponsiveness)
     : mThreadInfo(aThreadInfo) {
   MOZ_COUNT_CTOR(ProfiledThreadData);
   if (aIncludeResponsiveness) {
     mResponsiveness.emplace(aEventTarget, aThreadInfo->IsMainThread());
   }
@@ -218,17 +211,18 @@ void StreamSamplesAndMarkers(const char*
   // Use given process name (if any), unless we're the parent process.
   if (XRE_IsParentProcess()) {
     aWriter.StringProperty("processName", "Parent Process");
   } else if (!aProcessName.IsEmpty()) {
     aWriter.StringProperty("processName", aProcessName.Data());
   }
 
   aWriter.IntProperty("tid", static_cast<int64_t>(aThreadId));
-  aWriter.IntProperty("pid", static_cast<int64_t>(getpid()));
+  aWriter.IntProperty("pid",
+                      static_cast<int64_t>(profiler_current_process_id()));
 
   if (aRegisterTime) {
     aWriter.DoubleProperty(
         "registerTime", (aRegisterTime - aProcessStartTime).ToMilliseconds());
   } else {
     aWriter.NullProperty("registerTime");
   }
 
--- a/tools/profiler/core/platform-linux-android.cpp
+++ b/tools/profiler/core/platform-linux-android.cpp
@@ -64,18 +64,26 @@
 #include "mozilla/PodOperations.h"
 #include "mozilla/DebugOnly.h"
 
 #include <string.h>
 #include <list>
 
 using namespace mozilla;
 
-/* static */
-int Thread::GetCurrentId() { return gettid(); }
+int profiler_current_process_id() { return getpid(); }
+
+int profiler_current_thread_id() {
+  // glibc doesn't provide a wrapper for gettid().
+#if defined(__GLIBC__)
+  return static_cast<int>(static_cast<pid_t>(syscall(SYS_gettid)));
+#else
+  return static_cast<int>(gettid());
+#endif
+}
 
 void* GetStackTop(void* aGuess) { return aGuess; }
 
 static void PopulateRegsFromContext(Registers& aRegs, ucontext_t* aContext) {
   aRegs.mContext = aContext;
   mcontext_t& mcontext = aContext->uc_mcontext;
 
   // Extracting the sample from the context is extremely machine dependent.
@@ -232,17 +240,17 @@ static void SigprofHandler(int aSignal, 
   // |sSigHandlerCoordinator|.
   r = sem_post(&Sampler::sSigHandlerCoordinator->mMessage4);
   MOZ_ASSERT(r == 0);
 
   errno = savedErrno;
 }
 
 Sampler::Sampler(PSLockRef aLock)
-    : mMyPid(getpid())
+    : mMyPid(profiler_current_process_id())
       // We don't know what the sampler thread's ID will be until it runs, so
       // set mSamplerTid to a dummy value and fill it in for real in
       // SuspendAndSampleAndResumeThread().
       ,
       mSamplerTid(-1) {
 #if defined(USE_EHABI_STACKWALK)
   mozilla::EHABIStackWalkInit();
 #endif
@@ -272,17 +280,17 @@ template <typename Func>
 void Sampler::SuspendAndSampleAndResumeThread(
     PSLockRef aLock, const RegisteredThread& aRegisteredThread,
     const Func& aProcessRegs) {
   // Only one sampler thread can be sampling at once.  So we expect to have
   // complete control over |sSigHandlerCoordinator|.
   MOZ_ASSERT(!sSigHandlerCoordinator);
 
   if (mSamplerTid == -1) {
-    mSamplerTid = gettid();
+    mSamplerTid = profiler_current_thread_id();
   }
   int sampleeTid = aRegisteredThread.Info()->ThreadId();
   MOZ_RELEASE_ASSERT(sampleeTid != mSamplerTid);
 
   //----------------------------------------------------------------//
   // Suspend the samplee thread and get its context.
 
   SigHandlerCoordinator coord;  // on sampler thread's stack
--- a/tools/profiler/core/platform-macos.cpp
+++ b/tools/profiler/core/platform-macos.cpp
@@ -17,28 +17,32 @@
 #include <libkern/OSAtomic.h>
 #include <mach/mach.h>
 #include <mach/semaphore.h>
 #include <mach/task.h>
 #include <mach/thread_act.h>
 #include <mach/vm_statistics.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <sys/syscall.h>
 #include <sys/types.h>
 #include <sys/sysctl.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <math.h>
 
 // this port is based off of v8 svn revision 9837
 
-/* static */
-int Thread::GetCurrentId() { return gettid(); }
+int profiler_current_process_id() { return getpid(); }
+
+int profiler_current_thread_id() {
+  return static_cast<int>(static_cast<pid_t>(syscall(SYS_thread_selfid)));
+}
 
 void* GetStackTop(void* aGuess) {
   pthread_t thread = pthread_self();
   return pthread_get_stackaddr_np(thread);
 }
 
 class PlatformData {
  public:
--- a/tools/profiler/core/platform-win32.cpp
+++ b/tools/profiler/core/platform-win32.cpp
@@ -31,18 +31,19 @@
 #include <windows.h>
 #include <mmsystem.h>
 #include <process.h>
 
 #include "nsWindowsDllInterceptor.h"
 #include "mozilla/StackWalk_windows.h"
 #include "mozilla/WindowsVersion.h"
 
-/* static */
-int Thread::GetCurrentId() {
+int profiler_current_process_id() { return _getpid(); }
+
+int profiler_current_thread_id() {
   DWORD threadId = GetCurrentThreadId();
   MOZ_ASSERT(threadId <= INT32_MAX, "native thread ID is > INT32_MAX");
   return int(threadId);
 }
 
 void* GetStackTop(void* aGuess) {
   PNT_TIB pTib = reinterpret_cast<PNT_TIB>(NtCurrentTeb());
   return reinterpret_cast<void*>(pTib->StackBase);
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -76,22 +76,16 @@
 #include "prtime.h"
 
 #include <algorithm>
 #include <errno.h>
 #include <fstream>
 #include <ostream>
 #include <sstream>
 
-#if defined(XP_WIN)
-#  include <processthreadsapi.h>  // for GetCurrentProcessId()
-#else
-#  include <unistd.h>  // for getpid()
-#endif                 // defined(XP_WIN)
-
 #ifdef MOZ_TASK_TRACER
 #  include "GeckoTaskTracer.h"
 #endif
 
 #if defined(GP_OS_android)
 #  include "FennecJNINatives.h"
 #  include "FennecJNIWrappers.h"
 #endif
@@ -570,23 +564,17 @@ class ActivePS {
 
       // Crude, non UTF-8 compatible, case insensitive substring search
       if (name.find(filter) != std::string::npos) {
         return true;
       }
 
       // If the filter starts with pid:, check for a pid match
       if (filter.find("pid:") == 0) {
-        std::string mypid = std::to_string(
-#ifdef XP_WIN
-            GetCurrentProcessId()
-#else
-            getpid()
-#endif
-        );
+        std::string mypid = std::to_string(profiler_current_process_id());
         if (filter.compare(4, std::string::npos, mypid) == 0) {
           return true;
         }
       }
     }
 
     return false;
   }
@@ -2674,17 +2662,17 @@ uint32_t ParseFeaturesFromStringArray(co
     features |= ParseFeature(aFeatures[i], aIsStartup);
   }
   return features;
 }
 
 // Find the RegisteredThread for the current thread. This should only be called
 // in places where TLSRegisteredThread can't be used.
 static RegisteredThread* FindCurrentThreadRegisteredThread(PSLockRef aLock) {
-  int id = Thread::GetCurrentId();
+  int id = profiler_current_thread_id();
   const Vector<UniquePtr<RegisteredThread>>& registeredThreads =
       CorePS::RegisteredThreads(aLock);
   for (auto& registeredThread : registeredThreads) {
     if (registeredThread->Info()->ThreadId() == id) {
       return registeredThread.get();
     }
   }
 
@@ -2700,17 +2688,17 @@ static ProfilingStack* locked_register_t
 
   VTUNE_REGISTER_THREAD(aName);
 
   if (!TLSRegisteredThread::Init(aLock)) {
     return nullptr;
   }
 
   RefPtr<ThreadInfo> info =
-      new ThreadInfo(aName, Thread::GetCurrentId(), NS_IsMainThread());
+      new ThreadInfo(aName, profiler_current_thread_id(), NS_IsMainThread());
   UniquePtr<RegisteredThread> registeredThread = MakeUnique<RegisteredThread>(
       info, NS_GetCurrentThreadNoCreate(), aStackTop);
 
   TLSRegisteredThread::SetRegisteredThread(aLock, registeredThread.get());
 
   if (ActivePS::Exists(aLock) && ActivePS::ShouldProfileThread(aLock, info)) {
     registeredThread->RacyRegisteredThread().SetIsBeingProfiled(true);
     nsCOMPtr<nsIEventTarget> eventTarget = registeredThread->GetEventTarget();
@@ -3329,17 +3317,17 @@ static void locked_profiler_start(PSLock
     duration = Nothing();
   }
   double interval = aInterval > 0 ? aInterval : PROFILER_DEFAULT_INTERVAL;
 
   ActivePS::Create(aLock, capacity, interval, aFeatures, aFilters, aFilterCount,
                    duration);
 
   // Set up profiling for each registered thread, if appropriate.
-  int tid = Thread::GetCurrentId();
+  int tid = profiler_current_thread_id();
   const Vector<UniquePtr<RegisteredThread>>& registeredThreads =
       CorePS::RegisteredThreads(aLock);
   for (auto& registeredThread : registeredThreads) {
     RefPtr<ThreadInfo> info = registeredThread->Info();
 
     if (ActivePS::ShouldProfileThread(aLock, info)) {
       registeredThread->RacyRegisteredThread().SetIsBeingProfiled(true);
       nsCOMPtr<nsIEventTarget> eventTarget = registeredThread->GetEventTarget();
@@ -3513,17 +3501,17 @@ static MOZ_MUST_USE SamplerThread* locke
 
 #ifdef MOZ_TASK_TRACER
   if (ActivePS::FeatureTaskTracer(aLock)) {
     tasktracer::StopLogging();
   }
 #endif
 
   // Stop sampling live threads.
-  int tid = Thread::GetCurrentId();
+  int tid = profiler_current_thread_id();
   const Vector<LiveProfiledThreadData>& liveProfiledThreads =
       ActivePS::LiveProfiledThreads(aLock);
   for (auto& thread : liveProfiledThreads) {
     RegisteredThread* registeredThread = thread.mRegisteredThread;
     registeredThread->RacyRegisteredThread().SetIsBeingProfiled(false);
     if (ActivePS::FeatureJS(aLock)) {
       registeredThread->StopJSSampling();
       RefPtr<ThreadInfo> info = registeredThread->Info();
@@ -3858,17 +3846,17 @@ UniqueProfilerBacktrace profiler_get_bac
 
   RegisteredThread* registeredThread =
       TLSRegisteredThread::RegisteredThread(lock);
   if (!registeredThread) {
     MOZ_ASSERT(registeredThread);
     return nullptr;
   }
 
-  int tid = Thread::GetCurrentId();
+  int tid = profiler_current_thread_id();
 
   TimeStamp now = TimeStamp::Now();
 
   Registers regs;
 #if defined(HAVE_NATIVE_UNWIND)
   regs.SyncPopulate();
 #else
   regs.Clear();
@@ -4123,18 +4111,16 @@ void profiler_clear_js_context() {
       registeredThread->StartJSSampling(ActivePS::JSFlags(lock));
       return;
     }
   }
 
   registeredThread->ClearJSContext();
 }
 
-int profiler_current_thread_id() { return Thread::GetCurrentId(); }
-
 // NOTE: aCollector's methods will be called while the target thread is paused.
 // Doing things in those methods like allocating -- which may try to claim
 // locks -- is a surefire way to deadlock.
 void profiler_suspend_and_sample_thread(int aThreadId, uint32_t aFeatures,
                                         ProfilerStackCollector& aCollector,
                                         bool aSampleNative /* = true */) {
   // Lock the profiler mutex
   PSAutoLock lock(gPSMutex);
--- a/tools/profiler/core/platform.h
+++ b/tools/profiler/core/platform.h
@@ -26,75 +26,45 @@
 // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 // SUCH DAMAGE.
 
 #ifndef TOOLS_PLATFORM_H_
 #define TOOLS_PLATFORM_H_
 
 #include "PlatformMacros.h"
 
+#include "GeckoProfiler.h"
+
 #include "mozilla/Logging.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Vector.h"
 #include "nsString.h"
 
 #include <functional>
 #include <stdint.h>
 
-// We need a definition of gettid(), but old glibc versions don't provide a
-// wrapper for it.
-#if defined(__GLIBC__)
-#  include <unistd.h>
-#  include <sys/syscall.h>
-#  define gettid() static_cast<pid_t>(syscall(SYS_gettid))
-#elif defined(GP_OS_darwin)
-#  include <unistd.h>
-#  include <sys/syscall.h>
-#  define gettid() static_cast<pid_t>(syscall(SYS_thread_selfid))
-#elif defined(GP_OS_android)
-#  include <unistd.h>
-#elif defined(GP_OS_windows)
-#  include <windows.h>
-#  include <process.h>
-#  ifndef getpid
-#    define getpid _getpid
-#  endif
-#endif
-
 extern mozilla::LazyLogModule gProfilerLog;
 
 // These are for MOZ_LOG="prof:3" or higher. It's the default logging level for
 // the profiler, and should be used sparingly.
 #define LOG_TEST MOZ_LOG_TEST(gProfilerLog, mozilla::LogLevel::Info)
 #define LOG(arg, ...)                            \
   MOZ_LOG(gProfilerLog, mozilla::LogLevel::Info, \
-          ("[%d] " arg, getpid(), ##__VA_ARGS__))
+          ("[%d] " arg, profiler_current_process_id(), ##__VA_ARGS__))
 
 // These are for MOZ_LOG="prof:4" or higher. It should be used for logging that
 // is somewhat more verbose than LOG.
 #define DEBUG_LOG_TEST MOZ_LOG_TEST(gProfilerLog, mozilla::LogLevel::Debug)
 #define DEBUG_LOG(arg, ...)                       \
   MOZ_LOG(gProfilerLog, mozilla::LogLevel::Debug, \
-          ("[%d] " arg, getpid(), ##__VA_ARGS__))
+          ("[%d] " arg, profiler_current_process_id(), ##__VA_ARGS__))
 
 typedef uint8_t* Address;
 
 // ----------------------------------------------------------------------------
-// Thread
-//
-// This class has static methods for the different platform specific
-// functions. Add methods here to cope with differences between the
-// supported platforms.
-
-class Thread {
- public:
-  static int GetCurrentId();
-};
-
-// ----------------------------------------------------------------------------
 // Miscellaneous
 
 class PlatformData;
 
 // We can't new/delete the type safely without defining it
 // (-Wdelete-incomplete).  Use these to hide the details from clients.
 struct PlatformDataDestructor {
   void operator()(PlatformData*);
--- a/tools/profiler/core/shared-libraries-linux.cc
+++ b/tools/profiler/core/shared-libraries-linux.cc
@@ -178,17 +178,17 @@ SharedLibraryInfo SharedLibraryInfo::Get
     // So if libxul was loaded by the system linker (e.g. as part of
     // xpcshell when running tests), it won't be available and we should
     // not call it.
     return info;
   }
 #endif
 
   // Read info from /proc/self/maps. We ignore most of it.
-  pid_t pid = getpid();
+  pid_t pid = profiler_current_process_id();
   char path[PATH_MAX];
   SprintfLiteral(path, "/proc/%d/maps", pid);
   std::ifstream maps(path);
   std::string line;
   while (std::getline(maps, line)) {
     int ret;
     unsigned long start;
     unsigned long end;
--- a/tools/profiler/lul/LulMain.cpp
+++ b/tools/profiler/lul/LulMain.cpp
@@ -24,17 +24,17 @@
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
 
 #include "LulCommonExt.h"
 #include "LulElfExt.h"
 
 #include "LulMainInt.h"
 
-#include "platform-linux-lul.h"  // for gettid()
+#include "GeckoProfiler.h"  // for profiler_current_thread_id()
 
 // Set this to 1 for verbose logging
 #define DEBUG_MAIN 0
 
 namespace lul {
 
 using mozilla::CheckedInt;
 using mozilla::DebugOnly;
@@ -679,29 +679,30 @@ class PriMap {
   // a logging sink, for debugging.
   void (*mLog)(const char*);
 };
 
 ////////////////////////////////////////////////////////////////
 // LUL                                                        //
 ////////////////////////////////////////////////////////////////
 
-#define LUL_LOG(_str)                                                  \
-  do {                                                                 \
-    char buf[200];                                                     \
-    SprintfLiteral(buf, "LUL: pid %d tid %d lul-obj %p: %s", getpid(), \
-                   gettid(), this, (_str));                            \
-    buf[sizeof(buf) - 1] = 0;                                          \
-    mLog(buf);                                                         \
+#define LUL_LOG(_str)                                           \
+  do {                                                          \
+    char buf[200];                                              \
+    SprintfLiteral(buf, "LUL: pid %d tid %d lul-obj %p: %s",    \
+                   profiler_current_process_id(),               \
+                   profiler_current_thread_id(), this, (_str)); \
+    buf[sizeof(buf) - 1] = 0;                                   \
+    mLog(buf);                                                  \
   } while (0)
 
 LUL::LUL(void (*aLog)(const char*))
     : mLog(aLog),
       mAdminMode(true),
-      mAdminThreadId(gettid()),
+      mAdminThreadId(profiler_current_thread_id()),
       mPriMap(new PriMap(aLog)),
       mSegArray(new SegArray()),
       mUSU(new UniqueStringUniverse()) {
   LUL_LOG("LUL::LUL: Created object");
 }
 
 LUL::~LUL() {
   LUL_LOG("LUL::~LUL: Destroyed object");
@@ -744,25 +745,25 @@ size_t LUL::SizeOfIncludingThis(MallocSi
 
   return n;
 }
 
 void LUL::EnableUnwinding() {
   LUL_LOG("LUL::EnableUnwinding");
   // Don't assert for Admin mode here.  That is, tolerate a call here
   // if we are already in Unwinding mode.
-  MOZ_RELEASE_ASSERT(gettid() == mAdminThreadId);
+  MOZ_RELEASE_ASSERT(profiler_current_thread_id() == mAdminThreadId);
 
   mAdminMode = false;
 }
 
 void LUL::NotifyAfterMap(uintptr_t aRXavma, size_t aSize, const char* aFileName,
                          const void* aMappedImage) {
   MOZ_RELEASE_ASSERT(mAdminMode);
-  MOZ_RELEASE_ASSERT(gettid() == mAdminThreadId);
+  MOZ_RELEASE_ASSERT(profiler_current_thread_id() == mAdminThreadId);
 
   mLog(":\n");
   char buf[200];
   SprintfLiteral(buf, "NotifyMap %llx %llu %s\n",
                  (unsigned long long int)aRXavma, (unsigned long long int)aSize,
                  aFileName);
   buf[sizeof(buf) - 1] = 0;
   mLog(buf);
@@ -797,17 +798,17 @@ void LUL::NotifyAfterMap(uintptr_t aRXav
     // Tell the segment array about the mapping, so that the stack
     // scan and __kernel_syscall mechanisms know where valid code is.
     mSegArray->add(aRXavma, aRXavma + aSize - 1, true);
   }
 }
 
 void LUL::NotifyExecutableArea(uintptr_t aRXavma, size_t aSize) {
   MOZ_RELEASE_ASSERT(mAdminMode);
-  MOZ_RELEASE_ASSERT(gettid() == mAdminThreadId);
+  MOZ_RELEASE_ASSERT(profiler_current_thread_id() == mAdminThreadId);
 
   mLog(":\n");
   char buf[200];
   SprintfLiteral(buf, "NotifyExecutableArea %llx %llu\n",
                  (unsigned long long int)aRXavma,
                  (unsigned long long int)aSize);
   buf[sizeof(buf) - 1] = 0;
   mLog(buf);
@@ -817,17 +818,17 @@ void LUL::NotifyExecutableArea(uintptr_t
     // Tell the segment array about the mapping, so that the stack
     // scan and __kernel_syscall mechanisms know where valid code is.
     mSegArray->add(aRXavma, aRXavma + aSize - 1, true);
   }
 }
 
 void LUL::NotifyBeforeUnmap(uintptr_t aRXavmaMin, uintptr_t aRXavmaMax) {
   MOZ_RELEASE_ASSERT(mAdminMode);
-  MOZ_RELEASE_ASSERT(gettid() == mAdminThreadId);
+  MOZ_RELEASE_ASSERT(profiler_current_thread_id() == mAdminThreadId);
 
   mLog(":\n");
   char buf[100];
   SprintfLiteral(buf, "NotifyUnmap %016llx-%016llx\n",
                  (unsigned long long int)aRXavmaMin,
                  (unsigned long long int)aRXavmaMax);
   buf[sizeof(buf) - 1] = 0;
   mLog(buf);
@@ -845,17 +846,17 @@ void LUL::NotifyBeforeUnmap(uintptr_t aR
   SprintfLiteral(buf, "NotifyUnmap: now have %d SecMaps\n",
                  (int)mPriMap->CountSecMaps());
   buf[sizeof(buf) - 1] = 0;
   mLog(buf);
 }
 
 size_t LUL::CountMappings() {
   MOZ_RELEASE_ASSERT(mAdminMode);
-  MOZ_RELEASE_ASSERT(gettid() == mAdminThreadId);
+  MOZ_RELEASE_ASSERT(profiler_current_thread_id() == mAdminThreadId);
 
   return mPriMap->CountSecMaps();
 }
 
 // RUNS IN NO-MALLOC CONTEXT
 static TaggedUWord DerefTUW(TaggedUWord aAddr, const StackImage* aStackImg) {
   if (!aAddr.Valid()) {
     return TaggedUWord();
--- a/tools/profiler/lul/platform-linux-lul.cpp
+++ b/tools/profiler/lul/platform-linux-lul.cpp
@@ -68,10 +68,11 @@ void read_procmaps(lul::LUL* aLUL) {
 }
 
 // LUL needs a callback for its logging sink.
 void logging_sink_for_LUL(const char* str) {
   // These are only printed when Verbose logging is enabled (e.g. with
   // MOZ_LOG="prof:5"). This is because LUL's logging is much more verbose than
   // the rest of the profiler's logging, which occurs at the Info (3) and Debug
   // (4) levels.
-  MOZ_LOG(gProfilerLog, mozilla::LogLevel::Verbose, ("[%d] %s", getpid(), str));
+  MOZ_LOG(gProfilerLog, mozilla::LogLevel::Verbose,
+          ("[%d] %s", profiler_current_process_id(), str));
 }
--- a/tools/profiler/moz.build
+++ b/tools/profiler/moz.build
@@ -33,17 +33,17 @@ if CONFIG['MOZ_GECKO_PROFILER']:
         'gecko/nsProfilerStartParams.cpp',
         'gecko/ProfilerChild.cpp',
         'gecko/ProfilerIOInterposeObserver.cpp',
         'gecko/ProfilerParent.cpp',
         'gecko/ThreadResponsiveness.cpp',
     ]
     if CONFIG['MOZ_REPLACE_MALLOC'] and CONFIG['MOZ_PROFILER_MEMORY']:
         SOURCES += [
-            'core/memory_hooks.cpp', # conflicts with platform.h class Thread
+            'core/memory_hooks.cpp', # Non-unified because of order of #includes
         ]
 
     XPCOM_MANIFESTS += [
         'gecko/components.conf',
     ]
 
     if CONFIG['OS_TARGET'] == 'Darwin':
         # This file cannot be built in unified mode because it includes
--- a/tools/profiler/public/GeckoProfiler.h
+++ b/tools/profiler/public/GeckoProfiler.h
@@ -445,16 +445,19 @@ void profiler_get_start_params(
     int* aEntrySize, mozilla::Maybe<double>* aDuration, double* aInterval,
     uint32_t* aFeatures,
     mozilla::Vector<const char*, 0, mozilla::MallocAllocPolicy>* aFilters);
 
 // The number of milliseconds since the process started. Operates the same
 // whether the profiler is active or inactive.
 double profiler_time();
 
+// Get the current process's ID.
+int profiler_current_process_id();
+
 // Get the current thread's ID.
 int profiler_current_thread_id();
 
 // An object of this class is passed to profiler_suspend_and_sample_thread().
 // For each stack frame, one of the Collect methods will be called.
 class ProfilerStackCollector {
  public:
   // Some collectors need to worry about possibly overwriting previous
--- a/tools/profiler/tasktracer/GeckoTaskTracer.cpp
+++ b/tools/profiler/tasktracer/GeckoTaskTracer.cpp
@@ -17,21 +17,16 @@
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "prtime.h"
 
 #include <stdarg.h>
 
-#if defined(GP_OS_windows)
-#  include <windows.h>
-#  define getpid GetCurrentProcessId
-#endif
-
 #define MAX_SIZE_LOG (1024 * 128)
 
 // NS_ENSURE_TRUE_VOID() without the warning on the debug build.
 #define ENSURE_TRUE_VOID(x)   \
   do {                        \
     if (MOZ_UNLIKELY(!(x))) { \
       return;                 \
     }                         \
@@ -215,30 +210,30 @@ TraceInfoHolder GetOrCreateTraceInfo() {
 
   if (info && info->mObsolete) {
     // TraceInfo is obsolete: remove it.
     FreeTraceInfo(info);
     info = nullptr;
   }
 
   if (!info) {
-    info = AllocTraceInfo(Thread::GetCurrentId());
+    info = AllocTraceInfo(profiler_current_thread_id());
     sTraceInfoTLS.set(info);
   }
 
   return TraceInfoHolder{info};  // |mLogsMutex| will be held, then
                                  // ||sMutex| will be released for
                                  // efficiency reason.
 }
 
 uint64_t GenNewUniqueTaskId() {
   TraceInfoHolder info = GetOrCreateTraceInfo();
   ENSURE_TRUE(info, 0);
 
-  int tid = Thread::GetCurrentId();
+  int tid = profiler_current_thread_id();
   uint64_t taskid = ((uint64_t)tid << 32) | ++info->mLastUniqueTaskId;
   return taskid;
 }
 
 AutoSaveCurTraceInfoImpl::AutoSaveCurTraceInfoImpl() {
   GetCurTraceInfo(&mSavedSourceEventId, &mSavedTaskId, &mSavedSourceEventType);
 }
 
@@ -301,18 +296,18 @@ void LogBegin(uint64_t aTaskId, uint64_t
 
   // Log format:
   // [1 taskId beginTime processId threadId]
   TraceInfoLogType* log = info->AppendLog();
   if (log) {
     log->mBegin.mType = ACTION_BEGIN;
     log->mBegin.mTaskId = aTaskId;
     log->mBegin.mTime = GetTimestamp();
-    log->mBegin.mPid = getpid();
-    log->mBegin.mTid = Thread::GetCurrentId();
+    log->mBegin.mPid = profiler_current_process_id();
+    log->mBegin.mTid = profiler_current_thread_id();
 
     MOZ_ASSERT(log->mBegin.mPid >= 0,
                "native process ID is < 0 (signed integer overflow)");
     MOZ_ASSERT(log->mBegin.mTid >= 0,
                "native thread ID is < 0  (signed integer overflow)");
   }
 }
 
--- a/tools/profiler/tests/gtest/GeckoProfiler.cpp
+++ b/tools/profiler/tests/gtest/GeckoProfiler.cpp
@@ -861,17 +861,17 @@ void DoSuspendAndSample(int aTid, nsIThr
 }
 
 TEST(GeckoProfiler, SuspendAndSample)
 {
   nsCOMPtr<nsIThread> thread;
   nsresult rv = NS_NewNamedThread("GeckoProfGTest", getter_AddRefs(thread));
   ASSERT_TRUE(NS_SUCCEEDED(rv));
 
-  int tid = Thread::GetCurrentId();
+  int tid = profiler_current_thread_id();
 
   ASSERT_TRUE(!profiler_is_active());
 
   // Suspend and sample while the profiler is inactive.
   DoSuspendAndSample(tid, thread);
 
   uint32_t features = ProfilerFeature::JS | ProfilerFeature::Threads;
   const char* filters[] = {"GeckoMain", "Compositor"};