blob: 3b1cbf8a660982d51edc73044a9f236d4d01a7fa [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2019 The Chromium Authors
Alex Clarke831ed1e62019-02-18 21:10:082// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/scheduler/browser_ui_thread_scheduler.h"
6
mikt541ac712025-08-04 03:16:227#include <memory>
Alex Clarke831ed1e62019-02-18 21:10:088#include <utility>
9
Alex Clarke9018deb2019-03-18 19:17:3410#include "base/feature_list.h"
Anand Ravi5e3bf102025-05-02 15:24:4911#include "base/functional/bind.h"
Alex Clarke831ed1e62019-02-18 21:10:0812#include "base/memory/ptr_util.h"
Alex Clarke636e7052019-05-30 10:49:3713#include "base/message_loop/message_pump.h"
Chris Sharp7840c582019-08-02 15:45:3214#include "base/message_loop/message_pump_type.h"
Alex Clarke831ed1e62019-02-18 21:10:0815#include "base/process/process.h"
Carlos Caballeroff8c5032019-04-01 11:15:0816#include "base/run_loop.h"
Alex Clarke831ed1e62019-02-18 21:10:0817#include "base/task/sequence_manager/sequence_manager.h"
18#include "base/task/sequence_manager/sequence_manager_impl.h"
Carlos Caballeroc472c2bf2019-04-18 09:30:3619#include "base/task/sequence_manager/task_queue.h"
Alex Clarke831ed1e62019-02-18 21:10:0820#include "base/task/sequence_manager/time_domain.h"
21#include "base/threading/platform_thread.h"
Stephen Nusko408b9a92022-09-15 10:03:5722#include "base/trace_event/trace_event.h"
Alex Clarke831ed1e62019-02-18 21:10:0823#include "build/build_config.h"
Scott Haseley72d89b02023-02-17 03:29:2524#include "content/browser/scheduler/browser_task_priority.h"
mikt541ac712025-08-04 03:16:2225#include "content/common/features.h"
Carlos Caballero5f6212b2019-05-13 13:45:1626#include "content/public/browser/browser_thread.h"
Alex Clarke9018deb2019-03-18 19:17:3427#include "content/public/common/content_features.h"
Alex Clarke831ed1e62019-02-18 21:10:0828
Stephen Nusko408b9a92022-09-15 10:03:5729namespace {
30
31content::BrowserUIThreadScheduler* g_browser_ui_thread_scheduler = nullptr;
32
33} // namespace
Alex Clarke831ed1e62019-02-18 21:10:0834namespace content {
35
36BrowserUIThreadScheduler::~BrowserUIThreadScheduler() = default;
37
38// static
39std::unique_ptr<BrowserUIThreadScheduler>
mikt541ac712025-08-04 03:16:2240BrowserUIThreadScheduler::CreateForTesting() {
41 auto scheduler = base::WrapUnique(new BrowserUIThreadScheduler());
42 scheduler->InstallPartitionAllocSchedulerLoopQuarantineTaskObserver();
43 return scheduler;
44}
45// static
46std::unique_ptr<BrowserUIThreadScheduler>
Alex Clarke831ed1e62019-02-18 21:10:0847BrowserUIThreadScheduler::CreateForTesting(
Etienne Pierre-doray40545ac2021-11-11 13:34:2848 base::sequence_manager::SequenceManager* sequence_manager) {
mikt541ac712025-08-04 03:16:2249 auto scheduler =
50 base::WrapUnique(new BrowserUIThreadScheduler(sequence_manager));
51 scheduler->InstallPartitionAllocSchedulerLoopQuarantineTaskObserver();
52 return scheduler;
Alex Clarke831ed1e62019-02-18 21:10:0853}
Stephen Nusko408b9a92022-09-15 10:03:5754BrowserUIThreadScheduler* BrowserUIThreadScheduler::Get() {
55 DCHECK(g_browser_ui_thread_scheduler);
56 return g_browser_ui_thread_scheduler;
57}
Alex Clarke831ed1e62019-02-18 21:10:0858BrowserUIThreadScheduler::BrowserUIThreadScheduler()
59 : owned_sequence_manager_(
60 base::sequence_manager::CreateUnboundSequenceManager(
Alex Clarke5f3d461b2019-04-29 14:23:1161 base::sequence_manager::SequenceManager::Settings::Builder()
Chris Sharp7840c582019-08-02 15:45:3262 .SetMessagePumpType(base::MessagePumpType::UI)
François Doraye616cfc2023-03-06 15:52:2963 .SetCanRunTasksByBatches(true)
Scott Haseley72d89b02023-02-17 03:29:2564 .SetPrioritySettings(
65 internal::CreateBrowserTaskPrioritySettings())
Patrick Monettea2e2f9c2025-08-06 14:25:0166 .SetIsMainThread(true)
Anand Ravi5e3bf102025-05-02 15:24:4967 .SetShouldSampleCPUTime(true)
Anand Ravi3007a572025-08-08 15:11:3368 .SetShouldReportLockMetrics(true)
Alex Clarke5f3d461b2019-04-29 14:23:1169 .Build())),
Etienne Pierre-doray40545ac2021-11-11 13:34:2870 task_queues_(BrowserThread::UI, owned_sequence_manager_.get()),
François Doray253a3062022-10-24 16:45:2971 handle_(task_queues_.GetHandle()) {
Anand Ravi5e3bf102025-05-02 15:24:4972 task_queues_.SetOnTaskCompletedHandler(base::BindRepeating(
73 &BrowserUIThreadScheduler::OnTaskCompleted, base::Unretained(this)));
Carlos Caballero5f6212b2019-05-13 13:45:1674 CommonSequenceManagerSetup(owned_sequence_manager_.get());
Alex Clarke49854cc2019-06-27 08:25:4975 owned_sequence_manager_->SetDefaultTaskRunner(
76 handle_->GetDefaultTaskRunner());
Alex Clarke831ed1e62019-02-18 21:10:0877
Carlos Caballero5f6212b2019-05-13 13:45:1678 owned_sequence_manager_->BindToMessagePump(
Chris Sharp7840c582019-08-02 15:45:3279 base::MessagePump::Create(base::MessagePumpType::UI));
Stephen Nusko408b9a92022-09-15 10:03:5780 g_browser_ui_thread_scheduler = this;
Alex Clarke831ed1e62019-02-18 21:10:0881}
82
83BrowserUIThreadScheduler::BrowserUIThreadScheduler(
Etienne Pierre-doray40545ac2021-11-11 13:34:2884 base::sequence_manager::SequenceManager* sequence_manager)
85 : task_queues_(BrowserThread::UI, sequence_manager),
François Doray253a3062022-10-24 16:45:2986 handle_(task_queues_.GetHandle()) {
Carlos Caballero5f6212b2019-05-13 13:45:1687 CommonSequenceManagerSetup(sequence_manager);
Stephen Nusko408b9a92022-09-15 10:03:5788 g_browser_ui_thread_scheduler = this;
Alex Clarke831ed1e62019-02-18 21:10:0889}
90
Carlos Caballero5f6212b2019-05-13 13:45:1691void BrowserUIThreadScheduler::CommonSequenceManagerSetup(
92 base::sequence_manager::SequenceManager* sequence_manager) {
Scott Haseley72d89b02023-02-17 03:29:2593 DCHECK_EQ(static_cast<size_t>(sequence_manager->GetPriorityCount()),
94 static_cast<size_t>(internal::BrowserTaskPriority::kPriorityCount));
Alexander Timine653dfc2020-01-07 17:55:0695 sequence_manager->EnableCrashKeys("ui_scheduler_async_stack");
Carlos Caballeroff8c5032019-04-01 11:15:0896}
97
Anand Ravi5e3bf102025-05-02 15:24:4998void BrowserUIThreadScheduler::OnTaskCompleted(
99 const base::sequence_manager::Task& task,
100 base::sequence_manager::TaskQueue::TaskTiming* task_timing,
101 base::LazyNow* lazy_now) {
102 // Note: Thread time is already subsampled in sequence manager by a factor of
103 // |kTaskSamplingRateForRecordingCPUTime|. So browser main can piggy back on
104 // that subsampling to record histograms without fear of oversampling.
105 task_timing->RecordTaskEnd(lazy_now);
106 task_timing->RecordUmaOnCpuMetrics("BrowserScheduler.UIThread");
107}
108
mikt541ac712025-08-04 03:16:22109void BrowserUIThreadScheduler::
110 InstallPartitionAllocSchedulerLoopQuarantineTaskObserver() {
111 if (base::FeatureList::IsEnabled(
112 features::
113 kPartitionAllocSchedulerLoopQuarantineTaskObserverForBrowserUIThread)) {
114 task_queues_.AddTaskObserver(&scheduler_loop_quarantine_task_observer_);
115 }
116}
117
Alex Clarke831ed1e62019-02-18 21:10:08118} // namespace content