• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "base/threading/scoped_thread_priority.h"
6 
7 #include "base/check_op.h"
8 #include "base/location.h"
9 #include "base/threading/platform_thread.h"
10 #include "base/trace_event/base_tracing.h"
11 #include "build/build_config.h"
12 
13 namespace base {
14 
ScopedBoostPriority(ThreadType target_thread_type)15 ScopedBoostPriority::ScopedBoostPriority(ThreadType target_thread_type) {
16   CHECK_LT(target_thread_type, ThreadType::kRealtimeAudio, NotFatalUntil::M133);
17   const ThreadType original_thread_type =
18       PlatformThread::GetCurrentThreadType();
19   const bool should_boost = original_thread_type < target_thread_type &&
20                             PlatformThread::CanChangeThreadType(
21                                 original_thread_type, target_thread_type) &&
22                             PlatformThread::CanChangeThreadType(
23                                 target_thread_type, original_thread_type);
24   if (should_boost) {
25     original_thread_type_.emplace(original_thread_type);
26     PlatformThread::SetCurrentThreadType(target_thread_type);
27   }
28 }
29 
~ScopedBoostPriority()30 ScopedBoostPriority::~ScopedBoostPriority() {
31   if (original_thread_type_.has_value())
32     PlatformThread::SetCurrentThreadType(original_thread_type_.value());
33 }
34 
35 namespace internal {
36 
37 ScopedMayLoadLibraryAtBackgroundPriority::
ScopedMayLoadLibraryAtBackgroundPriority(const Location & from_here,std::atomic_bool * already_loaded)38     ScopedMayLoadLibraryAtBackgroundPriority(const Location& from_here,
39                                              std::atomic_bool* already_loaded)
40 #if BUILDFLAG(IS_WIN)
41     : already_loaded_(already_loaded)
42 #endif  // BUILDFLAG(IS_WIN)
43 {
44   TRACE_EVENT_BEGIN(
45       "base", "ScopedMayLoadLibraryAtBackgroundPriority",
46       [&](perfetto::EventContext ctx) {
47         ctx.event()->set_source_location_iid(
48             base::trace_event::InternedSourceLocation::Get(&ctx, from_here));
49       });
50 
51 #if BUILDFLAG(IS_WIN)
52   if (already_loaded_ && already_loaded_->load(std::memory_order_relaxed))
53     return;
54 
55   const base::ThreadType thread_type = PlatformThread::GetCurrentThreadType();
56   if (thread_type == base::ThreadType::kBackground) {
57     original_thread_type_ = thread_type;
58     PlatformThread::SetCurrentThreadType(base::ThreadType::kDefault);
59 
60     TRACE_EVENT_BEGIN0(
61         "base",
62         "ScopedMayLoadLibraryAtBackgroundPriority : Priority Increased");
63   }
64 #endif  // BUILDFLAG(IS_WIN)
65 }
66 
67 ScopedMayLoadLibraryAtBackgroundPriority::
~ScopedMayLoadLibraryAtBackgroundPriority()68     ~ScopedMayLoadLibraryAtBackgroundPriority() {
69   // Trace events must be closed in reverse order of opening so that they nest
70   // correctly.
71 #if BUILDFLAG(IS_WIN)
72   if (original_thread_type_) {
73     TRACE_EVENT_END0(
74         "base",
75         "ScopedMayLoadLibraryAtBackgroundPriority : Priority Increased");
76     PlatformThread::SetCurrentThreadType(original_thread_type_.value());
77   }
78 
79   if (already_loaded_)
80     already_loaded_->store(true, std::memory_order_relaxed);
81 #endif  // BUILDFLAG(IS_WIN)
82   TRACE_EVENT_END0("base", "ScopedMayLoadLibraryAtBackgroundPriority");
83 }
84 
85 }  // namespace internal
86 }  // namespace base
87