diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-11-28 16:14:41 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-12-13 15:19:41 +0000 |
commit | 61d9742824d54be5693191fe502325a909feca59 (patch) | |
tree | cbf28e779b11338fe52eb75b915684cd8955542c /chromium/base/task/thread_pool | |
parent | 45f9ded08bb7526984b24ccb5a5327aaf6821676 (diff) |
BASELINE: Update Chromium to 108.0.5359.70
Change-Id: I77334ff232b819600f275bd3cfe41fbaa3619230
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/445904
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/base/task/thread_pool')
74 files changed, 734 insertions, 423 deletions
diff --git a/chromium/base/task/thread_pool/can_run_policy_test.h b/chromium/base/task/thread_pool/can_run_policy_test.h index 3a700bf914d..d0a2ac3ee3f 100644 --- a/chromium/base/task/thread_pool/can_run_policy_test.h +++ b/chromium/base/task/thread_pool/can_run_policy_test.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/delayed_priority_queue.cc b/chromium/base/task/thread_pool/delayed_priority_queue.cc new file mode 100644 index 00000000000..50ac00bd93c --- /dev/null +++ b/chromium/base/task/thread_pool/delayed_priority_queue.cc @@ -0,0 +1,189 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/task/thread_pool/delayed_priority_queue.h" + +#include <utility> + +#include "base/check_op.h" +#include "base/memory/ptr_util.h" +#include "base/stl_util.h" + +namespace base::internal { + +// A class combining a TaskSource and the delayed_sort_key that determines its +// position in a DelayedPriorityQueue. Instances are only mutable via +// take_task_source() which can only be called once and renders its instance +// invalid after the call. +class DelayedPriorityQueue::TaskSourceAndDelayedSortKey { + public: + TaskSourceAndDelayedSortKey() = default; + TaskSourceAndDelayedSortKey(scoped_refptr<TaskSource> task_source, + const TimeTicks& delayed_sort_key) + : task_source_(std::move(task_source)), + delayed_sort_key_(delayed_sort_key) { + DCHECK(task_source_); + } + TaskSourceAndDelayedSortKey(const TaskSourceAndDelayedSortKey&) = delete; + TaskSourceAndDelayedSortKey& operator=(const TaskSourceAndDelayedSortKey&) = + delete; + + // Note: while |task_source_| should always be non-null post-move (i.e. we + // shouldn't be moving an invalid TaskSourceAndDelayedSortKey around), there + // can't be a DCHECK(task_source_) on moves as IntrusiveHeap moves elements on + // pop instead of overwriting them: resulting in the move of a + // TaskSourceAndDelayedSortKey with a null |task_source_| in + // Transaction::Pop()'s implementation. + TaskSourceAndDelayedSortKey(TaskSourceAndDelayedSortKey&& other) = default; + TaskSourceAndDelayedSortKey& operator=(TaskSourceAndDelayedSortKey&& other) = + default; + + // Extracts |task_source_| from this object. This object is invalid after this + // call. + scoped_refptr<TaskSource> take_task_source() { + DCHECK(task_source_); + task_source_->ClearDelayedHeapHandle(); + return std::move(task_source_); + } + + // Compares this TaskSourceAndDelayedSortKey to |other| based on their + // respective |delayed_sort_key_|. Used for a max-heap. + bool operator<(const TaskSourceAndDelayedSortKey& other) const { + return delayed_sort_key_ < other.delayed_sort_key_; + } + + // Required by IntrusiveHeap. + void SetHeapHandle(const HeapHandle& handle) { + DCHECK(task_source_); + task_source_->SetDelayedHeapHandle(handle); + } + + // Required by IntrusiveHeap. + void ClearHeapHandle() { + // Ensure |task_source_| is not nullptr, which may be the case if + // take_task_source() was called before this. + if (task_source_) + task_source_->ClearDelayedHeapHandle(); + } + + // Required by IntrusiveHeap. + HeapHandle GetHeapHandle() const { + if (task_source_) + return task_source_->GetDelayedHeapHandle(); + return HeapHandle::Invalid(); + } + + scoped_refptr<TaskSource> task_source() const { return task_source_; } + + TimeTicks delayed_sort_key() const { return delayed_sort_key_; } + + private: + scoped_refptr<TaskSource> task_source_; + TimeTicks delayed_sort_key_; +}; + +DelayedPriorityQueue::DelayedPriorityQueue() = default; + +DelayedPriorityQueue::~DelayedPriorityQueue() { + if (!is_flush_task_sources_on_destroy_enabled_) + return; + + while (!container_.empty()) { + auto task_source = PopTaskSource(); + task_source->ClearForTesting(); // IN-TEST + } +} + +DelayedPriorityQueue& DelayedPriorityQueue::operator=( + DelayedPriorityQueue&& other) = default; + +void DelayedPriorityQueue::Push(scoped_refptr<TaskSource> task_source, + TimeTicks task_source_delayed_sort_key) { + container_.insert(TaskSourceAndDelayedSortKey(std::move(task_source), + task_source_delayed_sort_key)); +} + +const TimeTicks DelayedPriorityQueue::PeekDelayedSortKey() const { + DCHECK(!IsEmpty()); + return container_.top().delayed_sort_key(); +} + +scoped_refptr<TaskSource> DelayedPriorityQueue::PeekTaskSource() const { + DCHECK(!IsEmpty()); + + auto& task_source_and_delayed_sort_key = container_.top(); + return task_source_and_delayed_sort_key.task_source(); +} + +scoped_refptr<TaskSource> DelayedPriorityQueue::PopTaskSource() { + DCHECK(!IsEmpty()); + + auto task_source_and_delayed_sort_key = container_.take_top(); + scoped_refptr<TaskSource> task_source = + task_source_and_delayed_sort_key.take_task_source(); + return task_source; +} + +scoped_refptr<TaskSource> DelayedPriorityQueue::RemoveTaskSource( + scoped_refptr<TaskSource> task_source) { + if (IsEmpty()) + return nullptr; + + const HeapHandle heap_handle = task_source->delayed_heap_handle(); + if (!heap_handle.IsValid()) + return nullptr; + + TaskSourceAndDelayedSortKey& task_source_and_delayed_sort_key = + const_cast<DelayedPriorityQueue::TaskSourceAndDelayedSortKey&>( + container_.at(heap_handle)); + DCHECK_EQ(task_source_and_delayed_sort_key.task_source(), task_source); + task_source = task_source_and_delayed_sort_key.take_task_source(); + + container_.erase(heap_handle); + return task_source; +} + +void DelayedPriorityQueue::UpdateDelayedSortKey( + scoped_refptr<TaskSource> task_source) { + if (IsEmpty()) + return; + + const HeapHandle heap_handle = task_source->delayed_heap_handle(); + if (!heap_handle.IsValid()) + return; + + DCHECK_EQ(container_.at(heap_handle).task_source(), task_source); + + task_source = const_cast<DelayedPriorityQueue::TaskSourceAndDelayedSortKey&>( + container_.at(heap_handle)) + .take_task_source(); + auto delayed_sort_key = task_source->GetDelayedSortKey(); + container_.Replace( + heap_handle, + TaskSourceAndDelayedSortKey(std::move(task_source), delayed_sort_key)); +} + +bool DelayedPriorityQueue::IsEmpty() const { + return container_.empty(); +} + +size_t DelayedPriorityQueue::Size() const { + return container_.size(); +} + +void DelayedPriorityQueue::EnableFlushTaskSourcesOnDestroyForTesting() { + DCHECK(!is_flush_task_sources_on_destroy_enabled_); + is_flush_task_sources_on_destroy_enabled_ = true; +} + +// Delayed tasks are ordered by latest_delayed_run_time(). The top task may +// not be the first task eligible to run, but tasks will always become ripe +// before their latest_delayed_run_time(). +bool DelayedPriorityQueue::DelayedPriorityQueueComparisonOperator::operator()( + const TaskSourceAndDelayedSortKey& lhs, + const TaskSourceAndDelayedSortKey& rhs) const { + return lhs.delayed_sort_key() > rhs.delayed_sort_key(); +} + +} // namespace base::internal diff --git a/chromium/base/task/thread_pool/delayed_priority_queue.h b/chromium/base/task/thread_pool/delayed_priority_queue.h new file mode 100644 index 00000000000..b7735564244 --- /dev/null +++ b/chromium/base/task/thread_pool/delayed_priority_queue.h @@ -0,0 +1,88 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_TASK_THREAD_POOL_DELAYED_PRIORITY_QUEUE_H_ +#define BASE_TASK_THREAD_POOL_DELAYED_PRIORITY_QUEUE_H_ + +#include "base/base_export.h" +#include "base/containers/intrusive_heap.h" +#include "base/stl_util.h" +#include "base/task/thread_pool/task_source.h" +#include "base/time/time.h" + +namespace base::internal { + +// A DelayedPriorityQueue holds TaskSources not ready to run yet. TaskSources +// are ordered by delayed runtime. This class is not thread-safe (requires +// external synchronization). +class BASE_EXPORT DelayedPriorityQueue { + public: + DelayedPriorityQueue(); + DelayedPriorityQueue(const DelayedPriorityQueue&) = delete; + DelayedPriorityQueue& operator=(const DelayedPriorityQueue&) = delete; + ~DelayedPriorityQueue(); + + DelayedPriorityQueue& operator=(DelayedPriorityQueue&& other); + + // Inserts |task_source| in the DelayedPriorityQueue with |delayed_sort_key|. + void Push(scoped_refptr<TaskSource> task_source, TimeTicks delayed_sort_key); + + // Returns a delayed sort key representing the priority of the highest pending + // task in this DelayedPriorityQueue. Cannot be called on an empty + // DelayedPriorityQueue. + const TimeTicks PeekDelayedSortKey() const; + + // Returns a pointer to the earliest-to-run TaskSource in this + // DelayedPriorityQueue. Cannot be called on an empty DelayedPriorityQueue. + scoped_refptr<TaskSource> PeekTaskSource() const; + + // Removes and returns the highest priority TaskSource in this + // DelayedPriorityQueue. Cannot be called on an empty DelayedPriorityQueue. + scoped_refptr<TaskSource> PopTaskSource(); + + // Removes |task_source| from the DelayedPriorityQueue. Returns a TaskSource + // which evaluates to true if successful, or false if |task_source| is not + // currently in the DelayedPriorityQueue or the DelayedPriorityQueue is empty. + scoped_refptr<TaskSource> RemoveTaskSource( + scoped_refptr<TaskSource> task_source); + + // Updates the delayed sort key of |task_source| to |delayed_sort_key|, + // reordering |task_source| in the queue if necessary. No-ops if the + // TaskSource is not in the DelayedPriorityQueue or the DelayedPriorityQueue + // is empty. + void UpdateDelayedSortKey(scoped_refptr<TaskSource> task_source); + + // Returns true if the DelayedPriorityQueue is empty. + bool IsEmpty() const; + + // Returns the number of TaskSources in the DelayedPriorityQueue. + size_t Size() const; + + // Set the DelayedPriorityQueue to empty all its TaskSources of Tasks when it + // is destroyed; needed to prevent memory leaks caused by a reference cycle + // (TaskSource -> Task -> TaskRunner -> TaskSource...) during test teardown. + void EnableFlushTaskSourcesOnDestroyForTesting(); + + private: + // A class combining a TaskSource and the delayed_sort_key that determines + // its position in a PriorityQueue. + class TaskSourceAndDelayedSortKey; + + struct DelayedPriorityQueueComparisonOperator { + bool operator()(const TaskSourceAndDelayedSortKey& lhs, + const TaskSourceAndDelayedSortKey& rhs) const; + }; + + using ContainerType = IntrusiveHeap<TaskSourceAndDelayedSortKey, + DelayedPriorityQueueComparisonOperator>; + + ContainerType container_; + + // Should only be enabled by EnableFlushTaskSourcesOnDestroyForTesting(). + bool is_flush_task_sources_on_destroy_enabled_ = false; +}; + +} // namespace base::internal + +#endif // BASE_TASK_THREAD_POOL_DELAYED_PRIORITY_QUEUE_H_ diff --git a/chromium/base/task/thread_pool/delayed_priority_queue_unittest.cc b/chromium/base/task/thread_pool/delayed_priority_queue_unittest.cc new file mode 100644 index 00000000000..1543479bff9 --- /dev/null +++ b/chromium/base/task/thread_pool/delayed_priority_queue_unittest.cc @@ -0,0 +1,201 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/task/thread_pool/delayed_priority_queue.h" + +#include <memory> +#include <utility> + +#include "base/callback_helpers.h" +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" +#include "base/task/task_traits.h" +#include "base/task/thread_pool/sequence.h" +#include "base/task/thread_pool/task.h" +#include "base/test/gtest_util.h" +#include "base/test/task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base::internal { + +namespace { + +class DelayedPriorityQueueWithSequencesTest : public testing::Test { + protected: + scoped_refptr<Sequence> MakeSequenceWithDelayedTask( + TimeDelta delayed_run_time) { + // FastForward time to ensure that queue order between task sources is well + // defined. + task_environment.FastForwardBy(Microseconds(1)); + scoped_refptr<Sequence> sequence = MakeRefCounted<Sequence>( + TaskTraits(), nullptr, TaskSourceExecutionMode::kParallel); + sequence->BeginTransaction().PushDelayedTask( + Task(FROM_HERE, DoNothing(), TimeTicks::Now(), delayed_run_time)); + return sequence; + } + + void Push(scoped_refptr<Sequence> task_source) { + auto delayed_sort_key = task_source->GetDelayedSortKey(); + pq.Push(std::move(task_source), delayed_sort_key); + } + + test::TaskEnvironment task_environment{ + test::TaskEnvironment::TimeSource::MOCK_TIME}; + + scoped_refptr<Sequence> sequence_a = + MakeSequenceWithDelayedTask(Milliseconds(90)); + TimeTicks sort_key_a = sequence_a->GetDelayedSortKey(); + + scoped_refptr<Sequence> sequence_b = + MakeSequenceWithDelayedTask(Milliseconds(70)); + TimeTicks sort_key_b = sequence_b->GetDelayedSortKey(); + + scoped_refptr<Sequence> sequence_c = + MakeSequenceWithDelayedTask(Milliseconds(80)); + TimeTicks sort_key_c = sequence_c->GetDelayedSortKey(); + + scoped_refptr<Sequence> sequence_d = + MakeSequenceWithDelayedTask(Milliseconds(100)); + TimeTicks sort_key_d = sequence_d->GetDelayedSortKey(); + + DelayedPriorityQueue pq; +}; + +} // namespace + +TEST_F(DelayedPriorityQueueWithSequencesTest, PushPopPeek) { + EXPECT_TRUE(pq.IsEmpty()); + + // Push |sequence_a| in the DelayedPriorityQueue. It becomes the sequence with + // the earliest delayed runtime. + Push(sequence_a); + EXPECT_EQ(sort_key_a, pq.PeekDelayedSortKey()); + + // Push |sequence_b| in the DelayedPriorityQueue. It becomes the sequence with + // the earliest delayed runtime. + Push(sequence_b); + EXPECT_EQ(sort_key_b, pq.PeekDelayedSortKey()); + + // Push |sequence_c| in the DelayedPriorityQueue. |sequence_b| is still the + // sequence with the earliest delayed runtime. + Push(sequence_c); + EXPECT_EQ(sort_key_b, pq.PeekDelayedSortKey()); + + // Push |sequence_d| in the DelayedPriorityQueue. |sequence_b| is still the + // sequence with the earliest delayed runtime. + Push(sequence_d); + EXPECT_EQ(sort_key_b, pq.PeekDelayedSortKey()); + + // Pop |sequence_b| from the DelayedPriorityQueue. |sequence_c| becomes the + // sequence with the earliest delayed runtime. + EXPECT_EQ(sequence_b, pq.PopTaskSource()); + EXPECT_EQ(sort_key_c, pq.PeekDelayedSortKey()); + + // Pop |sequence_c| from the DelayedPriorityQueue. |sequence_a| becomes the + // sequence with the earliest delayed runtime. + EXPECT_EQ(sequence_c, pq.PopTaskSource()); + EXPECT_EQ(sort_key_a, pq.PeekDelayedSortKey()); + + // Pop |sequence_a| from the DelayedPriorityQueue. |sequence_d| becomes the + // sequence with the earliest delayed runtime. + EXPECT_EQ(sequence_a, pq.PopTaskSource()); + EXPECT_EQ(sort_key_d, pq.PeekDelayedSortKey()); + + // Pop |sequence_d| from the DelayedPriorityQueue. It is now empty. + EXPECT_EQ(sequence_d, pq.PopTaskSource()); + EXPECT_TRUE(pq.IsEmpty()); +} + +TEST_F(DelayedPriorityQueueWithSequencesTest, RemoveSequence) { + EXPECT_TRUE(pq.IsEmpty()); + + // Push all test Sequences into the PriorityQueue. |sequence_b| + // will be the sequence with the highest priority. + Push(sequence_a); + Push(sequence_b); + Push(sequence_c); + Push(sequence_d); + EXPECT_EQ(sort_key_b, pq.PeekDelayedSortKey()); + + // Remove |sequence_a| from the PriorityQueue. |sequence_b| is still the + // sequence with the highest priority. + EXPECT_TRUE(pq.RemoveTaskSource(sequence_a)); + EXPECT_EQ(sort_key_b, pq.PeekDelayedSortKey()); + + // RemoveTaskSource() should return false if called on a sequence not in the + // PriorityQueue. + EXPECT_FALSE(pq.RemoveTaskSource(sequence_a)); + + // Remove |sequence_b| from the PriorityQueue. |sequence_c| becomes the + // sequence with the highest priority. + EXPECT_TRUE(pq.RemoveTaskSource(sequence_b)); + EXPECT_EQ(sort_key_c, pq.PeekDelayedSortKey()); + + // Remove |sequence_d| from the PriorityQueue. |sequence_c| is still the + // sequence with the highest priority. + EXPECT_TRUE(pq.RemoveTaskSource(sequence_d)); + EXPECT_EQ(sort_key_c, pq.PeekDelayedSortKey()); + + // Remove |sequence_c| from the PriorityQueue, making it empty. + EXPECT_TRUE(pq.RemoveTaskSource(sequence_c)); + EXPECT_TRUE(pq.IsEmpty()); + + // Return false if RemoveTaskSource() is called on an empty PriorityQueue. + EXPECT_FALSE(pq.RemoveTaskSource(sequence_c)); +} + +// Test that when the top of a task source changes, the delayed queue is +// appropriately rearranged +TEST_F(DelayedPriorityQueueWithSequencesTest, UpdateDelayedSortKey) { + EXPECT_TRUE(pq.IsEmpty()); + + // Push all test Sequences into the PriorityQueue. |sequence_b| becomes the + // sequence with the highest priority. + Push(sequence_a); + Push(sequence_b); + Push(sequence_c); + Push(sequence_d); + EXPECT_EQ(sort_key_b, pq.PeekDelayedSortKey()); + + { + // Push a new delayed task earlier than pq's top into sequence_c. + // |sequence_c| becomes the sequence on top of the delayed priority queue. + sequence_c->BeginTransaction().PushDelayedTask( + Task(FROM_HERE, DoNothing(), TimeTicks::Now(), Milliseconds(60))); + + sort_key_c = sequence_c->GetDelayedSortKey(); + pq.UpdateDelayedSortKey(sequence_c); + EXPECT_EQ(sort_key_c, pq.PeekDelayedSortKey()); + } + + { + // Push a new delayed task earlier than pq's top into sequence_d. + // |sequence_d| becomes the sequence on top of the delayed priority queue. + sequence_d->BeginTransaction().PushDelayedTask( + Task(FROM_HERE, DoNothing(), TimeTicks::Now(), Milliseconds(50))); + + sort_key_d = sequence_d->GetDelayedSortKey(); + pq.UpdateDelayedSortKey(sequence_d); + EXPECT_EQ(sort_key_d, pq.PeekDelayedSortKey()); + + // Pop top task source and verify that it is |sequence_d| + EXPECT_EQ(sequence_d, pq.PopTaskSource()); + // New top should be |sequence_c| + EXPECT_EQ(sort_key_c, pq.PeekDelayedSortKey()); + } + + { + EXPECT_EQ(sequence_c, pq.PopTaskSource()); + EXPECT_EQ(sequence_b, pq.PopTaskSource()); + EXPECT_EQ(sequence_a, pq.PopTaskSource()); + } + + { + // No-op if UpdateSortKey() is called on an empty PriorityQueue. + pq.UpdateDelayedSortKey(sequence_b); + EXPECT_TRUE(pq.IsEmpty()); + } +} + +} // namespace base::internal diff --git a/chromium/base/task/thread_pool/delayed_task_manager.cc b/chromium/base/task/thread_pool/delayed_task_manager.cc index e0a1bcb69e5..856444491e2 100644 --- a/chromium/base/task/thread_pool/delayed_task_manager.cc +++ b/chromium/base/task/thread_pool/delayed_task_manager.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/delayed_task_manager.h b/chromium/base/task/thread_pool/delayed_task_manager.h index 38eeb673a05..41961433cc7 100644 --- a/chromium/base/task/thread_pool/delayed_task_manager.h +++ b/chromium/base/task/thread_pool/delayed_task_manager.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/delayed_task_manager_unittest.cc b/chromium/base/task/thread_pool/delayed_task_manager_unittest.cc index 1e199e7942d..f0d2dd50c11 100644 --- a/chromium/base/task/thread_pool/delayed_task_manager_unittest.cc +++ b/chromium/base/task/thread_pool/delayed_task_manager_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/environment_config.cc b/chromium/base/task/thread_pool/environment_config.cc index afbefc14c02..4de0c855264 100644 --- a/chromium/base/task/thread_pool/environment_config.cc +++ b/chromium/base/task/thread_pool/environment_config.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/environment_config.h b/chromium/base/task/thread_pool/environment_config.h index e89ef4fd728..9288d5bc85c 100644 --- a/chromium/base/task/thread_pool/environment_config.h +++ b/chromium/base/task/thread_pool/environment_config.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/environment_config_unittest.cc b/chromium/base/task/thread_pool/environment_config_unittest.cc index cf80ca3ae1e..5b438958ce2 100644 --- a/chromium/base/task/thread_pool/environment_config_unittest.cc +++ b/chromium/base/task/thread_pool/environment_config_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/initialization_util.cc b/chromium/base/task/thread_pool/initialization_util.cc index a2fa8e92d25..9a8658aa28d 100644 --- a/chromium/base/task/thread_pool/initialization_util.cc +++ b/chromium/base/task/thread_pool/initialization_util.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/initialization_util.h b/chromium/base/task/thread_pool/initialization_util.h index bf26e4cfb88..5a64ea9e3cc 100644 --- a/chromium/base/task/thread_pool/initialization_util.h +++ b/chromium/base/task/thread_pool/initialization_util.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/job_task_source.cc b/chromium/base/task/thread_pool/job_task_source.cc index ccb62253e42..4376b026378 100644 --- a/chromium/base/task/thread_pool/job_task_source.cc +++ b/chromium/base/task/thread_pool/job_task_source.cc @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -367,11 +367,7 @@ bool JobTaskSource::WillReEnqueue(TimeTicks now, // This is a no-op. void JobTaskSource::OnBecomeReady() {} -TaskSourceSortKey JobTaskSource::GetSortKey( - bool disable_fair_scheduling) const { - if (disable_fair_scheduling) { - return TaskSourceSortKey(priority_racy(), ready_time_); - } +TaskSourceSortKey JobTaskSource::GetSortKey() const { return TaskSourceSortKey(priority_racy(), ready_time_, TS_UNCHECKED_READ(state_).Load().worker_count()); } diff --git a/chromium/base/task/thread_pool/job_task_source.h b/chromium/base/task/thread_pool/job_task_source.h index 69caa4d6eef..a7e744eae54 100644 --- a/chromium/base/task/thread_pool/job_task_source.h +++ b/chromium/base/task/thread_pool/job_task_source.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -71,8 +71,7 @@ class BASE_EXPORT JobTaskSource : public TaskSource { // TaskSource: ExecutionEnvironment GetExecutionEnvironment() override; size_t GetRemainingConcurrency() const override; - TaskSourceSortKey GetSortKey( - bool disable_fair_scheduling = false) const override; + TaskSourceSortKey GetSortKey() const override; TimeTicks GetDelayedSortKey() const override; bool IsActive() const; diff --git a/chromium/base/task/thread_pool/job_task_source_unittest.cc b/chromium/base/task/thread_pool/job_task_source_unittest.cc index 86535605aaf..4ff3f69ada5 100644 --- a/chromium/base/task/thread_pool/job_task_source_unittest.cc +++ b/chromium/base/task/thread_pool/job_task_source_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/pooled_parallel_task_runner.cc b/chromium/base/task/thread_pool/pooled_parallel_task_runner.cc index 4560077c208..23c1856844f 100644 --- a/chromium/base/task/thread_pool/pooled_parallel_task_runner.cc +++ b/chromium/base/task/thread_pool/pooled_parallel_task_runner.cc @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/pooled_parallel_task_runner.h b/chromium/base/task/thread_pool/pooled_parallel_task_runner.h index c03397cf5e3..d2a37457ce5 100644 --- a/chromium/base/task/thread_pool/pooled_parallel_task_runner.h +++ b/chromium/base/task/thread_pool/pooled_parallel_task_runner.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/pooled_sequenced_task_runner.cc b/chromium/base/task/thread_pool/pooled_sequenced_task_runner.cc index 2a4c1b411f7..3b7ceb6c788 100644 --- a/chromium/base/task/thread_pool/pooled_sequenced_task_runner.cc +++ b/chromium/base/task/thread_pool/pooled_sequenced_task_runner.cc @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 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 72975e8fe90..5d5a3fe52c6 100644 --- a/chromium/base/task/thread_pool/pooled_sequenced_task_runner.h +++ b/chromium/base/task/thread_pool/pooled_sequenced_task_runner.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc b/chromium/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc index ed562938fa3..0963b3aa0a3 100644 --- a/chromium/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc +++ b/chromium/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -216,8 +216,7 @@ class WorkerThreadDelegate : public WorkerThread::Delegate { bool EnqueueTaskSource( TransactionWithRegisteredTaskSource transaction_with_task_source) { CheckedAutoLock auto_lock(lock_); - auto sort_key = transaction_with_task_source.task_source->GetSortKey( - /* disable_fair_scheduling */ false); + auto sort_key = transaction_with_task_source.task_source->GetSortKey(); priority_queue_.Push(std::move(transaction_with_task_source.task_source), sort_key); if (!worker_awake_ && CanRunNextTaskSource()) { @@ -535,10 +534,10 @@ void PooledSingleThreadTaskRunnerManager::Start( WorkerThreadObserver* worker_thread_observer) { DCHECK(!worker_thread_observer_); worker_thread_observer_ = worker_thread_observer; -#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL) +#if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA) DCHECK(io_thread_task_runner); io_thread_task_runner_ = std::move(io_thread_task_runner); -#endif +#endif // (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA) decltype(workers_) workers_to_start; { diff --git a/chromium/base/task/thread_pool/pooled_single_thread_task_runner_manager.h b/chromium/base/task/thread_pool/pooled_single_thread_task_runner_manager.h index 2d87e44ea91..c4ddb4304ed 100644 --- a/chromium/base/task/thread_pool/pooled_single_thread_task_runner_manager.h +++ b/chromium/base/task/thread_pool/pooled_single_thread_task_runner_manager.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/pooled_single_thread_task_runner_manager_unittest.cc b/chromium/base/task/thread_pool/pooled_single_thread_task_runner_manager_unittest.cc index 71926ccffc6..95b36d51e23 100644 --- a/chromium/base/task/thread_pool/pooled_single_thread_task_runner_manager_unittest.cc +++ b/chromium/base/task/thread_pool/pooled_single_thread_task_runner_manager_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/pooled_task_runner_delegate.cc b/chromium/base/task/thread_pool/pooled_task_runner_delegate.cc index 35dfe7c254e..e0b85b3dc7c 100644 --- a/chromium/base/task/thread_pool/pooled_task_runner_delegate.cc +++ b/chromium/base/task/thread_pool/pooled_task_runner_delegate.cc @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/pooled_task_runner_delegate.h b/chromium/base/task/thread_pool/pooled_task_runner_delegate.h index 4ba0dd736ee..6a503a3d010 100644 --- a/chromium/base/task/thread_pool/pooled_task_runner_delegate.h +++ b/chromium/base/task/thread_pool/pooled_task_runner_delegate.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/priority_queue.cc b/chromium/base/task/thread_pool/priority_queue.cc index 729f836c45e..8e53ed40445 100644 --- a/chromium/base/task/thread_pool/priority_queue.cc +++ b/chromium/base/task/thread_pool/priority_queue.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -41,7 +41,7 @@ class PriorityQueue::TaskSourceAndSortKey { // call. RegisteredTaskSource take_task_source() { DCHECK(task_source_); - task_source_->ClearHeapHandle(); + task_source_->ClearImmediateHeapHandle(); return std::move(task_source_); } @@ -54,7 +54,7 @@ class PriorityQueue::TaskSourceAndSortKey { // Required by IntrusiveHeap. void SetHeapHandle(const HeapHandle& handle) { DCHECK(task_source_); - task_source_->SetHeapHandle(handle); + task_source_->SetImmediateHeapHandle(handle); } // Required by IntrusiveHeap. @@ -62,13 +62,13 @@ class PriorityQueue::TaskSourceAndSortKey { // Ensure |task_source_| is not nullptr, which may be the case if // take_task_source() was called before this. if (task_source_) - task_source_->ClearHeapHandle(); + task_source_->ClearImmediateHeapHandle(); } // Required by IntrusiveHeap. HeapHandle GetHeapHandle() const { if (task_source_) - return task_source_->GetHeapHandle(); + return task_source_->GetImmediateHeapHandle(); return HeapHandle::Invalid(); } @@ -140,7 +140,7 @@ RegisteredTaskSource PriorityQueue::RemoveTaskSource( if (IsEmpty()) return nullptr; - const HeapHandle heap_handle = task_source.heap_handle(); + const HeapHandle heap_handle = task_source.immediate_heap_handle(); if (!heap_handle.IsValid()) return nullptr; @@ -162,7 +162,7 @@ void PriorityQueue::UpdateSortKey(const TaskSource& task_source, if (IsEmpty()) return; - const HeapHandle heap_handle = task_source.heap_handle(); + const HeapHandle heap_handle = task_source.immediate_heap_handle(); if (!heap_handle.IsValid()) return; diff --git a/chromium/base/task/thread_pool/priority_queue.h b/chromium/base/task/thread_pool/priority_queue.h index ceef6c72526..f6a39c71001 100644 --- a/chromium/base/task/thread_pool/priority_queue.h +++ b/chromium/base/task/thread_pool/priority_queue.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/priority_queue_unittest.cc b/chromium/base/task/thread_pool/priority_queue_unittest.cc index a976d37037f..aef842cd46e 100644 --- a/chromium/base/task/thread_pool/priority_queue_unittest.cc +++ b/chromium/base/task/thread_pool/priority_queue_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -49,7 +49,7 @@ class PriorityQueueWithSequencesTest : public testing::Test { } void Push(scoped_refptr<TaskSource> task_source) { - auto sort_key = task_source->GetSortKey(false); + auto sort_key = task_source->GetSortKey(); pq.Push(RegisteredTaskSource::CreateForTesting(std::move(task_source)), sort_key); } @@ -59,19 +59,19 @@ class PriorityQueueWithSequencesTest : public testing::Test { scoped_refptr<TaskSource> sequence_a = MakeSequenceWithTraitsAndTask(TaskTraits(TaskPriority::USER_VISIBLE)); - TaskSourceSortKey sort_key_a = sequence_a->GetSortKey(false); + TaskSourceSortKey sort_key_a = sequence_a->GetSortKey(); scoped_refptr<TaskSource> sequence_b = MakeSequenceWithTraitsAndTask(TaskTraits(TaskPriority::USER_BLOCKING)); - TaskSourceSortKey sort_key_b = sequence_b->GetSortKey(false); + TaskSourceSortKey sort_key_b = sequence_b->GetSortKey(); scoped_refptr<TaskSource> sequence_c = MakeSequenceWithTraitsAndTask(TaskTraits(TaskPriority::USER_BLOCKING)); - TaskSourceSortKey sort_key_c = sequence_c->GetSortKey(false); + TaskSourceSortKey sort_key_c = sequence_c->GetSortKey(); scoped_refptr<TaskSource> sequence_d = MakeSequenceWithTraitsAndTask(TaskTraits(TaskPriority::BEST_EFFORT)); - TaskSourceSortKey sort_key_d = sequence_d->GetSortKey(false); + TaskSourceSortKey sort_key_d = sequence_d->GetSortKey(); PriorityQueue pq; }; @@ -193,7 +193,7 @@ TEST_F(PriorityQueueWithSequencesTest, UpdateSortKey) { auto sequence_b_transaction = sequence_b->BeginTransaction(); sequence_b_transaction.UpdatePriority(TaskPriority::BEST_EFFORT); - pq.UpdateSortKey(*sequence_b, sequence_b->GetSortKey(false)); + pq.UpdateSortKey(*sequence_b, sequence_b->GetSortKey()); EXPECT_EQ(sort_key_c, pq.PeekSortKey()); ExpectNumSequences(2U, 1U, 1U); } @@ -205,7 +205,7 @@ TEST_F(PriorityQueueWithSequencesTest, UpdateSortKey) { auto sequence_c_transaction = sequence_c->BeginTransaction(); sequence_c_transaction.UpdatePriority(TaskPriority::USER_BLOCKING); - pq.UpdateSortKey(*sequence_c, sequence_c->GetSortKey(false)); + pq.UpdateSortKey(*sequence_c, sequence_c->GetSortKey()); ExpectNumSequences(2U, 1U, 1U); // Note: |sequence_c| is popped for comparison as |sort_key_c| becomes @@ -222,7 +222,7 @@ TEST_F(PriorityQueueWithSequencesTest, UpdateSortKey) { auto sequence_d_and_transaction = sequence_d->BeginTransaction(); sequence_d_and_transaction.UpdatePriority(TaskPriority::USER_BLOCKING); - pq.UpdateSortKey(*sequence_d, sequence_d->GetSortKey(false)); + pq.UpdateSortKey(*sequence_d, sequence_d->GetSortKey()); ExpectNumSequences(1U, 1U, 1U); // Note: |sequence_d| is popped for comparison as |sort_key_d| becomes @@ -235,7 +235,7 @@ TEST_F(PriorityQueueWithSequencesTest, UpdateSortKey) { } { - pq.UpdateSortKey(*sequence_d, sequence_d->GetSortKey(false)); + pq.UpdateSortKey(*sequence_d, sequence_d->GetSortKey()); ExpectNumSequences(1U, 1U, 0U); EXPECT_EQ(sequence_a, pq.PopTaskSource().Unregister()); ExpectNumSequences(1U, 0U, 0U); @@ -245,7 +245,7 @@ TEST_F(PriorityQueueWithSequencesTest, UpdateSortKey) { { // No-op if UpdateSortKey() is called on an empty PriorityQueue. - pq.UpdateSortKey(*sequence_b, sequence_b->GetSortKey(false)); + pq.UpdateSortKey(*sequence_b, sequence_b->GetSortKey()); EXPECT_TRUE(pq.IsEmpty()); ExpectNumSequences(0U, 0U, 0U); } diff --git a/chromium/base/task/thread_pool/sequence.cc b/chromium/base/task/thread_pool/sequence.cc index b875f537ce8..0730f702907 100644 --- a/chromium/base/task/thread_pool/sequence.cc +++ b/chromium/base/task/thread_pool/sequence.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -287,8 +287,7 @@ bool Sequence::HasImmediateTasks() const { return !queue_.empty(); } -TaskSourceSortKey Sequence::GetSortKey( - bool /* disable_fair_scheduling */) const { +TaskSourceSortKey Sequence::GetSortKey() const { return TaskSourceSortKey(priority_racy(), ready_time_.load(std::memory_order_relaxed)); } diff --git a/chromium/base/task/thread_pool/sequence.h b/chromium/base/task/thread_pool/sequence.h index 044e3679de5..7f0f3032649 100644 --- a/chromium/base/task/thread_pool/sequence.h +++ b/chromium/base/task/thread_pool/sequence.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -118,8 +118,7 @@ class BASE_EXPORT Sequence : public TaskSource { // TaskSource: ExecutionEnvironment GetExecutionEnvironment() override; size_t GetRemainingConcurrency() const override; - TaskSourceSortKey GetSortKey( - bool disable_fair_scheduling = false) const override; + TaskSourceSortKey GetSortKey() const override; TimeTicks GetDelayedSortKey() const override; // Returns a token that uniquely identifies this Sequence. diff --git a/chromium/base/task/thread_pool/sequence_unittest.cc b/chromium/base/task/thread_pool/sequence_unittest.cc index b8921e81715..6f352cb46b4 100644 --- a/chromium/base/task/thread_pool/sequence_unittest.cc +++ b/chromium/base/task/thread_pool/sequence_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/service_thread.cc b/chromium/base/task/thread_pool/service_thread.cc index 06a42255f05..d20511266c6 100644 --- a/chromium/base/task/thread_pool/service_thread.cc +++ b/chromium/base/task/thread_pool/service_thread.cc @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/service_thread.h b/chromium/base/task/thread_pool/service_thread.h index b264a74f80a..587db2445b3 100644 --- a/chromium/base/task/thread_pool/service_thread.h +++ b/chromium/base/task/thread_pool/service_thread.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/service_thread_unittest.cc b/chromium/base/task/thread_pool/service_thread_unittest.cc index 5a7d18000f1..4e16b0a281d 100644 --- a/chromium/base/task/thread_pool/service_thread_unittest.cc +++ b/chromium/base/task/thread_pool/service_thread_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/task.cc b/chromium/base/task/thread_pool/task.cc index ace7e8d31d2..59fa754c292 100644 --- a/chromium/base/task/thread_pool/task.cc +++ b/chromium/base/task/thread_pool/task.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/task.h b/chromium/base/task/thread_pool/task.h index 0489e27d97b..4e89eea2bf8 100644 --- a/chromium/base/task/thread_pool/task.h +++ b/chromium/base/task/thread_pool/task.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/task_source.cc b/chromium/base/task/thread_pool/task_source.cc index 41dd50a5d1b..2c254305b53 100644 --- a/chromium/base/task/thread_pool/task_source.cc +++ b/chromium/base/task/thread_pool/task_source.cc @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -38,12 +38,20 @@ void TaskSource::Transaction::UpdatePriority(TaskPriority priority) { std::memory_order_relaxed); } -void TaskSource::SetHeapHandle(const HeapHandle& handle) { - heap_handle_ = handle; +void TaskSource::SetImmediateHeapHandle(const HeapHandle& handle) { + immediate_pq_heap_handle_ = handle; } -void TaskSource::ClearHeapHandle() { - heap_handle_ = HeapHandle(); +void TaskSource::ClearImmediateHeapHandle() { + immediate_pq_heap_handle_ = HeapHandle(); +} + +void TaskSource::SetDelayedHeapHandle(const HeapHandle& handle) { + delayed_pq_heap_handle_ = handle; +} + +void TaskSource::ClearDelayedHeapHandle() { + delayed_pq_heap_handle_ = HeapHandle(); } TaskSource::TaskSource(const TaskTraits& traits, @@ -64,6 +72,11 @@ TaskSource::Transaction TaskSource::BeginTransaction() { return Transaction(this); } +void TaskSource::ClearForTesting() { + auto task = Clear(nullptr); + std::move(task.task).Run(); +} + RegisteredTaskSource::RegisteredTaskSource() = default; RegisteredTaskSource::RegisteredTaskSource(std::nullptr_t) diff --git a/chromium/base/task/thread_pool/task_source.h b/chromium/base/task/thread_pool/task_source.h index 7be81577982..4f37db6ce37 100644 --- a/chromium/base/task/thread_pool/task_source.h +++ b/chromium/base/task/thread_pool/task_source.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -148,17 +148,26 @@ class BASE_EXPORT TaskSource : public RefCountedThreadSafe<TaskSource> { virtual size_t GetRemainingConcurrency() const = 0; // Returns a TaskSourceSortKey representing the priority of the TaskSource. - virtual TaskSourceSortKey GetSortKey(bool disable_fair_scheduling) const = 0; + virtual TaskSourceSortKey GetSortKey() const = 0; // Returns a Timeticks object representing the next delayed runtime of the // TaskSource. virtual TimeTicks GetDelayedSortKey() const = 0; - // Support for IntrusiveHeap. - void SetHeapHandle(const HeapHandle& handle); - void ClearHeapHandle(); - HeapHandle GetHeapHandle() const { return heap_handle_; } + // Support for IntrusiveHeap in ThreadGroup::PriorityQueue. + void SetImmediateHeapHandle(const HeapHandle& handle); + void ClearImmediateHeapHandle(); + HeapHandle GetImmediateHeapHandle() const { + return immediate_pq_heap_handle_; + } + + HeapHandle immediate_heap_handle() const { return immediate_pq_heap_handle_; } + + // Support for IntrusiveHeap in ThreadGroup::DelayedPriorityQueue. + void SetDelayedHeapHandle(const HeapHandle& handle); + void ClearDelayedHeapHandle(); + HeapHandle GetDelayedHeapHandle() const { return delayed_pq_heap_handle_; } - HeapHandle heap_handle() const { return heap_handle_; } + HeapHandle delayed_heap_handle() const { return delayed_pq_heap_handle_; } // Returns the shutdown behavior of all Tasks in the TaskSource. Can be // accessed without a Transaction because it is never mutated. @@ -182,6 +191,8 @@ class BASE_EXPORT TaskSource : public RefCountedThreadSafe<TaskSource> { TaskSourceExecutionMode execution_mode() const { return execution_mode_; } + void ClearForTesting(); + protected: virtual ~TaskSource(); @@ -219,7 +230,11 @@ class BASE_EXPORT TaskSource : public RefCountedThreadSafe<TaskSource> { // The TaskSource's position in its current PriorityQueue. Access is protected // by the PriorityQueue's lock. - HeapHandle heap_handle_; + HeapHandle immediate_pq_heap_handle_; + + // The TaskSource's position in its current DelayedPriorityQueue. Access is + // protected by the DelayedPriorityQueue's lock. + HeapHandle delayed_pq_heap_handle_; // A pointer to the TaskRunner that posts to this TaskSource, if any. The // derived class is responsible for calling AddRef() when a TaskSource from diff --git a/chromium/base/task/thread_pool/task_source_sort_key.cc b/chromium/base/task/thread_pool/task_source_sort_key.cc index d34edff38d3..40eb7675ca1 100644 --- a/chromium/base/task/thread_pool/task_source_sort_key.cc +++ b/chromium/base/task/thread_pool/task_source_sort_key.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/task_source_sort_key.h b/chromium/base/task/thread_pool/task_source_sort_key.h index fde56c38b21..2d1337e8baf 100644 --- a/chromium/base/task/thread_pool/task_source_sort_key.h +++ b/chromium/base/task/thread_pool/task_source_sort_key.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/task_source_sort_key_unittest.cc b/chromium/base/task/thread_pool/task_source_sort_key_unittest.cc index cfd8f65fbce..095d47d6f61 100644 --- a/chromium/base/task/thread_pool/task_source_sort_key_unittest.cc +++ b/chromium/base/task/thread_pool/task_source_sort_key_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/task_tracker.cc b/chromium/base/task/thread_pool/task_tracker.cc index 21ad70ebf89..b81bf4633c8 100644 --- a/chromium/base/task/thread_pool/task_tracker.cc +++ b/chromium/base/task/thread_pool/task_tracker.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -323,7 +323,7 @@ bool TaskTracker::WillPostTask(Task* task, } // TODO(scheduler-dev): Record the task traits here. - task_annotator_.WillQueueTask("ThreadPool_PostTask", task, ""); + task_annotator_.WillQueueTask("ThreadPool_PostTask", task); return true; } diff --git a/chromium/base/task/thread_pool/task_tracker.h b/chromium/base/task/thread_pool/task_tracker.h index 43f40db8739..6b53bcca6b7 100644 --- a/chromium/base/task/thread_pool/task_tracker.h +++ b/chromium/base/task/thread_pool/task_tracker.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/task_tracker_unittest.cc b/chromium/base/task/thread_pool/task_tracker_unittest.cc index 9b14bb6e14c..c85a8a0e9eb 100644 --- a/chromium/base/task/thread_pool/task_tracker_unittest.cc +++ b/chromium/base/task/thread_pool/task_tracker_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/test_task_factory.cc b/chromium/base/task/thread_pool/test_task_factory.cc index f8970c3b164..72186140dd8 100644 --- a/chromium/base/task/thread_pool/test_task_factory.cc +++ b/chromium/base/task/thread_pool/test_task_factory.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/test_task_factory.h b/chromium/base/task/thread_pool/test_task_factory.h index 165c9e3ffa6..4a894d9b465 100644 --- a/chromium/base/task/thread_pool/test_task_factory.h +++ b/chromium/base/task/thread_pool/test_task_factory.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/test_utils.cc b/chromium/base/task/thread_pool/test_utils.cc index ea75cec9118..6144f617a6d 100644 --- a/chromium/base/task/thread_pool/test_utils.cc +++ b/chromium/base/task/thread_pool/test_utils.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -206,7 +206,7 @@ void MockPooledTaskRunnerDelegate::PostTaskWithSequenceNow( } bool MockPooledTaskRunnerDelegate::ShouldYield(const TaskSource* task_source) { - return thread_group_->ShouldYield(task_source->GetSortKey(false)); + return thread_group_->ShouldYield(task_source->GetSortKey()); } bool MockPooledTaskRunnerDelegate::EnqueueJobTaskSource( diff --git a/chromium/base/task/thread_pool/test_utils.h b/chromium/base/task/thread_pool/test_utils.h index 343a4d63c42..47c2534cdc4 100644 --- a/chromium/base/task/thread_pool/test_utils.h +++ b/chromium/base/task/thread_pool/test_utils.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/thread_group.cc b/chromium/base/task/thread_pool/thread_group.cc index a16db32fad5..0fcdc194d8b 100644 --- a/chromium/base/task/thread_pool/thread_group.cc +++ b/chromium/base/task/thread_pool/thread_group.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -99,7 +99,6 @@ bool ThreadGroup::IsBoundToCurrentThread() const { void ThreadGroup::Start() { CheckedAutoLock auto_lock(lock_); - disable_fair_scheduling_ = FeatureList::IsEnabled(kDisableFairJobScheduling); } size_t @@ -170,14 +169,14 @@ void ThreadGroup::ReEnqueueTaskSourceLockRequired( // Another worker that was running a task from this task source may have // reenqueued it already, in which case its heap_handle will be valid. It // shouldn't be queued twice so the task source registration is released. - if (transaction_with_task_source.task_source->heap_handle().IsValid()) { + if (transaction_with_task_source.task_source->immediate_heap_handle() + .IsValid()) { workers_executor->ScheduleReleaseTaskSource( std::move(transaction_with_task_source.task_source)); } else { // If the TaskSource should be reenqueued in the current thread group, // reenqueue it inside the scope of the lock. - auto sort_key = transaction_with_task_source.task_source->GetSortKey( - disable_fair_scheduling_); + auto sort_key = transaction_with_task_source.task_source->GetSortKey(); if (push_to_immediate_queue) { priority_queue_.Push( std::move(transaction_with_task_source.task_source), sort_key); @@ -224,19 +223,15 @@ RegisteredTaskSource ThreadGroup::TakeRegisteredTaskSource( return priority_queue_.PopTaskSource(); // Replace the top task_source and then update the queue. std::swap(priority_queue_.PeekTaskSource(), task_source); - if (!disable_fair_scheduling_) { - priority_queue_.UpdateSortKey(*task_source.get(), - task_source->GetSortKey(false)); - } + priority_queue_.UpdateSortKey(*task_source.get(), task_source->GetSortKey()); return task_source; } void ThreadGroup::UpdateSortKeyImpl(BaseScopedCommandsExecutor* executor, TaskSource::Transaction transaction) { CheckedAutoLock auto_lock(lock_); - priority_queue_.UpdateSortKey( - *transaction.task_source(), - transaction.task_source()->GetSortKey(disable_fair_scheduling_)); + priority_queue_.UpdateSortKey(*transaction.task_source(), + transaction.task_source()->GetSortKey()); EnsureEnoughWorkersLockRequired(executor); } @@ -248,15 +243,15 @@ void ThreadGroup::PushTaskSourceAndWakeUpWorkersImpl( DCHECK_EQ(delegate_->GetThreadGroupForTraits( transaction_with_task_source.transaction.traits()), this); - if (transaction_with_task_source.task_source->heap_handle().IsValid()) { + if (transaction_with_task_source.task_source->immediate_heap_handle() + .IsValid()) { // If the task source changed group, it is possible that multiple concurrent // workers try to enqueue it. Only the first enqueue should succeed. executor->ScheduleReleaseTaskSource( std::move(transaction_with_task_source.task_source)); return; } - auto sort_key = transaction_with_task_source.task_source->GetSortKey( - disable_fair_scheduling_); + auto sort_key = transaction_with_task_source.task_source->GetSortKey(); priority_queue_.Push(std::move(transaction_with_task_source.task_source), sort_key); EnsureEnoughWorkersLockRequired(executor); diff --git a/chromium/base/task/thread_pool/thread_group.h b/chromium/base/task/thread_pool/thread_group.h index 9321d182869..505433ca3bd 100644 --- a/chromium/base/task/thread_pool/thread_group.h +++ b/chromium/base/task/thread_pool/thread_group.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/thread_group_impl.cc b/chromium/base/task/thread_pool/thread_group_impl.cc index 507f4421e0c..b72cebb9aa8 100644 --- a/chromium/base/task/thread_pool/thread_group_impl.cc +++ b/chromium/base/task/thread_pool/thread_group_impl.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -20,7 +20,6 @@ #include "base/location.h" #include "base/memory/ptr_util.h" #include "base/memory/raw_ptr.h" -#include "base/metrics/histogram.h" #include "base/numerics/clamped_math.h" #include "base/ranges/algorithm.h" #include "base/sequence_token.h" @@ -51,8 +50,6 @@ namespace internal { namespace { -constexpr char kNumTasksBeforeDetachHistogramPrefix[] = - "ThreadPool.NumTasksBeforeDetach."; constexpr size_t kMaxNumberOfWorkers = 256; // In a background thread group: @@ -126,11 +123,6 @@ class ThreadGroupImpl::ScopedCommandsExecutor must_schedule_adjust_max_tasks_ = true; } - void ScheduleAddHistogramSample(HistogramBase* histogram, - HistogramBase::Sample sample) { - scheduled_histogram_samples_->emplace_back(histogram, sample); - } - private: class WorkerContainer { public: @@ -191,14 +183,6 @@ class ThreadGroupImpl::ScopedCommandsExecutor if (must_schedule_adjust_max_tasks_) outer_->ScheduleAdjustMaxTasks(); - - if (!scheduled_histogram_samples_->empty()) { - DCHECK_LE(scheduled_histogram_samples_->size(), - kHistogramSampleStackSize); - for (auto& scheduled_sample : scheduled_histogram_samples_) - scheduled_sample.first->Add(scheduled_sample.second); - scheduled_histogram_samples_->clear(); - } } const raw_ptr<ThreadGroupImpl> outer_; @@ -206,20 +190,8 @@ class ThreadGroupImpl::ScopedCommandsExecutor WorkerContainer workers_to_wake_up_; WorkerContainer workers_to_start_; bool must_schedule_adjust_max_tasks_ = false; - - // StackVector rather than std::vector avoid heap allocations; size should be - // high enough to store the maximum number of histogram samples added to a - // given ScopedCommandsExecutor instance. - static constexpr size_t kHistogramSampleStackSize = 5; - StackVector<std::pair<HistogramBase*, HistogramBase::Sample>, - kHistogramSampleStackSize> - scheduled_histogram_samples_; }; -// static -constexpr size_t - ThreadGroupImpl::ScopedCommandsExecutor::kHistogramSampleStackSize; - class ThreadGroupImpl::WorkerThreadDelegateImpl : public WorkerThread::Delegate, public BlockingObserver { public: @@ -288,15 +260,12 @@ class ThreadGroupImpl::WorkerThreadDelegateImpl : public WorkerThread::Delegate, EXCLUSIVE_LOCKS_REQUIRED(outer_->lock_); // Called in GetWork() when a worker becomes idle. - void OnWorkerBecomesIdleLockRequired(WorkerThread* worker) + void OnWorkerBecomesIdleLockRequired(ScopedCommandsExecutor* executor, + WorkerThread* worker) EXCLUSIVE_LOCKS_REQUIRED(outer_->lock_); // Accessed only from the worker thread. struct WorkerOnly { - // Number of tasks executed since the last time the - // ThreadPool.NumTasksBeforeDetach histogram was recorded. - size_t num_tasks_since_last_detach = 0; - // Associated WorkerThread, if any, initialized in OnMainEntry(). raw_ptr<WorkerThread> worker_thread_; @@ -368,20 +337,6 @@ ThreadGroupImpl::ThreadGroupImpl(StringPiece histogram_label, thread_group_label_(thread_group_label), thread_type_hint_(thread_type_hint), idle_workers_stack_cv_for_testing_(lock_.CreateConditionVariable()), - // Mimics the UMA_HISTOGRAM_COUNTS_1000 macro. When a worker runs more - // than 1000 tasks before detaching, there is no need to know the exact - // number of tasks that ran. - num_tasks_before_detach_histogram_( - histogram_label.empty() - ? nullptr - : Histogram::FactoryGet( - JoinString( - {kNumTasksBeforeDetachHistogramPrefix, histogram_label}, - ""), - 1, - 1000, - 50, - HistogramBase::kUmaTargetedHistogramFlag)), tracked_ref_factory_(this) { DCHECK(!thread_group_label_.empty()); } @@ -399,10 +354,7 @@ void ThreadGroupImpl::Start( DCHECK(!replacement_thread_group_); - in_start().wakeup_after_getwork = FeatureList::IsEnabled(kWakeUpAfterGetWork); - in_start().wakeup_strategy = kWakeUpStrategyParam.Get(); - in_start().may_block_without_delay = - FeatureList::IsEnabled(kMayBlockWithoutDelay); + in_start().no_worker_reclaim = FeatureList::IsEnabled(kNoWorkerThreadReclaim); in_start().may_block_threshold = may_block_threshold ? may_block_threshold.value() : (thread_type_hint_ == ThreadType::kDefault @@ -612,12 +564,8 @@ RegisteredTaskSource ThreadGroupImpl::WorkerThreadDelegateImpl::GetWork( // Note: FlushWorkerCreation() below releases |outer_->lock_|. It is thus // important that all other operations come after it to keep this method // transactional. - if (!outer_->after_start().wakeup_after_getwork && - outer_->after_start().wakeup_strategy != - WakeUpStrategy::kCentralizedWakeUps) { - outer_->EnsureEnoughWorkersLockRequired(&executor); - executor.FlushWorkerCreation(&outer_->lock_); - } + outer_->EnsureEnoughWorkersLockRequired(&executor); + executor.FlushWorkerCreation(&outer_->lock_); if (!CanGetWorkLockRequired(&executor, worker)) return nullptr; @@ -638,7 +586,7 @@ RegisteredTaskSource ThreadGroupImpl::WorkerThreadDelegateImpl::GetWork( task_source = outer_->TakeRegisteredTaskSource(&executor); } if (!task_source) { - OnWorkerBecomesIdleLockRequired(worker); + OnWorkerBecomesIdleLockRequired(&executor, worker); return nullptr; } @@ -648,12 +596,6 @@ RegisteredTaskSource ThreadGroupImpl::WorkerThreadDelegateImpl::GetWork( write_worker().current_task_priority = priority; write_worker().current_shutdown_behavior = task_source->shutdown_behavior(); - if (outer_->after_start().wakeup_after_getwork && - outer_->after_start().wakeup_strategy != - WakeUpStrategy::kCentralizedWakeUps) { - outer_->EnsureEnoughWorkersLockRequired(&executor); - } - return task_source; } @@ -663,8 +605,6 @@ void ThreadGroupImpl::WorkerThreadDelegateImpl::DidProcessTask( DCHECK(read_worker().current_task_priority); DCHECK(read_worker().current_shutdown_behavior); - ++worker_only().num_tasks_since_last_detach; - // A transaction to the TaskSource to reenqueue, if any. Instantiated here as // |TaskSource::lock_| is a UniversalPredecessor and must always be acquired // prior to acquiring a second lock @@ -711,8 +651,9 @@ void ThreadGroupImpl::WorkerThreadDelegateImpl::DidProcessTask( TimeDelta ThreadGroupImpl::WorkerThreadDelegateImpl::GetSleepTimeout() { DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_); + if (outer_->after_start().no_worker_reclaim) + return TimeDelta::Max(); // Sleep for an extra 10% to avoid the following pathological case: - // 0) A task is running on a timer which matches // |after_start().suggested_reclaim_time|. // 1) The timer fires and this worker is created by @@ -746,6 +687,8 @@ TimeDelta ThreadGroupImpl::WorkerThreadDelegateImpl::GetSleepTimeout() { bool ThreadGroupImpl::WorkerThreadDelegateImpl::CanCleanupLockRequired( const WorkerThread* worker) const { DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_); + if (outer_->after_start().no_worker_reclaim) + return false; const TimeTicks last_used_time = worker->GetLastUsedTime(); return !last_used_time.is_null() && @@ -760,14 +703,10 @@ void ThreadGroupImpl::WorkerThreadDelegateImpl::CleanupLockRequired( DCHECK(!outer_->join_for_testing_started_); DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_); - if (outer_->num_tasks_before_detach_histogram_) { - executor->ScheduleAddHistogramSample( - outer_->num_tasks_before_detach_histogram_, - saturated_cast<HistogramBase::Sample>( - worker_only().num_tasks_since_last_detach)); - } worker->Cleanup(); - outer_->idle_workers_stack_.Remove(worker); + + if (outer_->IsOnIdleStackLockRequired(worker)) + outer_->idle_workers_stack_.Remove(worker); // Remove the worker from |workers_|. auto worker_iter = ranges::find(outer_->workers_, worker); @@ -776,11 +715,23 @@ void ThreadGroupImpl::WorkerThreadDelegateImpl::CleanupLockRequired( } void ThreadGroupImpl::WorkerThreadDelegateImpl::OnWorkerBecomesIdleLockRequired( + ScopedCommandsExecutor* executor, WorkerThread* worker) { DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_); + DCHECK(!outer_->idle_workers_stack_.Contains(worker)); + + if (outer_->after_start().no_worker_reclaim) { + // Under NoWorkerThreadReclaim, immediately cleanup excess workers that were + // going to sleep. Only 1 worker is cleaned up at a time, which is enough + // because each worker who caused |max_tasks_| to increase will eventually + // go through this. + if (outer_->workers_.size() > outer_->max_tasks_) { + CleanupLockRequired(executor, worker); + return; + } + } // Add the worker to the idle stack. - DCHECK(!outer_->idle_workers_stack_.Contains(worker)); outer_->idle_workers_stack_.Push(worker); DCHECK_LE(outer_->idle_workers_stack_.Size(), outer_->workers_.size()); outer_->idle_workers_stack_cv_for_testing_->Broadcast(); @@ -832,10 +783,8 @@ void ThreadGroupImpl::WorkerThreadDelegateImpl::BlockingStarted( worker_only().worker_thread_->MaybeUpdateThreadType(); - // MayBlock with no delay reuses WillBlock implementation. // WillBlock is always used when time overrides is active. crbug.com/1038867 - if (outer_->after_start().may_block_without_delay || - base::subtle::ScopedTimeClockOverrides::overrides_active()) { + if (base::subtle::ScopedTimeClockOverrides::overrides_active()) { blocking_type = BlockingType::WILL_BLOCK; } @@ -870,10 +819,8 @@ void ThreadGroupImpl::WorkerThreadDelegateImpl::BlockingTypeUpgraded() { // The blocking type always being WILL_BLOCK in this experiment and with time // overrides, it should never be considered "upgraded". - if (outer_->after_start().may_block_without_delay || - base::subtle::ScopedTimeClockOverrides::overrides_active()) { + if (base::subtle::ScopedTimeClockOverrides::overrides_active()) return; - } ScopedCommandsExecutor executor(outer_.get()); CheckedAutoLock auto_lock(outer_->lock_); @@ -934,28 +881,35 @@ void ThreadGroupImpl::WorkerThreadDelegateImpl::OnShutdownStartedLockRequired( bool ThreadGroupImpl::WorkerThreadDelegateImpl::CanGetWorkLockRequired( ScopedCommandsExecutor* executor, WorkerThread* worker) { - // To avoid searching through the idle stack : use GetLastUsedTime() not being - // null (or being directly on top of the idle stack) as a proxy for being on - // the idle stack. const bool is_on_idle_workers_stack = - outer_->idle_workers_stack_.Peek() == worker || - !worker->GetLastUsedTime().is_null(); + outer_->IsOnIdleStackLockRequired(worker); DCHECK_EQ(is_on_idle_workers_stack, outer_->idle_workers_stack_.Contains(worker)); - if (is_on_idle_workers_stack) { - if (CanCleanupLockRequired(worker)) + if (outer_->after_start().no_worker_reclaim) { + DCHECK(!is_on_idle_workers_stack); + // Under NoWorkerThreadReclaim, immediately cleanup excess workers. Only 1 + // worker is cleaned up at a time, which is enough because each worker who + // caused |max_tasks_| to increase will eventually go through this. + if (outer_->GetNumAwakeWorkersLockRequired() > outer_->max_tasks_) { CleanupLockRequired(executor, worker); - return false; - } + return false; + } + } else { + if (is_on_idle_workers_stack) { + if (CanCleanupLockRequired(worker)) + CleanupLockRequired(executor, worker); + return false; + } - // Excess workers should not get work, until they are no longer excess (i.e. - // max tasks increases). This ensures that if we have excess workers in the - // thread group, they get a chance to no longer be excess before being cleaned - // up. - if (outer_->GetNumAwakeWorkersLockRequired() > outer_->max_tasks_) { - OnWorkerBecomesIdleLockRequired(worker); - return false; + // Excess workers should not get work, until they are no longer excess (i.e. + // max tasks increases). This ensures that if we have excess workers in the + // thread group, they get a chance to no longer be excess before being + // cleaned up. + if (outer_->GetNumAwakeWorkersLockRequired() > outer_->max_tasks_) { + OnWorkerBecomesIdleLockRequired(executor, worker); + return false; + } } return true; @@ -1117,12 +1071,7 @@ void ThreadGroupImpl::EnsureEnoughWorkersLockRequired( size_t num_workers_to_wake_up = ClampSub(desired_num_awake_workers, num_awake_workers); - if (after_start().wakeup_strategy == WakeUpStrategy::kExponentialWakeUps) { - num_workers_to_wake_up = std::min(num_workers_to_wake_up, size_t(2U)); - } else if (after_start().wakeup_strategy == - WakeUpStrategy::kSerializedWakeUps) { - num_workers_to_wake_up = std::min(num_workers_to_wake_up, size_t(1U)); - } + num_workers_to_wake_up = std::min(num_workers_to_wake_up, size_t(2U)); // Wake up the appropriate number of workers. for (size_t i = 0; i < num_workers_to_wake_up; ++i) { @@ -1230,6 +1179,14 @@ void ThreadGroupImpl::UpdateMinAllowedPriorityLockRequired() { } } +bool ThreadGroupImpl::IsOnIdleStackLockRequired(WorkerThread* worker) const { + // To avoid searching through the idle stack : use GetLastUsedTime() not being + // null (or being directly on top of the idle stack) as a proxy for being on + // the idle stack. + return idle_workers_stack_.Peek() == worker || + !worker->GetLastUsedTime().is_null(); +} + void ThreadGroupImpl::DecrementTasksRunningLockRequired(TaskPriority priority) { DCHECK_GT(num_running_tasks_, 0U); --num_running_tasks_; diff --git a/chromium/base/task/thread_pool/thread_group_impl.h b/chromium/base/task/thread_pool/thread_group_impl.h index c00a5eb06a4..b905ced66bc 100644 --- a/chromium/base/task/thread_pool/thread_group_impl.h +++ b/chromium/base/task/thread_pool/thread_group_impl.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -33,7 +33,6 @@ namespace base { -class HistogramBase; class WorkerThreadObserver; namespace internal { @@ -101,10 +100,6 @@ class BASE_EXPORT ThreadGroupImpl : public ThreadGroup { void DidUpdateCanRunPolicy() override; void OnShutdownStarted() override; - const HistogramBase* num_tasks_before_detach_histogram() const { - return num_tasks_before_detach_histogram_; - } - // Waits until at least |n| workers are idle. Note that while workers are // disallowed from cleaning up during this call: tests using a custom // |suggested_reclaim_time_| need to be careful to invoke this swiftly after @@ -213,6 +208,9 @@ class BASE_EXPORT ThreadGroupImpl : public ThreadGroup { // or when a new task is added to |priority_queue_|. void UpdateMinAllowedPriorityLockRequired() EXCLUSIVE_LOCKS_REQUIRED(lock_); + bool IsOnIdleStackLockRequired(WorkerThread* worker) const + EXCLUSIVE_LOCKS_REQUIRED(lock_); + // Increments/decrements the number of tasks of |priority| that are currently // running in this thread group. Must be invoked before/after running a task. void DecrementTasksRunningLockRequired(TaskPriority priority) @@ -244,6 +242,7 @@ class BASE_EXPORT ThreadGroupImpl : public ThreadGroup { // Suggested reclaim time for workers. TimeDelta suggested_reclaim_time; + bool no_worker_reclaim = false; // Environment to be initialized per worker. WorkerEnvironment worker_environment = WorkerEnvironment::NONE; @@ -253,10 +252,6 @@ class BASE_EXPORT ThreadGroupImpl : public ThreadGroup { // Optional observer notified when a worker enters and exits its main. raw_ptr<WorkerThreadObserver> worker_thread_observer = nullptr; - WakeUpStrategy wakeup_strategy; - bool wakeup_after_getwork; - bool may_block_without_delay; - // Threshold after which the max tasks is increased to compensate for a // worker that is within a MAY_BLOCK ScopedBlockingCall. TimeDelta may_block_threshold; @@ -345,16 +340,6 @@ class BASE_EXPORT ThreadGroupImpl : public ThreadGroup { // WorkerThreadDelegateImpl::OnMainEntry() completes. absl::optional<WaitableEvent> worker_started_for_testing_; - // Cached HistogramBase pointers, can be accessed without - // holding |lock_|. If |lock_| is held, add new samples using - // ThreadGroupImpl::ScopedCommandsExecutor (increase - // |scheduled_histogram_samples_| size as needed) to defer until after |lock_| - // release, due to metrics system callbacks which may schedule tasks. - - // ThreadPool.NumTasksBeforeDetach.[thread group name] histogram. - // Intentionally leaked. - const raw_ptr<HistogramBase> num_tasks_before_detach_histogram_; - // Ensures recently cleaned up workers (ref. // WorkerThreadDelegateImpl::CleanupLockRequired()) had time to exit as // they have a raw reference to |this| (and to TaskTracker) which can 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 97ac5e8dd55..9ce826c0fde 100644 --- a/chromium/base/task/thread_pool/thread_group_impl_unittest.cc +++ b/chromium/base/task/thread_pool/thread_group_impl_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -21,8 +21,6 @@ #include "base/memory/ptr_util.h" #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" -#include "base/metrics/histogram.h" -#include "base/metrics/histogram_samples.h" #include "base/metrics/statistics_recorder.h" #include "base/synchronization/atomic_flag.h" #include "base/synchronization/condition_variable.h" @@ -40,7 +38,7 @@ #include "base/task/thread_pool/worker_thread_observer.h" #include "base/test/bind.h" #include "base/test/gtest_util.h" -#include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/test/test_simple_task_runner.h" #include "base/test/test_timeouts.h" #include "base/test/test_waitable_event.h" @@ -682,134 +680,6 @@ TEST_F(ThreadGroupImplCheckTlsReuse, CheckCleanupWorkers) { namespace { -class ThreadGroupImplHistogramTest : public ThreadGroupImplImplTest { - public: - ThreadGroupImplHistogramTest() = default; - ThreadGroupImplHistogramTest(const ThreadGroupImplHistogramTest&) = delete; - ThreadGroupImplHistogramTest& operator=(const ThreadGroupImplHistogramTest&) = - delete; - - protected: - // Override SetUp() to allow every test case to initialize a thread group with - // its own arguments. - void SetUp() override {} - - private: - std::unique_ptr<StatisticsRecorder> statistics_recorder_ = - StatisticsRecorder::CreateTemporaryForTesting(); -}; - -} // namespace - -TEST_F(ThreadGroupImplHistogramTest, NumTasksBeforeCleanup) { - CreateThreadGroup(); - auto histogrammed_thread_task_runner = test::CreatePooledSequencedTaskRunner( - {WithBaseSyncPrimitives()}, &mock_pooled_task_runner_delegate_); - - // Post 3 tasks and hold the thread for idle thread stack ordering. - // This test assumes |histogrammed_thread_task_runner| gets assigned the same - // thread for each of its tasks. - PlatformThreadRef thread_ref; - histogrammed_thread_task_runner->PostTask( - FROM_HERE, BindOnce( - [](PlatformThreadRef* thread_ref) { - ASSERT_TRUE(thread_ref); - *thread_ref = PlatformThread::CurrentRef(); - }, - Unretained(&thread_ref))); - histogrammed_thread_task_runner->PostTask( - FROM_HERE, BindOnce( - [](PlatformThreadRef* thread_ref) { - ASSERT_FALSE(thread_ref->is_null()); - EXPECT_EQ(*thread_ref, PlatformThread::CurrentRef()); - }, - Unretained(&thread_ref))); - - TestWaitableEvent cleanup_thread_running; - TestWaitableEvent cleanup_thread_continue; - histogrammed_thread_task_runner->PostTask( - FROM_HERE, - BindOnce( - [](PlatformThreadRef* thread_ref, - TestWaitableEvent* cleanup_thread_running, - TestWaitableEvent* cleanup_thread_continue) { - ASSERT_FALSE(thread_ref->is_null()); - EXPECT_EQ(*thread_ref, PlatformThread::CurrentRef()); - cleanup_thread_running->Signal(); - cleanup_thread_continue->Wait(); - }, - Unretained(&thread_ref), Unretained(&cleanup_thread_running), - Unretained(&cleanup_thread_continue))); - - // Start the thread group with 2 workers, to avoid depending on the internal - // logic to always keep one extra idle worker. - // - // The thread group is started after the 3 initial tasks have been posted to - // ensure that they are scheduled on the same worker. If the tasks could run - // as they are posted, there would be a chance that: - // 1. Worker #1: Runs a tasks and empties the sequence, without adding - // itself to the idle stack yet. - // 2. Posting thread: Posts another task to the now empty sequence. - // Wakes up a new worker, since worker #1 isn't on the - // idle stack yet. - // 3: Worker #2: Runs the tasks, violating the expectation that the 3 - // initial tasks run on the same worker. - constexpr size_t kTwoWorkers = 2; - StartThreadGroup(kReclaimTimeForCleanupTests, kTwoWorkers); - - // Wait until the 3rd task is scheduled. - cleanup_thread_running.Wait(); - - // To allow the WorkerThread associated with - // |histogrammed_thread_task_runner| to cleanup, make sure it isn't on top of - // the idle stack by waking up another WorkerThread via - // |task_runner_for_top_idle|. |histogrammed_thread_task_runner| should - // release and go idle first and then |task_runner_for_top_idle| should - // release and go idle. This allows the WorkerThread associated with - // |histogrammed_thread_task_runner| to cleanup. - TestWaitableEvent top_idle_thread_running; - TestWaitableEvent top_idle_thread_continue; - auto task_runner_for_top_idle = test::CreatePooledSequencedTaskRunner( - {WithBaseSyncPrimitives()}, &mock_pooled_task_runner_delegate_); - task_runner_for_top_idle->PostTask( - FROM_HERE, - BindOnce( - [](PlatformThreadRef thread_ref, - TestWaitableEvent* top_idle_thread_running, - TestWaitableEvent* top_idle_thread_continue) { - ASSERT_FALSE(thread_ref.is_null()); - EXPECT_NE(thread_ref, PlatformThread::CurrentRef()) - << "Worker reused. Worker will not cleanup and the " - "histogram value will be wrong."; - top_idle_thread_running->Signal(); - top_idle_thread_continue->Wait(); - }, - thread_ref, Unretained(&top_idle_thread_running), - Unretained(&top_idle_thread_continue))); - top_idle_thread_running.Wait(); - EXPECT_EQ(0U, thread_group_->NumberOfIdleWorkersForTesting()); - cleanup_thread_continue.Signal(); - // Wait for the cleanup thread to also become idle. - thread_group_->WaitForWorkersIdleForTesting(1U); - top_idle_thread_continue.Signal(); - // Allow the thread processing the |histogrammed_thread_task_runner| work to - // cleanup. - thread_group_->WaitForWorkersCleanedUpForTesting(1U); - - // Verify that counts were recorded to the histogram as expected. - const auto* histogram = thread_group_->num_tasks_before_detach_histogram(); - EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(0)); - EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(1)); - EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(2)); - EXPECT_EQ(1, histogram->SnapshotSamples()->GetCount(3)); - EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(4)); - EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(5)); - EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(6)); - EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); -} - -namespace { - class ThreadGroupImplStandbyPolicyTest : public ThreadGroupImplImplTestBase, public testing::Test { public: @@ -1555,8 +1425,11 @@ TEST_F(ThreadGroupImplBlockingTest, ThreadBusyShutdown) { thread_group_.reset(); } -class ThreadGroupImplOverCapacityTest : public ThreadGroupImplImplTestBase, - public testing::Test { +enum class ReclaimType { DELAYED_RECLAIM, NO_RECLAIM }; + +class ThreadGroupImplOverCapacityTest + : public ThreadGroupImplImplTestBase, + public testing::TestWithParam<ReclaimType> { public: ThreadGroupImplOverCapacityTest() = default; ThreadGroupImplOverCapacityTest(const ThreadGroupImplOverCapacityTest&) = @@ -1565,7 +1438,10 @@ class ThreadGroupImplOverCapacityTest : public ThreadGroupImplImplTestBase, const ThreadGroupImplOverCapacityTest&) = delete; void SetUp() override { - CreateAndStartThreadGroup(kReclaimTimeForCleanupTests, kLocalMaxTasks); + if (GetParam() == ReclaimType::NO_RECLAIM) { + feature_list.InitAndEnableFeature(kNoWorkerThreadReclaim); + } + CreateThreadGroup(); task_runner_ = test::CreatePooledTaskRunner({MayBlock(), WithBaseSyncPrimitives()}, &mock_pooled_task_runner_delegate_); @@ -1574,6 +1450,7 @@ class ThreadGroupImplOverCapacityTest : public ThreadGroupImplImplTestBase, void TearDown() override { ThreadGroupImplImplTestBase::CommonTearDown(); } protected: + base::test::ScopedFeatureList feature_list; scoped_refptr<TaskRunner> task_runner_; static constexpr size_t kLocalMaxTasks = 3; @@ -1585,12 +1462,15 @@ class ThreadGroupImplOverCapacityTest : public ThreadGroupImplImplTestBase, "OverCapacityTestThreadGroup", "A", ThreadType::kDefault, task_tracker_.GetTrackedRef(), tracked_ref_factory_.GetTrackedRef()); ASSERT_TRUE(thread_group_); + + mock_pooled_task_runner_delegate_.SetThreadGroup(thread_group_.get()); } }; // Verify that workers that become idle due to the thread group being over // capacity will eventually cleanup. -TEST_F(ThreadGroupImplOverCapacityTest, VerifyCleanup) { +TEST_P(ThreadGroupImplOverCapacityTest, VerifyCleanup) { + StartThreadGroup(kReclaimTimeForCleanupTests, kLocalMaxTasks); TestWaitableEvent threads_running; TestWaitableEvent threads_continue; RepeatingClosure threads_running_barrier = BarrierClosure( @@ -1651,15 +1531,29 @@ TEST_F(ThreadGroupImplOverCapacityTest, VerifyCleanup) { kReclaimTimeForCleanupTests * i * 0.5); } - // Note: one worker above capacity will not get cleaned up since it's on the - // top of the idle stack. - thread_group_->WaitForWorkersCleanedUpForTesting(kLocalMaxTasks - 1); - EXPECT_EQ(kLocalMaxTasks + 1, thread_group_->NumberOfWorkersForTesting()); + if (GetParam() == ReclaimType::DELAYED_RECLAIM) { + // Note: one worker above capacity will not get cleaned up since it's on the + // top of the idle stack. + thread_group_->WaitForWorkersCleanedUpForTesting(kLocalMaxTasks - 1); + EXPECT_EQ(kLocalMaxTasks + 1, thread_group_->NumberOfWorkersForTesting()); + threads_continue.Signal(); + } else { + // When workers are't automatically reclaimed after a delay, blocking tasks + // need to return for extra workers to be cleaned up. + threads_continue.Signal(); + thread_group_->WaitForWorkersCleanedUpForTesting(kLocalMaxTasks); + EXPECT_EQ(kLocalMaxTasks, thread_group_->NumberOfWorkersForTesting()); + } threads_continue.Signal(); task_tracker_.FlushForTesting(); } +INSTANTIATE_TEST_SUITE_P(ReclaimType, + ThreadGroupImplOverCapacityTest, + ::testing::Values(ReclaimType::DELAYED_RECLAIM, + ReclaimType::NO_RECLAIM)); + // Verify that the maximum number of workers is 256 and that hitting the max // leaves the thread group in a valid state with regards to max tasks. TEST_F(ThreadGroupImplBlockingTest, MaximumWorkersTest) { diff --git a/chromium/base/task/thread_pool/thread_group_native.cc b/chromium/base/task/thread_pool/thread_group_native.cc index c149f1b3be7..24186986648 100644 --- a/chromium/base/task/thread_pool/thread_group_native.cc +++ b/chromium/base/task/thread_pool/thread_group_native.cc @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/thread_group_native.h b/chromium/base/task/thread_pool/thread_group_native.h index 96e71cd480e..b5e7be6befa 100644 --- a/chromium/base/task/thread_pool/thread_group_native.h +++ b/chromium/base/task/thread_pool/thread_group_native.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/thread_group_native_mac.h b/chromium/base/task/thread_pool/thread_group_native_mac.h index bef0db0eb79..94f771df5f7 100644 --- a/chromium/base/task/thread_pool/thread_group_native_mac.h +++ b/chromium/base/task/thread_pool/thread_group_native_mac.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/thread_group_native_mac.mm b/chromium/base/task/thread_pool/thread_group_native_mac.mm index 74982986851..e650f3a003d 100644 --- a/chromium/base/task/thread_pool/thread_group_native_mac.mm +++ b/chromium/base/task/thread_pool/thread_group_native_mac.mm @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/thread_group_native_win.cc b/chromium/base/task/thread_pool/thread_group_native_win.cc index e803dafc92a..f53521b8ae0 100644 --- a/chromium/base/task/thread_pool/thread_group_native_win.cc +++ b/chromium/base/task/thread_pool/thread_group_native_win.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/thread_group_native_win.h b/chromium/base/task/thread_pool/thread_group_native_win.h index 3aeabefa2af..16e8a308df7 100644 --- a/chromium/base/task/thread_pool/thread_group_native_win.h +++ b/chromium/base/task/thread_pool/thread_group_native_win.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/thread_group_unittest.cc b/chromium/base/task/thread_pool/thread_group_unittest.cc index f81822db5eb..d02abef5f5c 100644 --- a/chromium/base/task/thread_pool/thread_group_unittest.cc +++ b/chromium/base/task/thread_pool/thread_group_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/thread_pool_impl.cc b/chromium/base/task/thread_pool/thread_pool_impl.cc index 205ed148aec..036aba36352 100644 --- a/chromium/base/task/thread_pool/thread_pool_impl.cc +++ b/chromium/base/task/thread_pool/thread_pool_impl.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -125,11 +125,6 @@ void ThreadPoolImpl::Start(const ThreadPoolInstance::InitParams& init_params, DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!started_); - disable_job_yield_ = FeatureList::IsEnabled(kDisableJobYield); - disable_fair_scheduling_ = FeatureList::IsEnabled(kDisableFairJobScheduling); - disable_job_update_priority_ = - FeatureList::IsEnabled(kDisableJobUpdatePriority); - // The max number of concurrent BEST_EFFORT tasks is |kMaxBestEffortTasks|, // unless the max number of foreground threads is lower. const size_t max_best_effort_tasks = @@ -140,7 +135,7 @@ void ThreadPoolImpl::Start(const ThreadPoolInstance::InitParams& init_params, // FileDescriptorWatcher in the scope in which tasks run. ServiceThread::Options service_thread_options; service_thread_options.message_pump_type = -#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL) +#if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA) MessagePumpType::IO; #else MessagePumpType::DEFAULT; @@ -200,11 +195,6 @@ void ThreadPoolImpl::Start(const ThreadPoolInstance::InitParams& init_params, #endif } - const base::TimeDelta suggested_reclaim_time = - FeatureList::IsEnabled(kUseFiveMinutesThreadReclaimTime) - ? base::Minutes(5) - : init_params.suggested_reclaim_time; - #if HAS_NATIVE_THREAD_POOL() if (FeatureList::IsEnabled(kUseNativeThreadPool)) { static_cast<ThreadGroupNative*>(foreground_thread_group_.get()) @@ -219,7 +209,7 @@ void ThreadPoolImpl::Start(const ThreadPoolInstance::InitParams& init_params, // of best-effort tasks. static_cast<ThreadGroupImpl*>(foreground_thread_group_.get()) ->Start(init_params.max_num_foreground_threads, max_best_effort_tasks, - suggested_reclaim_time, service_thread_task_runner, + init_params.suggested_reclaim_time, service_thread_task_runner, worker_thread_observer, worker_environment, g_synchronous_thread_start_for_testing); } @@ -234,9 +224,9 @@ void ThreadPoolImpl::Start(const ThreadPoolInstance::InitParams& init_params, { static_cast<ThreadGroupImpl*>(background_thread_group_.get()) ->Start(max_best_effort_tasks, max_best_effort_tasks, - suggested_reclaim_time, service_thread_task_runner, - worker_thread_observer, worker_environment, - g_synchronous_thread_start_for_testing); + init_params.suggested_reclaim_time, + service_thread_task_runner, worker_thread_observer, + worker_environment, g_synchronous_thread_start_for_testing); } } @@ -470,8 +460,6 @@ bool ThreadPoolImpl::PostTaskWithSequence(Task task, } bool ThreadPoolImpl::ShouldYield(const TaskSource* task_source) { - if (disable_job_yield_) - return false; const TaskPriority priority = task_source->priority_racy(); auto* const thread_group = GetThreadGroupForTraits({priority, task_source->thread_policy()}); @@ -480,7 +468,7 @@ bool ThreadPoolImpl::ShouldYield(const TaskSource* task_source) { if (!thread_group->IsBoundToCurrentThread()) return true; return GetThreadGroupForTraits({priority, task_source->thread_policy()}) - ->ShouldYield(task_source->GetSortKey(disable_fair_scheduling_)); + ->ShouldYield(task_source->GetSortKey()); } bool ThreadPoolImpl::EnqueueJobTaskSource( @@ -543,8 +531,6 @@ void ThreadPoolImpl::UpdatePriority(scoped_refptr<TaskSource> task_source, void ThreadPoolImpl::UpdateJobPriority(scoped_refptr<TaskSource> task_source, TaskPriority priority) { - if (disable_job_update_priority_) - return; UpdatePriority(std::move(task_source), priority); } diff --git a/chromium/base/task/thread_pool/thread_pool_impl.h b/chromium/base/task/thread_pool/thread_pool_impl.h index b6eb4c677a9..97730e11b79 100644 --- a/chromium/base/task/thread_pool/thread_pool_impl.h +++ b/chromium/base/task/thread_pool/thread_pool_impl.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -149,10 +149,6 @@ class BASE_EXPORT ThreadPoolImpl : public ThreadPoolInstance, std::unique_ptr<ThreadGroup> foreground_thread_group_; std::unique_ptr<ThreadGroup> background_thread_group_; - bool disable_job_yield_ = false; - bool disable_fair_scheduling_ = false; - std::atomic<bool> disable_job_update_priority_{false}; - // Whether this TaskScheduler was started. bool started_ GUARDED_BY_CONTEXT(sequence_checker_) = false; diff --git a/chromium/base/task/thread_pool/thread_pool_impl_unittest.cc b/chromium/base/task/thread_pool/thread_pool_impl_unittest.cc index b53c6c67765..3ab7d3cc298 100644 --- a/chromium/base/task/thread_pool/thread_pool_impl_unittest.cc +++ b/chromium/base/task/thread_pool/thread_pool_impl_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -331,7 +331,7 @@ class ThreadPoolImplTestBase : public testing::Test { private: void SetupFeatures() { - std::vector<base::Feature> features; + std::vector<base::test::FeatureRef> features; #if HAS_NATIVE_THREAD_POOL() if (GetGroupTypes().foreground_type == test::GroupType::NATIVE) diff --git a/chromium/base/task/thread_pool/thread_pool_instance.cc b/chromium/base/task/thread_pool/thread_pool_instance.cc index a1c77bcb91f..be19c0c832c 100644 --- a/chromium/base/task/thread_pool/thread_pool_instance.cc +++ b/chromium/base/task/thread_pool/thread_pool_instance.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/thread_pool_instance.h b/chromium/base/task/thread_pool/thread_pool_instance.h index a4e502472c6..a8508cf2c42 100644 --- a/chromium/base/task/thread_pool/thread_pool_instance.h +++ b/chromium/base/task/thread_pool/thread_pool_instance.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/thread_pool_perftest.cc b/chromium/base/task/thread_pool/thread_pool_perftest.cc index 802d5f1adac..a29d57d3ff4 100644 --- a/chromium/base/task/thread_pool/thread_pool_perftest.cc +++ b/chromium/base/task/thread_pool/thread_pool_perftest.cc @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/tracked_ref.h b/chromium/base/task/thread_pool/tracked_ref.h index 17e5df69af8..191d2656cf5 100644 --- a/chromium/base/task/thread_pool/tracked_ref.h +++ b/chromium/base/task/thread_pool/tracked_ref.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/tracked_ref_unittest.cc b/chromium/base/task/thread_pool/tracked_ref_unittest.cc index 0f92d6f1b0b..a846646c2b9 100644 --- a/chromium/base/task/thread_pool/tracked_ref_unittest.cc +++ b/chromium/base/task/thread_pool/tracked_ref_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/worker_thread.cc b/chromium/base/task/thread_pool/worker_thread.cc index 8e6f3ddd720..ec83b3c38f1 100644 --- a/chromium/base/task/thread_pool/worker_thread.cc +++ b/chromium/base/task/thread_pool/worker_thread.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -28,7 +28,7 @@ #include "build/build_config.h" #include "third_party/abseil-cpp/absl/types/optional.h" -#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL) +#if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA) #include "base/files/file_descriptor_watcher_posix.h" #endif @@ -102,8 +102,8 @@ void WorkerThread::Delegate::WaitForWork(WaitableEvent* wake_up_event) { defined(PA_THREAD_CACHE_SUPPORTED) TimeDelta min_sleep_time = std::min(sleep_time, kPurgeThreadCacheIdleDelay); - static const base::Feature kDelayFirstWorkerWake{ - "DelayFirstWorkerWake", base::FEATURE_DISABLED_BY_DEFAULT}; + static BASE_FEATURE(kDelayFirstWorkerWake, "DelayFirstWorkerWake", + base::FEATURE_DISABLED_BY_DEFAULT); // ThreadPoolInstance::Start() must always be after FeatureList // initialization. This means this function has access to the feature state on // first call. Cache the feature check to avoid the overhead of calling @@ -157,7 +157,7 @@ bool WorkerThread::Start( CheckedAutoLock auto_lock(thread_lock_); DCHECK(thread_handle_.is_null()); -#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL) +#if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA) DCHECK(io_thread_task_runner); io_thread_task_runner_ = std::move(io_thread_task_runner); #endif @@ -283,7 +283,7 @@ void WorkerThread::UpdateThreadType(ThreadType desired_thread_type) { } void WorkerThread::ThreadMain() { -#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL) +#if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA) DCHECK(io_thread_task_runner_); FileDescriptorWatcher file_descriptor_watcher(io_thread_task_runner_); #endif diff --git a/chromium/base/task/thread_pool/worker_thread.h b/chromium/base/task/thread_pool/worker_thread.h index e0d27a89140..28104df7a8c 100644 --- a/chromium/base/task/thread_pool/worker_thread.h +++ b/chromium/base/task/thread_pool/worker_thread.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/worker_thread_observer.h b/chromium/base/task/thread_pool/worker_thread_observer.h index d2bc95d7e4a..629d293b27b 100644 --- a/chromium/base/task/thread_pool/worker_thread_observer.h +++ b/chromium/base/task/thread_pool/worker_thread_observer.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/worker_thread_stack.cc b/chromium/base/task/thread_pool/worker_thread_stack.cc index 55b4c82c04c..63bc475ca40 100644 --- a/chromium/base/task/thread_pool/worker_thread_stack.cc +++ b/chromium/base/task/thread_pool/worker_thread_stack.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/worker_thread_stack.h b/chromium/base/task/thread_pool/worker_thread_stack.h index 15539d45352..024be8971e6 100644 --- a/chromium/base/task/thread_pool/worker_thread_stack.h +++ b/chromium/base/task/thread_pool/worker_thread_stack.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/worker_thread_stack_unittest.cc b/chromium/base/task/thread_pool/worker_thread_stack_unittest.cc index 4096798f2d2..1047b2f3369 100644 --- a/chromium/base/task/thread_pool/worker_thread_stack_unittest.cc +++ b/chromium/base/task/thread_pool/worker_thread_stack_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/chromium/base/task/thread_pool/worker_thread_unittest.cc b/chromium/base/task/thread_pool/worker_thread_unittest.cc index 1e31dda299b..7d452df81d1 100644 --- a/chromium/base/task/thread_pool/worker_thread_unittest.cc +++ b/chromium/base/task/thread_pool/worker_thread_unittest.cc @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -11,10 +11,10 @@ #include <utility> #include <vector> -#include "base/allocator/allocator_shim.h" -#include "base/allocator/allocator_shim_default_dispatch_to_partition_alloc.h" #include "base/allocator/buildflags.h" #include "base/allocator/partition_allocator/partition_alloc_config.h" +#include "base/allocator/partition_allocator/shim/allocator_shim.h" +#include "base/allocator/partition_allocator/shim/allocator_shim_default_dispatch_to_partition_alloc.h" #include "base/bind.h" #include "base/callback_helpers.h" #include "base/compiler_specific.h" @@ -916,7 +916,7 @@ class WorkerThreadThreadCacheDelegate : public WorkerThreadDefaultDelegate { TEST(ThreadPoolWorkerThreadCachePurgeTest, Purge) { // Make sure the thread cache is enabled in the main partition. - base::internal::PartitionAllocMalloc::Allocator() + allocator_shim::internal::PartitionAllocMalloc::Allocator() ->EnableThreadCacheIfSupported(); Thread service_thread = Thread("ServiceThread"); |