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