tor-browser

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

scoped_thread_priority.h (3374B)


      1 // Copyright 2019 The Chromium Authors
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_THREADING_SCOPED_THREAD_PRIORITY_H_
      6 #define BASE_THREADING_SCOPED_THREAD_PRIORITY_H_
      7 
      8 #include <atomic>
      9 
     10 #include "base/base_export.h"
     11 #include "base/compiler_specific.h"
     12 #include "base/location.h"
     13 #include "base/macros/uniquify.h"
     14 #include "base/memory/raw_ptr.h"
     15 #include "build/build_config.h"
     16 #include "third_party/abseil-cpp/absl/types/optional.h"
     17 
     18 namespace base {
     19 
     20 class Location;
     21 enum class ThreadType : int;
     22 
     23 // All code that may load a DLL on a background thread must be surrounded by a
     24 // scope that starts with this macro.
     25 //
     26 // Example:
     27 //   Foo();
     28 //   {
     29 //     SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY();
     30 //     LoadMyDll();
     31 //   }
     32 //   Bar();
     33 //
     34 // The macro raises the thread priority to NORMAL for the scope if no other
     35 // thread has completed the current scope already (multiple threads can racily
     36 // begin the initialization and will all be boosted for it). On Windows, loading
     37 // a DLL on a background thread can lead to a priority inversion on the loader
     38 // lock and cause huge janks.
     39 #define SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY()                  \
     40  static std::atomic_bool BASE_UNIQUIFY(already_loaded){false};           \
     41  base::internal::ScopedMayLoadLibraryAtBackgroundPriority BASE_UNIQUIFY( \
     42      scoped_may_load_library_at_background_priority)(                    \
     43      FROM_HERE, &BASE_UNIQUIFY(already_loaded));
     44 
     45 // Like SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY, but raises the thread
     46 // priority every time the scope is entered. Use this around code that may
     47 // conditionally load a DLL each time it is executed, or which repeatedly loads
     48 // and unloads DLLs.
     49 #define SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY_REPEATEDLY()       \
     50  base::internal::ScopedMayLoadLibraryAtBackgroundPriority BASE_UNIQUIFY( \
     51      scoped_may_load_library_at_background_priority)(FROM_HERE, nullptr);
     52 
     53 // Boosts the current thread's priority to match the priority of threads of
     54 // |target_thread_type| in this scope.
     55 class BASE_EXPORT ScopedBoostPriority {
     56 public:
     57  explicit ScopedBoostPriority(ThreadType target_thread_type);
     58  ~ScopedBoostPriority();
     59 
     60  ScopedBoostPriority(const ScopedBoostPriority&) = delete;
     61  ScopedBoostPriority& operator=(const ScopedBoostPriority&) = delete;
     62 
     63 private:
     64  absl::optional<ThreadType> original_thread_type_;
     65 };
     66 
     67 namespace internal {
     68 
     69 class BASE_EXPORT ScopedMayLoadLibraryAtBackgroundPriority {
     70 public:
     71  // Boosts thread priority to NORMAL within its scope if |already_loaded| is
     72  // nullptr or set to false.
     73  explicit ScopedMayLoadLibraryAtBackgroundPriority(
     74      const Location& from_here,
     75      std::atomic_bool* already_loaded);
     76 
     77  ScopedMayLoadLibraryAtBackgroundPriority(
     78      const ScopedMayLoadLibraryAtBackgroundPriority&) = delete;
     79  ScopedMayLoadLibraryAtBackgroundPriority& operator=(
     80      const ScopedMayLoadLibraryAtBackgroundPriority&) = delete;
     81 
     82  ~ScopedMayLoadLibraryAtBackgroundPriority();
     83 
     84 private:
     85 #if BUILDFLAG(IS_WIN)
     86  // The original priority when invoking entering the scope().
     87  absl::optional<ThreadType> original_thread_type_;
     88  const raw_ptr<std::atomic_bool> already_loaded_;
     89 #endif
     90 };
     91 
     92 }  // namespace internal
     93 
     94 }  // namespace base
     95 
     96 #endif  // BASE_THREADING_SCOPED_THREAD_PRIORITY_H_