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