Commit 032f23b1 authored by Gerald Squelart's avatar Gerald Squelart
Browse files

Bug 1721569 - Change id native types to reflect what each platform really provides - r=florian

parent 1f76b475
Loading
Loading
Loading
Loading
+20 −27
Original line number Diff line number Diff line
@@ -14,22 +14,21 @@
// --------------------------------------------- Windows process & thread ids
#if defined(XP_WIN)

#  include "mozilla/Assertions.h"

#  include <process.h>
#  include <processthreadsapi.h>

namespace mozilla::baseprofiler {

BaseProfilerProcessId profiler_current_process_id() {
  return BaseProfilerProcessId::FromNumber(_getpid());
  return BaseProfilerProcessId::FromNativeId(_getpid());
}

BaseProfilerThreadId profiler_current_thread_id() {
  DWORD threadId = GetCurrentThreadId();
  MOZ_ASSERT(threadId <= INT32_MAX, "native thread ID is > INT32_MAX");
  return BaseProfilerThreadId::FromNumber(
      static_cast<BaseProfilerThreadId::NumberType>(threadId));
  static_assert(std::is_same_v<BaseProfilerThreadId::NativeType,
                               decltype(GetCurrentThreadId())>,
                "BaseProfilerThreadId::NativeType must be exactly the type "
                "returned by GetCurrentThreadId()");
  return BaseProfilerThreadId::FromNativeId(GetCurrentThreadId());
}

}  // namespace mozilla::baseprofiler
@@ -43,7 +42,7 @@ BaseProfilerThreadId profiler_current_thread_id() {
namespace mozilla::baseprofiler {

BaseProfilerProcessId profiler_current_process_id() {
  return BaseProfilerProcessId::FromNumber(getpid());
  return BaseProfilerProcessId::FromNativeId(getpid());
}

}  // namespace mozilla::baseprofiler
@@ -58,13 +57,10 @@ namespace mozilla::baseprofiler {

BaseProfilerThreadId profiler_current_thread_id() {
  uint64_t tid;
  pthread_threadid_np(nullptr, &tid);
  // Cast the uint64_t value to NumberType, which is an int.
  // In theory, this risks truncating the value. It's unknown if such large
  // values occur in reality.
  // It may be worth changing our cross-platform tid type to 64 bits.
  return BaseProfilerThreadId::FromNumber(
      static_cast<BaseProfilerThreadId::NumberType>(tid));
  if (pthread_threadid_np(nullptr, &tid) != 0) {
    return BaseProfilerThreadId{};
  }
  return BaseProfilerThreadId::FromNativeId(tid);
}

}  // namespace mozilla::baseprofiler
@@ -73,13 +69,10 @@ BaseProfilerThreadId profiler_current_thread_id() {
// Test Android before Linux, because Linux includes Android.
#  elif defined(__ANDROID__) || defined(ANDROID)

#    include <sys/types.h>

namespace mozilla::baseprofiler {

BaseProfilerThreadId profiler_current_thread_id() {
  return BaseProfilerThreadId::FromNumber(
      static_cast<BaseProfilerThreadId::NumberType>(gettid()));
  return BaseProfilerThreadId::FromNativeId(gettid());
}

}  // namespace mozilla::baseprofiler
@@ -93,8 +86,7 @@ namespace mozilla::baseprofiler {

BaseProfilerThreadId profiler_current_thread_id() {
  // glibc doesn't provide a wrapper for gettid() until 2.30
  return BaseProfilerThreadId::FromNumber(
      static_cast<BaseProfilerThreadId::NumberType>(syscall(SYS_gettid)));
  return BaseProfilerThreadId::FromNativeId(syscall(SYS_gettid));
}

}  // namespace mozilla::baseprofiler
@@ -108,15 +100,16 @@ namespace mozilla::baseprofiler {

BaseProfilerThreadId profiler_current_thread_id() {
  long id;
  (void)thr_self(&id);
  return BaseProfilerThreadId::FromNumber(
      static_cast<BaseProfilerThreadId::NumberType>(id));
  if (thr_self(&id) != 0) {
    return BaseProfilerThreadId{};
  }
  return BaseProfilerThreadId::FromNativeId(id);
}

}  // namespace mozilla::baseprofiler

// ------------------------------------------------------- Others
#  else  // Unsupported platforms.
#  else

namespace mozilla::baseprofiler {

@@ -126,7 +119,7 @@ BaseProfilerThreadId profiler_current_thread_id() {

}  // namespace mozilla::baseprofiler

#  endif  // End of unsupported platforms.
#  endif
#endif  // End of non-XP_WIN.

// --------------------------------------------- Platform-agnostic definitions
+96 −10
Original line number Diff line number Diff line
@@ -10,6 +10,66 @@
// This header contains most process- and thread-related functions.
// It is safe to include unconditionally.

// --------------------------------------------- Windows process & thread ids
#if defined(XP_WIN)

namespace mozilla::baseprofiler::detail {
using ProcessIdType = int;
using ThreadIdType = unsigned long;
}  // namespace mozilla::baseprofiler::detail

// --------------------------------------------- Non-Windows process id
#else
// All non-Windows platforms are assumed to be POSIX, which has getpid().

#  include <unistd.h>
namespace mozilla::baseprofiler::detail {
using ProcessIdType = decltype(getpid());
}  // namespace mozilla::baseprofiler::detail

// --------------------------------------------- Non-Windows thread id
// ------------------------------------------------------- macOS
#  if defined(XP_MACOSX)

namespace mozilla::baseprofiler::detail {
using ThreadIdType = uint64_t;
}  // namespace mozilla::baseprofiler::detail

// ------------------------------------------------------- Android
// Test Android before Linux, because Linux includes Android.
#  elif defined(__ANDROID__) || defined(ANDROID)

#    include <sys/types.h>
namespace mozilla::baseprofiler::detail {
using ThreadIdType = decltype(gettid());
}  // namespace mozilla::baseprofiler::detail

// ------------------------------------------------------- Linux
#  elif defined(XP_LINUX)

namespace mozilla::baseprofiler::detail {
using ThreadIdType = long;
}  // namespace mozilla::baseprofiler::detail

// ------------------------------------------------------- FreeBSD
#  elif defined(XP_FREEBSD)

namespace mozilla::baseprofiler::detail {
using ThreadIdType = long;
}  // namespace mozilla::baseprofiler::detail

// ------------------------------------------------------- Others
#  else

namespace mozilla::baseprofiler::detail {
using ThreadIdType = int;
}  // namespace mozilla::baseprofiler::detail

#  endif
#endif  // End of non-XP_WIN.

#include <stdint.h>
#include <string.h>
#include <type_traits>

namespace mozilla::baseprofiler {
@@ -17,6 +77,12 @@ namespace mozilla::baseprofiler {
// Trivially-copyable class containing a process id. It may be left unspecified.
class BaseProfilerProcessId {
 public:
  using NativeType = detail::ProcessIdType;

  using NumberType =
      std::conditional_t<(sizeof(NativeType) <= 4), uint32_t, uint64_t>;
  static_assert(sizeof(NativeType) <= sizeof(NumberType));

  // Unspecified process id.
  constexpr BaseProfilerProcessId() = default;

@@ -24,7 +90,15 @@ class BaseProfilerProcessId {
    return mProcessId != scUnspecified;
  }

  using NumberType = int;
  // Construct from a native type.
  [[nodiscard]] static BaseProfilerProcessId FromNativeId(
      const NativeType& aNativeProcessId) {
    BaseProfilerProcessId id;
    // Convert trivially-copyable native id by copying its bits.
    static_assert(std::is_trivially_copyable_v<NativeType>);
    memcpy(&id.mProcessId, &aNativeProcessId, sizeof(NativeType));
    return id;
  }

  // Get the process id as a number, which may be unspecified.
  // This should only be used for serialization or logging.
@@ -33,7 +107,9 @@ class BaseProfilerProcessId {
  // BaseProfilerProcessId from given number (which may be unspecified).
  constexpr static BaseProfilerProcessId FromNumber(
      const NumberType& aProcessId) {
    return BaseProfilerProcessId{aProcessId};
    BaseProfilerProcessId id;
    id.mProcessId = aProcessId;
    return id;
  }

  [[nodiscard]] constexpr bool operator==(
@@ -46,9 +122,6 @@ class BaseProfilerProcessId {
  }

 private:
  constexpr explicit BaseProfilerProcessId(const NumberType& aProcessId)
      : mProcessId(aProcessId) {}

  static constexpr NumberType scUnspecified = 0;
  NumberType mProcessId = scUnspecified;
};
@@ -63,6 +136,12 @@ static_assert(std::is_move_assignable_v<BaseProfilerProcessId>);
// Trivially-copyable class containing a thread id. It may be left unspecified.
class BaseProfilerThreadId {
 public:
  using NativeType = detail::ThreadIdType;

  using NumberType =
      std::conditional_t<(sizeof(NativeType) <= 4), uint32_t, uint64_t>;
  static_assert(sizeof(NativeType) <= sizeof(NumberType));

  // Unspecified thread id.
  constexpr BaseProfilerThreadId() = default;

@@ -70,7 +149,15 @@ class BaseProfilerThreadId {
    return mThreadId != scUnspecified;
  }

  using NumberType = int;
  // Construct from a native type.
  [[nodiscard]] static BaseProfilerThreadId FromNativeId(
      const NativeType& aNativeThreadId) {
    BaseProfilerThreadId id;
    // Convert trivially-copyable native id by copying its bits.
    static_assert(std::is_trivially_copyable_v<NativeType>);
    memcpy(&id.mThreadId, &aNativeThreadId, sizeof(NativeType));
    return id;
  }

  // Get the thread id as a number, which may be unspecified.
  // This should only be used for serialization or logging.
@@ -79,7 +166,9 @@ class BaseProfilerThreadId {
  // BaseProfilerThreadId from given number (which may be unspecified).
  constexpr static BaseProfilerThreadId FromNumber(
      const NumberType& aThreadId) {
    return BaseProfilerThreadId{aThreadId};
    BaseProfilerThreadId id;
    id.mThreadId = aThreadId;
    return id;
  }

  [[nodiscard]] constexpr bool operator==(
@@ -92,9 +181,6 @@ class BaseProfilerThreadId {
  }

 private:
  constexpr explicit BaseProfilerThreadId(const NumberType& aThreadId)
      : mThreadId(aThreadId) {}

  static constexpr NumberType scUnspecified = 0;
  NumberType mThreadId = scUnspecified;
};
+20 −27
Original line number Diff line number Diff line
@@ -14,20 +14,19 @@
// --------------------------------------------- Windows process & thread ids
#if defined(XP_WIN)

#  include "mozilla/Assertions.h"

#  include <process.h>
#  include <processthreadsapi.h>

ProfilerProcessId profiler_current_process_id() {
  return ProfilerProcessId::FromNumber(_getpid());
  return ProfilerProcessId::FromNativeId(_getpid());
}

ProfilerThreadId profiler_current_thread_id() {
  DWORD threadId = GetCurrentThreadId();
  MOZ_ASSERT(threadId <= INT32_MAX, "native thread ID is > INT32_MAX");
  return ProfilerThreadId::FromNumber(
      static_cast<ProfilerThreadId::NumberType>(threadId));
  static_assert(std::is_same_v<ProfilerThreadId::NativeType,
                               decltype(GetCurrentThreadId())>,
                "ProfilerThreadId::NativeType must be exactly the type "
                "returned by GetCurrentThreadId()");
  return ProfilerThreadId::FromNativeId(GetCurrentThreadId());
}

// --------------------------------------------- Non-Windows process id
@@ -37,7 +36,7 @@ ProfilerThreadId profiler_current_thread_id() {
#  include <unistd.h>

ProfilerProcessId profiler_current_process_id() {
  return ProfilerProcessId::FromNumber(getpid());
  return ProfilerProcessId::FromNativeId(getpid());
}

// --------------------------------------------- Non-Windows thread id
@@ -48,24 +47,18 @@ ProfilerProcessId profiler_current_process_id() {

ProfilerThreadId profiler_current_thread_id() {
  uint64_t tid;
  pthread_threadid_np(nullptr, &tid);
  // Cast the uint64_t value to NumberType, which is an int.
  // In theory, this risks truncating the value. It's unknown if such large
  // values occur in reality.
  // It may be worth changing our cross-platform tid type to 64 bits.
  return ProfilerThreadId::FromNumber(
      static_cast<ProfilerThreadId::NumberType>(tid));
  if (pthread_threadid_np(nullptr, &tid) != 0) {
    return ProfilerThreadId{};
  }
  return ProfilerThreadId::FromNativeId(tid);
}

// ------------------------------------------------------- Android
// Test Android before Linux, because Linux includes Android.
#  elif defined(__ANDROID__) || defined(ANDROID)

#    include <sys/types.h>

ProfilerThreadId profiler_current_thread_id() {
  return ProfilerThreadId::FromNumber(
      static_cast<ProfilerThreadId::NumberType>(gettid()));
  return ProfilerThreadId::FromNativeId(gettid());
}

// ------------------------------------------------------- Linux
@@ -75,8 +68,7 @@ ProfilerThreadId profiler_current_thread_id() {

ProfilerThreadId profiler_current_thread_id() {
  // glibc doesn't provide a wrapper for gettid() until 2.30
  return ProfilerThreadId::FromNumber(
      static_cast<ProfilerThreadId::NumberType>(syscall(SYS_gettid)));
  return ProfilerThreadId::FromNativeId(syscall(SYS_gettid));
}

// ------------------------------------------------------- FreeBSD
@@ -86,17 +78,18 @@ ProfilerThreadId profiler_current_thread_id() {

ProfilerThreadId profiler_current_thread_id() {
  long id;
  (void)thr_self(&id);
  return ProfilerThreadId::FromNumber(
      static_cast<ProfilerThreadId::NumberType>(id));
  if (thr_self(&id) != 0) {
    return ProfilerThreadId{};
  }
  return ProfilerThreadId::FromNativeId(id);
}

// ------------------------------------------------------- Others
#  else  // Unsupported platforms.
#  else

ProfilerThreadId profiler_current_thread_id() { return ProfilerThreadId{}; }

#  endif  // End of unsupported platforms.
#  endif
#endif  // End of non-XP_WIN.

// --------------------------------------------- Platform-agnostic definitions