tor-browser

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

BaseProfilerUtils.h (7551B)


      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 #ifndef BaseProfilerUtils_h
      8 #define BaseProfilerUtils_h
      9 
     10 // This header contains most process- and thread-related functions.
     11 // It is safe to include unconditionally.
     12 
     13 // --------------------------------------------- WASI process & thread ids
     14 #if defined(__wasi__)
     15 
     16 namespace mozilla::baseprofiler::detail {
     17 using ProcessIdType = unsigned;
     18 using ThreadIdType = unsigned;
     19 }  // namespace mozilla::baseprofiler::detail
     20 
     21 // --------------------------------------------- Windows process & thread ids
     22 #elif defined(XP_WIN)
     23 
     24 namespace mozilla::baseprofiler::detail {
     25 using ProcessIdType = int;
     26 using ThreadIdType = unsigned long;
     27 }  // namespace mozilla::baseprofiler::detail
     28 
     29 // --------------------------------------------- Non-Windows process id
     30 #else
     31 // All non-Windows platforms are assumed to be POSIX, which has getpid().
     32 
     33 #  include <unistd.h>
     34 namespace mozilla::baseprofiler::detail {
     35 using ProcessIdType = decltype(getpid());
     36 }  // namespace mozilla::baseprofiler::detail
     37 
     38 // --------------------------------------------- Non-Windows thread id
     39 // ------------------------------------------------------- macOS
     40 #  if defined(XP_MACOSX)
     41 
     42 namespace mozilla::baseprofiler::detail {
     43 using ThreadIdType = uint64_t;
     44 }  // namespace mozilla::baseprofiler::detail
     45 
     46 // ------------------------------------------------------- Android
     47 // Test Android before Linux, because Linux includes Android.
     48 #  elif defined(__ANDROID__) || defined(ANDROID)
     49 
     50 #    include <sys/types.h>
     51 namespace mozilla::baseprofiler::detail {
     52 using ThreadIdType = decltype(gettid());
     53 }  // namespace mozilla::baseprofiler::detail
     54 
     55 // ------------------------------------------------------- Linux
     56 #  elif defined(XP_LINUX)
     57 
     58 namespace mozilla::baseprofiler::detail {
     59 using ThreadIdType = long;
     60 }  // namespace mozilla::baseprofiler::detail
     61 
     62 // ------------------------------------------------------- FreeBSD
     63 #  elif defined(XP_FREEBSD)
     64 
     65 namespace mozilla::baseprofiler::detail {
     66 using ThreadIdType = long;
     67 }  // namespace mozilla::baseprofiler::detail
     68 
     69 // ------------------------------------------------------- Others
     70 #  else
     71 
     72 #    include <thread>
     73 
     74 namespace mozilla::baseprofiler::detail {
     75 using ThreadIdType = std::thread::id;
     76 }  // namespace mozilla::baseprofiler::detail
     77 
     78 #  endif
     79 #endif  // End of non-XP_WIN.
     80 
     81 #include <stdint.h>
     82 #include <string.h>
     83 #include <type_traits>
     84 
     85 namespace mozilla::baseprofiler {
     86 
     87 // Trivially-copyable class containing a process id. It may be left unspecified.
     88 class BaseProfilerProcessId {
     89 public:
     90  using NativeType = detail::ProcessIdType;
     91 
     92  using NumberType =
     93      std::conditional_t<(sizeof(NativeType) <= 4), uint32_t, uint64_t>;
     94  static_assert(sizeof(NativeType) <= sizeof(NumberType));
     95 
     96  // Unspecified process id.
     97  constexpr BaseProfilerProcessId() = default;
     98 
     99  [[nodiscard]] constexpr bool IsSpecified() const {
    100    return mProcessId != scUnspecified;
    101  }
    102 
    103  // Construct from a native type.
    104  [[nodiscard]] static BaseProfilerProcessId FromNativeId(
    105      const NativeType& aNativeProcessId) {
    106    BaseProfilerProcessId id;
    107    // Convert trivially-copyable native id by copying its bits.
    108    static_assert(std::is_trivially_copyable_v<NativeType>);
    109    memcpy(&id.mProcessId, &aNativeProcessId, sizeof(NativeType));
    110    return id;
    111  }
    112 
    113  // Get the process id as a number, which may be unspecified.
    114  // This should only be used for serialization or logging.
    115  [[nodiscard]] constexpr NumberType ToNumber() const { return mProcessId; }
    116 
    117  // BaseProfilerProcessId from given number (which may be unspecified).
    118  constexpr static BaseProfilerProcessId FromNumber(
    119      const NumberType& aProcessId) {
    120    BaseProfilerProcessId id;
    121    id.mProcessId = aProcessId;
    122    return id;
    123  }
    124 
    125  [[nodiscard]] constexpr bool operator==(
    126      const BaseProfilerProcessId& aOther) const {
    127    return mProcessId == aOther.mProcessId;
    128  }
    129  [[nodiscard]] constexpr bool operator!=(
    130      const BaseProfilerProcessId& aOther) const {
    131    return mProcessId != aOther.mProcessId;
    132  }
    133 
    134 private:
    135  static constexpr NumberType scUnspecified = 0;
    136  NumberType mProcessId = scUnspecified;
    137 };
    138 
    139 // Check traits. These should satisfy usage in std::atomic.
    140 static_assert(std::is_trivially_copyable_v<BaseProfilerProcessId>);
    141 static_assert(std::is_copy_constructible_v<BaseProfilerProcessId>);
    142 static_assert(std::is_move_constructible_v<BaseProfilerProcessId>);
    143 static_assert(std::is_copy_assignable_v<BaseProfilerProcessId>);
    144 static_assert(std::is_move_assignable_v<BaseProfilerProcessId>);
    145 
    146 // Trivially-copyable class containing a thread id. It may be left unspecified.
    147 class BaseProfilerThreadId {
    148 public:
    149  using NativeType = detail::ThreadIdType;
    150 
    151  using NumberType =
    152      std::conditional_t<(sizeof(NativeType) <= 4), uint32_t, uint64_t>;
    153  static_assert(sizeof(NativeType) <= sizeof(NumberType));
    154 
    155  // Unspecified thread id.
    156  constexpr BaseProfilerThreadId() = default;
    157 
    158  [[nodiscard]] constexpr bool IsSpecified() const {
    159    return mThreadId != scUnspecified;
    160  }
    161 
    162  // Construct from a native type.
    163  [[nodiscard]] static BaseProfilerThreadId FromNativeId(
    164      const NativeType& aNativeThreadId) {
    165    BaseProfilerThreadId id;
    166    // Convert trivially-copyable native id by copying its bits.
    167    static_assert(std::is_trivially_copyable_v<NativeType>);
    168    memcpy(&id.mThreadId, &aNativeThreadId, sizeof(NativeType));
    169    return id;
    170  }
    171 
    172  // Get the thread id as a number, which may be unspecified.
    173  // This should only be used for serialization or logging.
    174  [[nodiscard]] constexpr NumberType ToNumber() const { return mThreadId; }
    175 
    176  // BaseProfilerThreadId from given number (which may be unspecified).
    177  constexpr static BaseProfilerThreadId FromNumber(
    178      const NumberType& aThreadId) {
    179    BaseProfilerThreadId id;
    180    id.mThreadId = aThreadId;
    181    return id;
    182  }
    183 
    184  [[nodiscard]] constexpr bool operator==(
    185      const BaseProfilerThreadId& aOther) const {
    186    return mThreadId == aOther.mThreadId;
    187  }
    188  [[nodiscard]] constexpr bool operator!=(
    189      const BaseProfilerThreadId& aOther) const {
    190    return mThreadId != aOther.mThreadId;
    191  }
    192 
    193 private:
    194  static constexpr NumberType scUnspecified = 0;
    195  NumberType mThreadId = scUnspecified;
    196 };
    197 
    198 // Check traits. These should satisfy usage in std::atomic.
    199 static_assert(std::is_trivially_copyable_v<BaseProfilerThreadId>);
    200 static_assert(std::is_copy_constructible_v<BaseProfilerThreadId>);
    201 static_assert(std::is_move_constructible_v<BaseProfilerThreadId>);
    202 static_assert(std::is_copy_assignable_v<BaseProfilerThreadId>);
    203 static_assert(std::is_move_assignable_v<BaseProfilerThreadId>);
    204 
    205 }  // namespace mozilla::baseprofiler
    206 
    207 #include "mozilla/Types.h"
    208 
    209 namespace mozilla::baseprofiler {
    210 
    211 // Get the current process's ID.
    212 [[nodiscard]] MFBT_API BaseProfilerProcessId profiler_current_process_id();
    213 
    214 // Get the current thread's ID.
    215 [[nodiscard]] MFBT_API BaseProfilerThreadId profiler_current_thread_id();
    216 
    217 // Must be called at least once from the main thread, before any other main-
    218 // thread id function.
    219 MFBT_API void profiler_init_main_thread_id();
    220 
    221 [[nodiscard]] MFBT_API BaseProfilerThreadId profiler_main_thread_id();
    222 
    223 [[nodiscard]] MFBT_API bool profiler_is_main_thread();
    224 
    225 }  // namespace mozilla::baseprofiler
    226 
    227 #endif  // BaseProfilerUtils_h