diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2023-08-09 13:09:54 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2023-10-16 13:38:18 +0000 |
commit | acbcf08a6dffdfe90a6eaf661fcd6923f0de2447 (patch) | |
tree | 749564d8cf9b3d49cdae1cce9ec8ce0602900f1c /chromium/base/task/thread_pool | |
parent | 266cfa0fb83513250bcefd8234e0916c195a4b2e (diff) |
BASELINE: Update Chromium to 114.0.5735.248
Change-Id: Ie7ddd5d87175d4bde196f774c742cdbb9d5d311a
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/495463
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/base/task/thread_pool')
10 files changed, 74 insertions, 291 deletions
diff --git a/chromium/base/task/thread_pool/pooled_sequenced_task_runner.h b/chromium/base/task/thread_pool/pooled_sequenced_task_runner.h index cecd937cde8..16a41ced6e2 100644 --- a/chromium/base/task/thread_pool/pooled_sequenced_task_runner.h +++ b/chromium/base/task/thread_pool/pooled_sequenced_task_runner.h @@ -52,7 +52,9 @@ class BASE_EXPORT PooledSequencedTaskRunner private: ~PooledSequencedTaskRunner() override; - const raw_ptr<PooledTaskRunnerDelegate> pooled_task_runner_delegate_; + // Dangling usage guarded by MatchesCurrentDelegate() checks. + const raw_ptr<PooledTaskRunnerDelegate, DisableDanglingPtrDetection> + pooled_task_runner_delegate_; // Sequence for all Tasks posted through this TaskRunner. const scoped_refptr<Sequence> sequence_; diff --git a/chromium/base/task/thread_pool/task_tracker.cc b/chromium/base/task/thread_pool/task_tracker.cc index 51f2e15b1b5..94db917305a 100644 --- a/chromium/base/task/thread_pool/task_tracker.cc +++ b/chromium/base/task/thread_pool/task_tracker.cc @@ -17,7 +17,6 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" -#include "base/no_destructor.h" #include "base/notreached.h" #include "base/sequence_token.h" #include "base/strings/string_util.h" @@ -26,13 +25,13 @@ #include "base/task/scoped_set_task_priority_for_current_thread.h" #include "base/task/sequenced_task_runner.h" #include "base/task/single_thread_task_runner.h" -#include "base/task/task_executor.h" #include "base/threading/sequence_local_storage_map.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "base/trace_event/base_tracing.h" #include "base/values.h" #include "build/build_config.h" +#include "third_party/abseil-cpp/absl/base/attributes.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace base { @@ -121,11 +120,7 @@ auto EmitThreadPoolTraceEventMetadata(perfetto::EventContext& ctx, #endif // BUILDFLAG(ENABLE_BASE_TRACING) } -base::ThreadLocalBoolean& GetFizzleBlockShutdownTaskFlag() { - static base::NoDestructor<base::ThreadLocalBoolean> - fizzle_block_shutdown_tasks; - return *fizzle_block_shutdown_tasks; -} +ABSL_CONST_INIT thread_local bool fizzle_block_shutdown_tasks = false; } // namespace @@ -318,8 +313,7 @@ bool TaskTracker::WillPostTask(Task* task, // A non BLOCK_SHUTDOWN task is allowed to be posted iff shutdown hasn't // started and the task is not delayed. if (shutdown_behavior != TaskShutdownBehavior::BLOCK_SHUTDOWN || - !task->delayed_run_time.is_null() || - GetFizzleBlockShutdownTaskFlag().Get()) { + !task->delayed_run_time.is_null() || fizzle_block_shutdown_tasks) { return false; } @@ -424,11 +418,11 @@ bool TaskTracker::IsShutdownComplete() const { } void TaskTracker::BeginFizzlingBlockShutdownTasks() { - GetFizzleBlockShutdownTaskFlag().Set(true); + fizzle_block_shutdown_tasks = true; } void TaskTracker::EndFizzlingBlockShutdownTasks() { - GetFizzleBlockShutdownTaskFlag().Set(false); + fizzle_block_shutdown_tasks = false; } void TaskTracker::RunTask(Task task, diff --git a/chromium/base/task/thread_pool/task_tracker.h b/chromium/base/task/thread_pool/task_tracker.h index 2a25c36f7ea..b4267faf481 100644 --- a/chromium/base/task/thread_pool/task_tracker.h +++ b/chromium/base/task/thread_pool/task_tracker.h @@ -217,7 +217,7 @@ class BASE_EXPORT TaskTracker { TaskSource* task_source, const SequenceToken& token); - void NOT_TAIL_CALLED RunTaskImpl(Task& task, + NOT_TAIL_CALLED void RunTaskImpl(Task& task, const TaskTraits& traits, TaskSource* task_source, const SequenceToken& token); diff --git a/chromium/base/task/thread_pool/thread_group.cc b/chromium/base/task/thread_pool/thread_group.cc index 2855a21fd42..f5aca2f952d 100644 --- a/chromium/base/task/thread_pool/thread_group.cc +++ b/chromium/base/task/thread_pool/thread_group.cc @@ -9,11 +9,10 @@ #include "base/feature_list.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" -#include "base/lazy_instance.h" #include "base/task/task_features.h" #include "base/task/thread_pool/task_tracker.h" -#include "base/threading/thread_local.h" #include "build/build_config.h" +#include "third_party/abseil-cpp/absl/base/attributes.h" #if BUILDFLAG(IS_WIN) #include "base/win/com_init_check_hook.h" @@ -26,12 +25,7 @@ namespace internal { namespace { // ThreadGroup that owns the current thread, if any. -LazyInstance<ThreadLocalPointer<const ThreadGroup>>::Leaky - tls_current_thread_group = LAZY_INSTANCE_INITIALIZER; - -const ThreadGroup* GetCurrentThreadGroup() { - return tls_current_thread_group.Get().Get(); -} +ABSL_CONST_INIT thread_local const ThreadGroup* current_thread_group = nullptr; } // namespace @@ -82,17 +76,17 @@ ThreadGroup::ThreadGroup(TrackedRef<TaskTracker> task_tracker, ThreadGroup::~ThreadGroup() = default; void ThreadGroup::BindToCurrentThread() { - DCHECK(!GetCurrentThreadGroup()); - tls_current_thread_group.Get().Set(this); + DCHECK(!CurrentThreadHasGroup()); + current_thread_group = this; } void ThreadGroup::UnbindFromCurrentThread() { - DCHECK(GetCurrentThreadGroup()); - tls_current_thread_group.Get().Set(nullptr); + DCHECK(IsBoundToCurrentThread()); + current_thread_group = nullptr; } bool ThreadGroup::IsBoundToCurrentThread() const { - return GetCurrentThreadGroup() == this; + return current_thread_group == this; } void ThreadGroup::Start() { @@ -346,7 +340,7 @@ ThreadGroup::GetScopedWindowsThreadEnvironment(WorkerEnvironment environment) { // static bool ThreadGroup::CurrentThreadHasGroup() { - return GetCurrentThreadGroup() != nullptr; + return current_thread_group != nullptr; } } // namespace internal diff --git a/chromium/base/task/thread_pool/thread_group_impl_unittest.cc b/chromium/base/task/thread_pool/thread_group_impl_unittest.cc index 3bbc5c95a89..70a3d185033 100644 --- a/chromium/base/task/thread_pool/thread_group_impl_unittest.cc +++ b/chromium/base/task/thread_pool/thread_group_impl_unittest.cc @@ -47,7 +47,6 @@ #include "base/threading/simple_thread.h" #include "base/threading/thread.h" #include "base/threading/thread_checker_impl.h" -#include "base/threading/thread_local_storage.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "build/build_config.h" @@ -594,94 +593,6 @@ TEST_F(BackgroundThreadGroupImplTest, UpdatePriorityBlockingStarted) { namespace { -constexpr size_t kMagicTlsValue = 42; - -class ThreadGroupImplCheckTlsReuse : public ThreadGroupImplImplTest { - public: - ThreadGroupImplCheckTlsReuse(const ThreadGroupImplCheckTlsReuse&) = delete; - ThreadGroupImplCheckTlsReuse& operator=(const ThreadGroupImplCheckTlsReuse&) = - delete; - - void SetTlsValueAndWait() { - slot_.Set(reinterpret_cast<void*>(kMagicTlsValue)); - waiter_.Wait(); - } - - void CountZeroTlsValuesAndWait(TestWaitableEvent* count_waiter) { - if (!slot_.Get()) - subtle::NoBarrier_AtomicIncrement(&zero_tls_values_, 1); - - count_waiter->Signal(); - waiter_.Wait(); - } - - protected: - ThreadGroupImplCheckTlsReuse() = default; - - void SetUp() override { - CreateAndStartThreadGroup(kReclaimTimeForCleanupTests, kMaxTasks); - } - - subtle::Atomic32 zero_tls_values_ = 0; - - TestWaitableEvent waiter_; - - private: - ThreadLocalStorage::Slot slot_; -}; - -} // namespace - -// Checks that at least one worker has been cleaned up by checking the TLS. -TEST_F(ThreadGroupImplCheckTlsReuse, CheckCleanupWorkers) { - // Saturate the workers and mark each worker's thread with a magic TLS value. - std::vector<std::unique_ptr<test::TestTaskFactory>> factories; - for (size_t i = 0; i < kMaxTasks; ++i) { - factories.push_back(std::make_unique<test::TestTaskFactory>( - test::CreatePooledTaskRunner({WithBaseSyncPrimitives()}, - &mock_pooled_task_runner_delegate_), - TaskSourceExecutionMode::kParallel)); - ASSERT_TRUE(factories.back()->PostTask( - PostNestedTask::NO, - BindOnce(&ThreadGroupImplCheckTlsReuse::SetTlsValueAndWait, - Unretained(this)))); - factories.back()->WaitForAllTasksToRun(); - } - - // Release tasks waiting on |waiter_|. - waiter_.Signal(); - thread_group_->WaitForAllWorkersIdleForTesting(); - - // All workers should be done running by now, so reset for the next phase. - waiter_.Reset(); - - // Wait for the thread group to clean up at least one worker. - thread_group_->WaitForWorkersCleanedUpForTesting(1U); - - // Saturate and count the worker threads that do not have the magic TLS value. - // If the value is not there, that means we're at a new worker. - std::vector<std::unique_ptr<TestWaitableEvent>> count_waiters; - for (auto& factory : factories) { - count_waiters.push_back(std::make_unique<TestWaitableEvent>()); - ASSERT_TRUE(factory->PostTask( - PostNestedTask::NO, - BindOnce(&ThreadGroupImplCheckTlsReuse::CountZeroTlsValuesAndWait, - Unretained(this), count_waiters.back().get()))); - factory->WaitForAllTasksToRun(); - } - - // Wait for all counters to complete. - for (auto& count_waiter : count_waiters) - count_waiter->Wait(); - - EXPECT_GT(subtle::NoBarrier_Load(&zero_tls_values_), 0); - - // Release tasks waiting on |waiter_|. - waiter_.Signal(); -} - -namespace { - class ThreadGroupImplStandbyPolicyTest : public ThreadGroupImplImplTestBase, public testing::Test { public: @@ -704,139 +615,6 @@ TEST_F(ThreadGroupImplStandbyPolicyTest, InitOne) { EXPECT_EQ(1U, thread_group_->NumberOfWorkersForTesting()); } -// Verify that the ThreadGroupImpl keeps at least one idle standby -// thread, capacity permitting. -TEST_F(ThreadGroupImplStandbyPolicyTest, VerifyStandbyThread) { - auto task_runner = test::CreatePooledTaskRunner( - {WithBaseSyncPrimitives()}, &mock_pooled_task_runner_delegate_); - - TestWaitableEvent thread_running(WaitableEvent::ResetPolicy::AUTOMATIC); - TestWaitableEvent threads_continue; - - RepeatingClosure thread_blocker = BindLambdaForTesting([&]() { - thread_running.Signal(); - threads_continue.Wait(); - }); - - // There should be one idle thread until we reach capacity - for (size_t i = 0; i < kMaxTasks; ++i) { - EXPECT_EQ(i + 1, thread_group_->NumberOfWorkersForTesting()); - task_runner->PostTask(FROM_HERE, thread_blocker); - thread_running.Wait(); - } - - // There should not be an extra idle thread if it means going above capacity - EXPECT_EQ(kMaxTasks, thread_group_->NumberOfWorkersForTesting()); - - threads_continue.Signal(); - // Wait long enough for all but one worker to clean up. - thread_group_->WaitForWorkersCleanedUpForTesting(kMaxTasks - 1); - EXPECT_EQ(1U, thread_group_->NumberOfWorkersForTesting()); - // Give extra time for a worker to cleanup : none should as the thread group - // is expected to keep a worker ready regardless of how long it was idle for. - PlatformThread::Sleep(kReclaimTimeForCleanupTests); - EXPECT_EQ(1U, thread_group_->NumberOfWorkersForTesting()); -} - -// Verify that being "the" idle thread counts as being active (i.e. won't be -// reclaimed even if not on top of the idle stack when reclaim timeout expires). -// Regression test for https://crbug.com/847501. -TEST_F(ThreadGroupImplStandbyPolicyTest, InAndOutStandbyThreadIsActive) { - auto sequenced_task_runner = test::CreatePooledSequencedTaskRunner( - {}, &mock_pooled_task_runner_delegate_); - - TestWaitableEvent timer_started; - - RepeatingTimer recurring_task; - sequenced_task_runner->PostTask( - FROM_HERE, BindLambdaForTesting([&]() { - recurring_task.Start(FROM_HERE, kReclaimTimeForCleanupTests / 2, - DoNothing()); - timer_started.Signal(); - })); - - timer_started.Wait(); - - // Running a task should have brought up a new standby thread. - EXPECT_EQ(2U, thread_group_->NumberOfWorkersForTesting()); - - // Give extra time for a worker to cleanup : none should as the two workers - // are both considered "active" per the timer ticking faster than the reclaim - // timeout. - PlatformThread::Sleep(kReclaimTimeForCleanupTests * 2); - EXPECT_EQ(2U, thread_group_->NumberOfWorkersForTesting()); - - sequenced_task_runner->PostTask(FROM_HERE, BindLambdaForTesting([&]() { - recurring_task.AbandonAndStop(); - })); - - // Stopping the recurring task should let the second worker be reclaimed per - // not being "the" standby thread for a full reclaim timeout. - thread_group_->WaitForWorkersCleanedUpForTesting(1); - EXPECT_EQ(1U, thread_group_->NumberOfWorkersForTesting()); -} - -// Verify that being "the" idle thread counts as being active but isn't sticky. -// Regression test for https://crbug.com/847501. -TEST_F(ThreadGroupImplStandbyPolicyTest, OnlyKeepActiveStandbyThreads) { - auto sequenced_task_runner = test::CreatePooledSequencedTaskRunner( - {}, &mock_pooled_task_runner_delegate_); - - // Start this test like - // ThreadGroupImplStandbyPolicyTest.InAndOutStandbyThreadIsActive and - // give it some time to stabilize. - RepeatingTimer recurring_task; - sequenced_task_runner->PostTask( - FROM_HERE, BindLambdaForTesting([&]() { - recurring_task.Start(FROM_HERE, kReclaimTimeForCleanupTests / 2, - DoNothing()); - })); - - PlatformThread::Sleep(kReclaimTimeForCleanupTests * 2); - EXPECT_EQ(2U, thread_group_->NumberOfWorkersForTesting()); - - // Then also flood the thread group (cycling the top of the idle stack). - { - auto task_runner = test::CreatePooledTaskRunner( - {WithBaseSyncPrimitives()}, &mock_pooled_task_runner_delegate_); - - TestWaitableEvent thread_running(WaitableEvent::ResetPolicy::AUTOMATIC); - TestWaitableEvent threads_continue; - - RepeatingClosure thread_blocker = BindLambdaForTesting([&]() { - thread_running.Signal(); - threads_continue.Wait(); - }); - - for (size_t i = 0; i < kMaxTasks; ++i) { - task_runner->PostTask(FROM_HERE, thread_blocker); - thread_running.Wait(); - } - - EXPECT_EQ(kMaxTasks, thread_group_->NumberOfWorkersForTesting()); - threads_continue.Signal(); - - // Flush to ensure all references to |threads_continue| are gone before it - // goes out of scope. - task_tracker_.FlushForTesting(); - } - - // All workers should clean up but two (since the timer is still running). - thread_group_->WaitForWorkersCleanedUpForTesting(kMaxTasks - 2); - EXPECT_EQ(2U, thread_group_->NumberOfWorkersForTesting()); - - // Extra time shouldn't change this. - PlatformThread::Sleep(kReclaimTimeForCleanupTests * 2); - EXPECT_EQ(2U, thread_group_->NumberOfWorkersForTesting()); - - // Stopping the timer should let the number of active threads go down to one. - sequenced_task_runner->PostTask(FROM_HERE, BindLambdaForTesting([&]() { - recurring_task.AbandonAndStop(); - })); - thread_group_->WaitForWorkersCleanedUpForTesting(1); - EXPECT_EQ(1U, thread_group_->NumberOfWorkersForTesting()); -} - namespace { enum class OptionalBlockingType { diff --git a/chromium/base/task/thread_pool/thread_pool_impl.cc b/chromium/base/task/thread_pool/thread_pool_impl.cc index 4eedf8f24b4..6573385304d 100644 --- a/chromium/base/task/thread_pool/thread_pool_impl.cc +++ b/chromium/base/task/thread_pool/thread_pool_impl.cc @@ -65,12 +65,6 @@ bool HasDisableBestEffortTasksSwitch() { // internal edge case. bool g_synchronous_thread_start_for_testing = false; -// Verifies that |traits| do not have properties that are banned in ThreadPool. -void AssertNoExtensionInTraits(const base::TaskTraits& traits) { - DCHECK_EQ(traits.extension_id(), - TaskTraitsExtensionStorage::kInvalidExtensionId); -} - } // namespace ThreadPoolImpl::ThreadPoolImpl(StringPiece histogram_label) @@ -228,7 +222,6 @@ bool ThreadPoolImpl::PostDelayedTask(const Location& from_here, const TaskTraits& traits, OnceClosure task, TimeDelta delay) { - AssertNoExtensionInTraits(traits); // Post |task| as part of a one-off single-task Sequence. return PostTaskWithSequence( Task(from_here, std::move(task), TimeTicks::Now(), delay, @@ -239,13 +232,11 @@ bool ThreadPoolImpl::PostDelayedTask(const Location& from_here, scoped_refptr<TaskRunner> ThreadPoolImpl::CreateTaskRunner( const TaskTraits& traits) { - AssertNoExtensionInTraits(traits); return MakeRefCounted<PooledParallelTaskRunner>(traits, this); } scoped_refptr<SequencedTaskRunner> ThreadPoolImpl::CreateSequencedTaskRunner( const TaskTraits& traits) { - AssertNoExtensionInTraits(traits); return MakeRefCounted<PooledSequencedTaskRunner>(traits, this); } @@ -253,7 +244,6 @@ scoped_refptr<SingleThreadTaskRunner> ThreadPoolImpl::CreateSingleThreadTaskRunner( const TaskTraits& traits, SingleThreadTaskRunnerThreadMode thread_mode) { - AssertNoExtensionInTraits(traits); return single_thread_task_runner_manager_.CreateSingleThreadTaskRunner( traits, thread_mode); } @@ -262,7 +252,6 @@ ThreadPoolImpl::CreateSingleThreadTaskRunner( scoped_refptr<SingleThreadTaskRunner> ThreadPoolImpl::CreateCOMSTATaskRunner( const TaskTraits& traits, SingleThreadTaskRunnerThreadMode thread_mode) { - AssertNoExtensionInTraits(traits); return single_thread_task_runner_manager_.CreateCOMSTATaskRunner(traits, thread_mode); } @@ -270,7 +259,6 @@ scoped_refptr<SingleThreadTaskRunner> ThreadPoolImpl::CreateCOMSTATaskRunner( scoped_refptr<UpdateableSequencedTaskRunner> ThreadPoolImpl::CreateUpdateableSequencedTaskRunner(const TaskTraits& traits) { - AssertNoExtensionInTraits(traits); return MakeRefCounted<PooledSequencedTaskRunner>(traits, this); } diff --git a/chromium/base/task/thread_pool/thread_pool_impl.h b/chromium/base/task/thread_pool/thread_pool_impl.h index 6b113ee7c1c..38b68257657 100644 --- a/chromium/base/task/thread_pool/thread_pool_impl.h +++ b/chromium/base/task/thread_pool/thread_pool_impl.h @@ -15,7 +15,6 @@ #include "base/strings/string_piece.h" #include "base/synchronization/atomic_flag.h" #include "base/task/single_thread_task_runner_thread_mode.h" -#include "base/task/task_executor.h" #include "base/task/task_traits.h" #include "base/task/thread_pool/delayed_task_manager.h" #include "base/task/thread_pool/environment_config.h" @@ -43,7 +42,6 @@ namespace internal { // Default ThreadPoolInstance implementation. This class is thread-safe, except // for methods noted otherwise in thread_pool_instance.h. class BASE_EXPORT ThreadPoolImpl : public ThreadPoolInstance, - public TaskExecutor, public ThreadGroup::Delegate, public PooledTaskRunnerDelegate { public: @@ -82,25 +80,6 @@ class BASE_EXPORT ThreadPoolImpl : public ThreadPoolInstance, void BeginFizzlingBlockShutdownTasks() override; void EndFizzlingBlockShutdownTasks() override; - // TaskExecutor: - bool PostDelayedTask(const Location& from_here, - const TaskTraits& traits, - OnceClosure task, - TimeDelta delay) override; - scoped_refptr<TaskRunner> CreateTaskRunner(const TaskTraits& traits) override; - scoped_refptr<SequencedTaskRunner> CreateSequencedTaskRunner( - const TaskTraits& traits) override; - scoped_refptr<SingleThreadTaskRunner> CreateSingleThreadTaskRunner( - const TaskTraits& traits, - SingleThreadTaskRunnerThreadMode thread_mode) override; -#if BUILDFLAG(IS_WIN) - scoped_refptr<SingleThreadTaskRunner> CreateCOMSTATaskRunner( - const TaskTraits& traits, - SingleThreadTaskRunnerThreadMode thread_mode) override; -#endif // BUILDFLAG(IS_WIN) - scoped_refptr<UpdateableSequencedTaskRunner> - CreateUpdateableSequencedTaskRunner(const TaskTraits& traits); - // PooledTaskRunnerDelegate: bool EnqueueJobTaskSource(scoped_refptr<JobTaskSource> task_source) override; void RemoveJobTaskSource(scoped_refptr<JobTaskSource> task_source) override; @@ -126,6 +105,54 @@ class BASE_EXPORT ThreadPoolImpl : public ThreadPoolInstance, // configuration param because only one internal test truly needs this. static void SetSynchronousThreadStartForTesting(bool enabled); + // Posts |task| with a |delay| and specific |traits|. |delay| can be zero. For + // one off tasks that don't require a TaskRunner. Returns false if the task + // definitely won't run because of current shutdown state. + bool PostDelayedTask(const Location& from_here, + const TaskTraits& traits, + OnceClosure task, + TimeDelta delay); + + // Returns a TaskRunner whose PostTask invocations result in scheduling tasks + // using |traits|. Tasks may run in any order and in parallel. + scoped_refptr<TaskRunner> CreateTaskRunner(const TaskTraits& traits); + + // Returns a SequencedTaskRunner whose PostTask invocations result in + // scheduling tasks using |traits|. Tasks run one at a time in posting order. + scoped_refptr<SequencedTaskRunner> CreateSequencedTaskRunner( + const TaskTraits& traits); + + // Returns a SingleThreadTaskRunner whose PostTask invocations result in + // scheduling tasks using |traits|. Tasks run on a single thread in posting + // order. If |traits| identifies an existing thread, + // SingleThreadTaskRunnerThreadMode::SHARED must be used. + scoped_refptr<SingleThreadTaskRunner> CreateSingleThreadTaskRunner( + const TaskTraits& traits, + SingleThreadTaskRunnerThreadMode thread_mode); + +#if BUILDFLAG(IS_WIN) + // Returns a SingleThreadTaskRunner whose PostTask invocations result in + // scheduling tasks using |traits| in a COM Single-Threaded Apartment. Tasks + // run in the same Single-Threaded Apartment in posting order for the returned + // SingleThreadTaskRunner. If |traits| identifies an existing thread, + // SingleThreadTaskRunnerThreadMode::SHARED must be used. + scoped_refptr<SingleThreadTaskRunner> CreateCOMSTATaskRunner( + const TaskTraits& traits, + SingleThreadTaskRunnerThreadMode thread_mode); +#endif // BUILDFLAG(IS_WIN) + + // Returns a task runner whose PostTask invocations result in scheduling tasks + // using |traits|. The priority in |traits| can be updated at any time via + // UpdateableSequencedTaskRunner::UpdatePriority(). An update affects all + // tasks posted to the task runner that aren't running yet. Tasks run one at a + // time in posting order. + // + // |traits| requirements: + // - base::ThreadPolicy must be specified if the priority of the task runner + // will ever be increased from BEST_EFFORT. + scoped_refptr<UpdateableSequencedTaskRunner> + CreateUpdateableSequencedTaskRunner(const TaskTraits& traits); + private: // Invoked after |num_fences_| or |num_best_effort_fences_| is updated. Sets // the CanRunPolicy in TaskTracker and wakes up workers as appropriate. diff --git a/chromium/base/task/thread_pool/thread_pool_instance.cc b/chromium/base/task/thread_pool/thread_pool_instance.cc index 2a915be21a4..cd0b13db62b 100644 --- a/chromium/base/task/thread_pool/thread_pool_instance.cc +++ b/chromium/base/task/thread_pool/thread_pool_instance.cc @@ -7,6 +7,7 @@ #include <algorithm> #include "base/check.h" +#include "base/cxx17_backports.h" #include "base/memory/ptr_util.h" #include "base/system/sys_info.h" #include "base/task/thread_pool/thread_pool_impl.h" @@ -25,10 +26,11 @@ size_t GetDefaultMaxNumUtilityThreads(size_t max_num_foreground_threads_in) { int num_of_efficient_processors = SysInfo::NumberOfEfficientProcessors(); if (num_of_efficient_processors != 0) { DCHECK_GT(num_of_efficient_processors, 0); - return std::min(max_num_foreground_threads_in, - static_cast<size_t>(num_of_efficient_processors)); + return std::max<size_t>( + 2, std::min(max_num_foreground_threads_in, + static_cast<size_t>(num_of_efficient_processors))); } - return std::max<size_t>(1, max_num_foreground_threads_in / 2); + return std::max<size_t>(2, max_num_foreground_threads_in / 2); } } // namespace diff --git a/chromium/base/task/thread_pool/worker_thread.h b/chromium/base/task/thread_pool/worker_thread.h index 77b2fc1cc94..8fea0ce4948 100644 --- a/chromium/base/task/thread_pool/worker_thread.h +++ b/chromium/base/task/thread_pool/worker_thread.h @@ -214,7 +214,7 @@ class BASE_EXPORT WorkerThread : public RefCountedThreadSafe<WorkerThread>, // ThreadMain() -> RunLabeledWorker() -> RunWorker(). // "RunLabeledWorker()" is a dummy frame based on ThreadLabel+ThreadType // and used to easily identify threads in stack traces. - void NOT_TAIL_CALLED RunWorker(); + NOT_TAIL_CALLED void RunWorker(); // Self-reference to prevent destruction of |this| while the thread is alive. // Set in Start() before creating the thread. Reset in ThreadMain() before the diff --git a/chromium/base/task/thread_pool/worker_thread_unittest.cc b/chromium/base/task/thread_pool/worker_thread_unittest.cc index 02439b8edff..c5c2a5027f2 100644 --- a/chromium/base/task/thread_pool/worker_thread_unittest.cc +++ b/chromium/base/task/thread_pool/worker_thread_unittest.cc @@ -42,6 +42,7 @@ #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && \ PA_CONFIG(THREAD_CACHE_SUPPORTED) +#include "base/allocator/partition_allocator/extended_api.h" // nogncheck #include "base/allocator/partition_allocator/thread_cache.h" #endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && // PA_CONFIG(THREAD_CACHE_SUPPORTED) @@ -926,11 +927,8 @@ class WorkerThreadThreadCacheDelegate : public WorkerThreadDefaultDelegate { TEST(ThreadPoolWorkerThreadCachePurgeTest, Purge) { // Make sure the thread cache is enabled in the main partition. - if (!allocator_shim::internal::PartitionAllocMalloc::Allocator() - ->thread_cache_for_testing()) { - allocator_shim::internal::PartitionAllocMalloc::Allocator() - ->EnableThreadCacheIfSupported(); - } + partition_alloc::internal::ThreadCacheProcessScopeForTesting scope( + allocator_shim::internal::PartitionAllocMalloc::Allocator()); Thread service_thread = Thread("ServiceThread"); Thread::Options service_thread_options; |