#include "base/task/thread_pool/thread_group.h"
#include <string_view>
#include <utility>
#include "base/check.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/task/task_features.h"
#include "base/task/thread_pool/task_tracker.h"
#include "build/build_config.h"
#include "third_party/abseil-cpp/absl/base/attributes.h"
#if BUILDFLAG(IS_WIN)
#include "base/win/com_init_check_hook.h"
#include "base/win/scoped_winrt_initializer.h"
#endif
namespace base {
namespace internal {
namespace {
constexpr size_t kMaxNumberOfWorkers = …;
constexpr TimeDelta kForegroundMayBlockThreshold = …;
constexpr TimeDelta kForegroundBlockedWorkersPoll = …;
constexpr TimeDelta kBackgroundMayBlockThreshold = …;
constexpr TimeDelta kBackgroundBlockedWorkersPoll = …;
ABSL_CONST_INIT thread_local const ThreadGroup* current_thread_group = …;
}
constexpr ThreadGroup::YieldSortKey ThreadGroup::kMaxYieldSortKey;
void ThreadGroup::BaseScopedCommandsExecutor::ScheduleReleaseTaskSource(
RegisteredTaskSource task_source) { … }
void ThreadGroup::BaseScopedCommandsExecutor::ScheduleAdjustMaxTasks() { … }
void ThreadGroup::BaseScopedCommandsExecutor::ScheduleStart(
scoped_refptr<WorkerThread> worker) { … }
ThreadGroup::BaseScopedCommandsExecutor::BaseScopedCommandsExecutor(
ThreadGroup* outer)
: … { … }
ThreadGroup::BaseScopedCommandsExecutor::~BaseScopedCommandsExecutor() { … }
void ThreadGroup::BaseScopedCommandsExecutor::FlushWorkerCreation(
CheckedLock* held_lock) { … }
void ThreadGroup::BaseScopedCommandsExecutor::Flush() { … }
ThreadGroup::ScopedReenqueueExecutor::ScopedReenqueueExecutor() = default;
ThreadGroup::ScopedReenqueueExecutor::~ScopedReenqueueExecutor() { … }
void ThreadGroup::ScopedReenqueueExecutor::
SchedulePushTaskSourceAndWakeUpWorkers(
RegisteredTaskSourceAndTransaction transaction_with_task_source,
ThreadGroup* destination_thread_group) { … }
ThreadGroup::ThreadGroup(std::string_view histogram_label,
std::string_view thread_group_label,
ThreadType thread_type_hint,
TrackedRef<TaskTracker> task_tracker,
TrackedRef<Delegate> delegate)
: … { … }
void ThreadGroup::StartImpl(
size_t max_tasks,
size_t max_best_effort_tasks,
TimeDelta suggested_reclaim_time,
scoped_refptr<SingleThreadTaskRunner> service_thread_task_runner,
WorkerThreadObserver* worker_thread_observer,
WorkerEnvironment worker_environment,
bool synchronous_thread_start_for_testing,
std::optional<TimeDelta> may_block_threshold) { … }
ThreadGroup::~ThreadGroup() = default;
void ThreadGroup::BindToCurrentThread() { … }
void ThreadGroup::UnbindFromCurrentThread() { … }
bool ThreadGroup::IsBoundToCurrentThread() const { … }
void ThreadGroup::SetMaxTasks(size_t max_tasks) { … }
void ThreadGroup::ResetMaxTasks() { … }
size_t
ThreadGroup::GetNumAdditionalWorkersForBestEffortTaskSourcesLockRequired()
const { … }
size_t
ThreadGroup::GetNumAdditionalWorkersForForegroundTaskSourcesLockRequired()
const { … }
RegisteredTaskSource ThreadGroup::RemoveTaskSource(
const TaskSource& task_source) { … }
void ThreadGroup::ReEnqueueTaskSourceLockRequired(
BaseScopedCommandsExecutor* workers_executor,
ScopedReenqueueExecutor* reenqueue_executor,
RegisteredTaskSourceAndTransaction transaction_with_task_source) { … }
RegisteredTaskSource ThreadGroup::TakeRegisteredTaskSource(
BaseScopedCommandsExecutor* executor) { … }
void ThreadGroup::UpdateSortKeyImpl(BaseScopedCommandsExecutor* executor,
TaskSource::Transaction transaction) { … }
void ThreadGroup::PushTaskSourceAndWakeUpWorkersImpl(
BaseScopedCommandsExecutor* executor,
RegisteredTaskSourceAndTransaction transaction_with_task_source) { … }
void ThreadGroup::EnqueueAllTaskSources(PriorityQueue* new_priority_queue) { … }
void ThreadGroup::HandoffAllTaskSourcesToOtherThreadGroup(
ThreadGroup* destination_thread_group) { … }
void ThreadGroup::HandoffNonUserBlockingTaskSourcesToOtherThreadGroup(
ThreadGroup* destination_thread_group) { … }
bool ThreadGroup::ShouldYield(TaskSourceSortKey sort_key) { … }
#if BUILDFLAG(IS_WIN)
std::unique_ptr<win::ScopedWindowsThreadEnvironment>
ThreadGroup::GetScopedWindowsThreadEnvironment(WorkerEnvironment environment) {
std::unique_ptr<win::ScopedWindowsThreadEnvironment> scoped_environment;
if (environment == WorkerEnvironment::COM_MTA) {
scoped_environment = std::make_unique<win::ScopedWinrtInitializer>();
}
CHECK(!scoped_environment || scoped_environment->Succeeded());
return scoped_environment;
}
#endif
bool ThreadGroup::CurrentThreadHasGroup() { … }
size_t ThreadGroup::GetMaxTasksForTesting() const { … }
size_t ThreadGroup::GetMaxBestEffortTasksForTesting() const { … }
void ThreadGroup::WaitForWorkersIdleLockRequiredForTesting(size_t n) { … }
void ThreadGroup::WaitForWorkersIdleForTesting(size_t n) { … }
void ThreadGroup::WaitForAllWorkersIdleForTesting() { … }
void ThreadGroup::WaitForWorkersCleanedUpForTesting(size_t n) { … }
size_t ThreadGroup::GetMaxConcurrentNonBlockedTasksDeprecated() const { … }
size_t ThreadGroup::NumberOfWorkersForTesting() const { … }
size_t ThreadGroup::NumberOfIdleWorkersForTesting() const { … }
size_t ThreadGroup::GetDesiredNumAwakeWorkersLockRequired() const { … }
void ThreadGroup::MaybeScheduleAdjustMaxTasksLockRequired(
BaseScopedCommandsExecutor* executor) { … }
bool ThreadGroup::ShouldPeriodicallyAdjustMaxTasksLockRequired() { … }
void ThreadGroup::UpdateMinAllowedPriorityLockRequired() { … }
void ThreadGroup::DecrementTasksRunningLockRequired(TaskPriority priority) { … }
void ThreadGroup::IncrementTasksRunningLockRequired(TaskPriority priority) { … }
void ThreadGroup::DecrementMaxTasksLockRequired() { … }
void ThreadGroup::IncrementMaxTasksLockRequired() { … }
void ThreadGroup::DecrementMaxBestEffortTasksLockRequired() { … }
void ThreadGroup::IncrementMaxBestEffortTasksLockRequired() { … }
ThreadGroup::InitializedInStart::InitializedInStart() = default;
ThreadGroup::InitializedInStart::~InitializedInStart() = default;
}
}