Commit aef33f34 authored by Francois Doray's avatar Francois Doray Committed by Chromium LUCI CQ

[threadpool] Remove obsolete histogram ThreadPool.HeartbeatLatencyMicroseconds.*

These histograms gave an approximate idea of the latency between when a
task is posted and when the ThreadPool starts executing it. However,
they were imperfect:

- If the task is posted just before the system sleeps, it may run
  after the system wakes up from sleep, resulting in a long latency
  being reported.
- The task is more likely to be posted just after the system wakes
  up from sleep.
- The task can be posted in a background renderer. The latency will
  be high because the process priority is low. We have no way to
  distinguish this case.
- The task can be posted when the user is not actively using
  Chrome. The latency will be low because there are no other tasks.
  We have no way to distinguish this case.

Fixed: 1089861
Change-Id: Ibc4c8dc6c4e2ce38e69e7ccfd9ddcda0218dd20a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2526173
Commit-Queue: François Doray <fdoray@chromium.org>
Reviewed-by: default avatarGabriel Charette <gab@chromium.org>
Reviewed-by: default avatarAlexei Svitkine <asvitkine@chromium.org>
Cr-Commit-Position: refs/heads/master@{#831910}
parent c468505c
......@@ -73,7 +73,7 @@ class PooledSingleThreadTaskRunnerManagerTest : public testing::Test {
}
Thread service_thread_{"ThreadPoolServiceThread"};
TaskTracker task_tracker_{"Test"};
TaskTracker task_tracker_;
DelayedTaskManager delayed_task_manager_;
std::unique_ptr<PooledSingleThreadTaskRunnerManager>
single_thread_task_runner_manager_;
......
......@@ -4,51 +4,12 @@
#include "base/task/thread_pool/service_thread.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/debug/alias.h"
#include "base/rand_util.h"
#include "base/stl_util.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/task/thread_pool/task_tracker.h"
#include "base/task/thread_pool/thread_pool_instance.h"
namespace base {
namespace internal {
namespace {
TimeDelta g_heartbeat_for_testing = TimeDelta();
} // namespace
ServiceThread::ServiceThread(const TaskTracker* task_tracker)
: Thread("ThreadPoolServiceThread"), task_tracker_(task_tracker) {}
// static
void ServiceThread::SetHeartbeatIntervalForTesting(TimeDelta heartbeat) {
g_heartbeat_for_testing = heartbeat;
}
void ServiceThread::Init() {
// In unit tests we sometimes do not have a fully functional thread pool
// environment, do not perform the heartbeat report in that case since it
// relies on such an environment.
if (ThreadPoolInstance::Get()) {
// Compute the histogram every hour (with a slight offset to drift if that
// hour tick happens to line up with specific events). Once per hour per
// user was deemed sufficient to gather a reliable metric.
constexpr TimeDelta kHeartbeat = TimeDelta::FromMinutes(59);
heartbeat_metrics_timer_.Start(
FROM_HERE,
g_heartbeat_for_testing.is_zero() ? kHeartbeat
: g_heartbeat_for_testing,
BindRepeating(&ServiceThread::PerformHeartbeatLatencyReport,
Unretained(this)));
}
}
ServiceThread::ServiceThread() : Thread("ThreadPoolServiceThread") {}
NOINLINE void ServiceThread::Run(RunLoop* run_loop) {
Thread::Run(run_loop);
......@@ -57,31 +18,5 @@ NOINLINE void ServiceThread::Run(RunLoop* run_loop) {
base::debug::Alias(&line_number);
}
void ServiceThread::PerformHeartbeatLatencyReport() const {
if (!task_tracker_)
return;
// Only record latency for one TaskPriority per report to avoid bias in the
// order in which tasks are posted (should we record all at once) as well as
// to avoid spinning up many worker threads to process this report if the
// thread pool is currently idle (each thread group keeps at least one idle
// thread so a single task isn't an issue).
// Invoke RandInt() out-of-line to ensure it's obtained before
// TimeTicks::Now().
const TaskPriority profiled_priority = static_cast<TaskPriority>(
RandInt(static_cast<int>(TaskPriority::LOWEST),
static_cast<int>(TaskPriority::HIGHEST)));
// Post through the static API to time the full stack. Use a new Now() for
// every set of traits in case PostTask() itself is slow.
// Bonus: this approach also includes the overhead of BindOnce() in the
// reported latency.
ThreadPool::PostTask(
FROM_HERE, {profiled_priority},
BindOnce(&TaskTracker::RecordHeartbeatLatencyHistogram,
Unretained(task_tracker_), profiled_priority, TimeTicks::Now()));
}
} // namespace internal
} // namespace base
......@@ -7,14 +7,10 @@
#include "base/base_export.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
namespace base {
namespace internal {
class TaskTracker;
// The ThreadPool's ServiceThread is a mostly idle thread that is responsible
// for handling async events (e.g. delayed tasks and async I/O). Its role is to
// merely forward such events to their destination (hence staying mostly idle
......@@ -23,36 +19,15 @@ class TaskTracker;
// and make it easier to identify the service thread in stack traces.
class BASE_EXPORT ServiceThread : public Thread {
public:
// Constructs a ServiceThread which will record heartbeat metrics. This
// includes latency metrics through |task_tracker| if non-null. In that
// case, this ServiceThread will assume a registered ThreadPool instance
// and that |task_tracker| will outlive this ServiceThread.
explicit ServiceThread(const TaskTracker* task_tracker);
ServiceThread();
ServiceThread(const ServiceThread&) = delete;
ServiceThread& operator=(const ServiceThread&) = delete;
~ServiceThread() override = default;
// Overrides the default interval at which |heartbeat_latency_timer_| fires.
// Call this with a |heartbeat| of zero to undo the override.
// Must not be called while the ServiceThread is running.
static void SetHeartbeatIntervalForTesting(TimeDelta heartbeat);
private:
// Thread:
void Init() override;
void Run(RunLoop* run_loop) override;
// Kicks off a single async task which will record a histogram on the latency
// of a randomly chosen set of TaskTraits.
void PerformHeartbeatLatencyReport() const;
const TaskTracker* const task_tracker_;
// Fires a recurring heartbeat task to record metrics which are independent
// from any execution sequence. This is done on the service thread to avoid
// all external dependencies (even main thread).
base::RepeatingTimer heartbeat_metrics_timer_;
};
} // namespace internal
......
......@@ -8,12 +8,6 @@
#include "base/bind.h"
#include "base/debug/stack_trace.h"
#include "base/logging.h"
#include "base/task/thread_pool/thread_pool_impl.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -44,7 +38,7 @@ void VerifyHasStringOnStack(const std::string& query) {
#endif
TEST(ThreadPoolServiceThreadTest, MAYBE_StackHasIdentifyingFrame) {
ServiceThread service_thread(nullptr);
ServiceThread service_thread;
service_thread.Start();
service_thread.task_runner()->PostTask(
......@@ -53,45 +47,5 @@ TEST(ThreadPoolServiceThreadTest, MAYBE_StackHasIdentifyingFrame) {
service_thread.FlushForTesting();
}
// Integration test verifying that a service thread running in a fully
// integrated ThreadPool environment results in reporting
// HeartbeatLatencyMicroseconds metrics.
TEST(ThreadPoolServiceThreadIntegrationTest, HeartbeatLatencyReport) {
ServiceThread::SetHeartbeatIntervalForTesting(TimeDelta::FromMilliseconds(1));
ThreadPoolInstance::Set(std::make_unique<internal::ThreadPoolImpl>("Test"));
ThreadPoolInstance::Get()->StartWithDefaultParams();
static constexpr const char* kExpectedMetrics[] = {
"ThreadPool.HeartbeatLatencyMicroseconds.Test."
"UserBlockingTaskPriority",
"ThreadPool.HeartbeatLatencyMicroseconds.Test."
"UserVisibleTaskPriority",
"ThreadPool.HeartbeatLatencyMicroseconds.Test."
"BackgroundTaskPriority"};
// Each report hits a single histogram above (randomly selected). But 1000
// reports should touch all histograms at least once the vast majority of the
// time.
constexpr TimeDelta kReasonableTimeout = TimeDelta::FromSeconds(1);
constexpr TimeDelta kBusyWaitTime = TimeDelta::FromMilliseconds(100);
const TimeTicks start_time = TimeTicks::Now();
HistogramTester tester;
for (const char* expected_metric : kExpectedMetrics) {
while (tester.GetAllSamples(expected_metric).empty()) {
if (TimeTicks::Now() - start_time > kReasonableTimeout)
LOG(WARNING) << "Waiting a while for " << expected_metric;
PlatformThread::Sleep(kBusyWaitTime);
}
}
ThreadPoolInstance::Get()->JoinForTesting();
ThreadPoolInstance::Set(nullptr);
ServiceThread::SetHeartbeatIntervalForTesting(TimeDelta());
}
} // namespace internal
} // namespace base
......@@ -79,38 +79,6 @@ void TaskTracingInfo::AppendAsTraceFormat(std::string* out) const {
out->append(tmp);
}
// Constructs a histogram to track latency which is logging to
// "ThreadPool.{histogram_name}.{histogram_label}.{task_type_suffix}".
HistogramBase* GetLatencyHistogram(StringPiece histogram_name,
StringPiece histogram_label,
StringPiece task_type_suffix) {
DCHECK(!histogram_name.empty());
DCHECK(!task_type_suffix.empty());
if (histogram_label.empty())
return nullptr;
// Mimics the UMA_HISTOGRAM_HIGH_RESOLUTION_CUSTOM_TIMES macro. The minimums
// and maximums were chosen to place the 1ms mark at around the 70% range
// coverage for buckets giving us good info for tasks that have a latency
// below 1ms (most of them) and enough info to assess how bad the latency is
// for tasks that exceed this threshold.
const std::string histogram = JoinString(
{"ThreadPool", histogram_name, histogram_label, task_type_suffix}, ".");
return Histogram::FactoryMicrosecondsTimeGet(
histogram, TimeDelta::FromMicroseconds(1),
TimeDelta::FromMilliseconds(20), 50,
HistogramBase::kUmaTargetedHistogramFlag);
}
// Returns a histogram stored in an array indexed by task priority.
// TODO(jessemckenna): use the STATIC_HISTOGRAM_POINTER_GROUP macro from
// histogram_macros.h instead.
HistogramBase* GetHistogramForTaskPriority(TaskPriority task_priority,
HistogramBase* const histograms[3]) {
return histograms[static_cast<int>(task_priority)];
}
bool HasLogBestEffortTasksSwitch() {
// The CommandLine might not be initialized if ThreadPool is initialized in a
// dynamic library which doesn't have access to argc/argv.
......@@ -289,24 +257,12 @@ class TaskTracker::State {
subtle::Atomic32 bits_ = 0;
};
// TODO(jessemckenna): Write a helper function to avoid code duplication below.
TaskTracker::TaskTracker(StringPiece histogram_label)
: histogram_label_(histogram_label),
has_log_best_effort_tasks_switch_(HasLogBestEffortTasksSwitch()),
TaskTracker::TaskTracker()
: has_log_best_effort_tasks_switch_(HasLogBestEffortTasksSwitch()),
state_(new State),
can_run_policy_(CanRunPolicy::kAll),
flush_cv_(flush_lock_.CreateConditionVariable()),
shutdown_lock_(&flush_lock_),
heartbeat_latency_histograms_{
GetLatencyHistogram("HeartbeatLatencyMicroseconds",
histogram_label,
"BackgroundTaskPriority"),
GetLatencyHistogram("HeartbeatLatencyMicroseconds",
histogram_label,
"UserVisibleTaskPriority"),
GetLatencyHistogram("HeartbeatLatencyMicroseconds",
histogram_label,
"UserBlockingTaskPriority")},
tracked_ref_factory_(this) {}
TaskTracker::~TaskTracker() = default;
......@@ -483,16 +439,6 @@ bool TaskTracker::IsShutdownComplete() const {
return shutdown_event_ && shutdown_event_->IsSignaled();
}
void TaskTracker::RecordHeartbeatLatencyHistogram(TaskPriority priority,
TimeTicks posted_time) const {
if (histogram_label_.empty())
return;
const TimeDelta task_latency = TimeTicks::Now() - posted_time;
GetHistogramForTaskPriority(priority, heartbeat_latency_histograms_)
->AddTimeMicrosecondsGranularity(task_latency);
}
void TaskTracker::RunTask(Task task,
TaskSource* task_source,
const TaskTraits& traits) {
......
......@@ -15,7 +15,6 @@
#include "base/atomicops.h"
#include "base/base_export.h"
#include "base/callback_forward.h"
#include "base/metrics/histogram_base.h"
#include "base/sequence_checker.h"
#include "base/strings/string_piece.h"
#include "base/synchronization/waitable_event.h"
......@@ -52,9 +51,7 @@ enum class CanRunPolicy {
// and records metrics and trace events. This class is thread-safe.
class BASE_EXPORT TaskTracker {
public:
// |histogram_label| is used to label histograms. No histograms are recorded
// if it is empty.
explicit TaskTracker(StringPiece histogram_label);
TaskTracker();
TaskTracker(const TaskTracker&) = delete;
TaskTracker& operator=(const TaskTracker&) = delete;
virtual ~TaskTracker();
......@@ -131,13 +128,6 @@ class BASE_EXPORT TaskTracker {
// no tasks are blocking shutdown).
bool IsShutdownComplete() const;
// Records Now() - posted_time to
// ThreadPool.[label].HeartbeatLatencyMicroseconds.[suffix].
// [label] is the histogram label provided to the constructor.
// [suffix] is derived from |task_priority|.
void RecordHeartbeatLatencyHistogram(TaskPriority task_priority,
TimeTicks posted_time) const;
TrackedRef<TaskTracker> GetTrackedRef() {
return tracked_ref_factory_.GetTrackedRef();
}
......@@ -249,14 +239,6 @@ class BASE_EXPORT TaskTracker {
// completes.
std::unique_ptr<WaitableEvent> shutdown_event_ GUARDED_BY(shutdown_lock_);
// ThreadPool.HeartbeatLatencyMicroseconds.* histograms. The index is a
// TaskPriority. Intentionally leaked.
// TODO(scheduler-dev): Consider using STATIC_HISTOGRAM_POINTER_GROUP.
using TaskPriorityType = std::underlying_type<TaskPriority>::type;
static constexpr TaskPriorityType kNumTaskPriorities =
static_cast<TaskPriorityType>(TaskPriority::HIGHEST) + 1;
HistogramBase* const heartbeat_latency_histograms_[kNumTaskPriorities];
// Ensures all state (e.g. dangling cleaned up workers) is coalesced before
// destroying the TaskTracker (e.g. in test environments).
// Ref. https://crbug.com/827615.
......
......@@ -11,7 +11,7 @@
namespace base {
namespace internal {
TaskTrackerPosix::TaskTrackerPosix(StringPiece name) : TaskTracker(name) {}
TaskTrackerPosix::TaskTrackerPosix() = default;
TaskTrackerPosix::~TaskTrackerPosix() = default;
void TaskTrackerPosix::RunTask(Task task,
......
......@@ -24,7 +24,7 @@ struct Task;
// TaskTracker can run tasks.
class BASE_EXPORT TaskTrackerPosix : public TaskTracker {
public:
explicit TaskTrackerPosix(StringPiece name);
TaskTrackerPosix();
TaskTrackerPosix(const TaskTrackerPosix&) = delete;
TaskTrackerPosix& operator=(const TaskTrackerPosix&) = delete;
~TaskTrackerPosix() override;
......
......@@ -45,7 +45,7 @@ class ThreadPoolTaskTrackerPosixTest : public testing::Test {
protected:
Thread service_thread_;
TaskTrackerPosix tracker_{"Test"};
TaskTrackerPosix tracker_;
};
} // namespace
......
......@@ -239,7 +239,7 @@ class ThreadPoolTaskTrackerTest
return num_tasks_executed_;
}
TaskTracker tracker_{"Test"};
TaskTracker tracker_;
private:
void RunTaskCallback() {
......@@ -1173,7 +1173,7 @@ class WaitAllowedTestThread : public SimpleThread {
private:
void Run() override {
auto task_tracker = std::make_unique<TaskTracker>("Test");
auto task_tracker = std::make_unique<TaskTracker>();
// Waiting is allowed by default. Expect TaskTracker to disallow it before
// running a task without the WithBaseSyncPrimitives() trait.
......
......@@ -124,7 +124,7 @@ class ThreadGroupImplImplTestBase : public ThreadGroup::Delegate {
}
Thread service_thread_;
TaskTracker task_tracker_{"Test"};
TaskTracker task_tracker_;
std::unique_ptr<ThreadGroupImpl> thread_group_;
DelayedTaskManager delayed_task_manager_;
TrackedRefFactory<ThreadGroup::Delegate> tracked_ref_factory_;
......
......@@ -167,7 +167,7 @@ class ThreadGroupTestBase : public testing::Test, public ThreadGroup::Delegate {
virtual test::PoolType GetPoolType() const = 0;
Thread service_thread_{"ThreadPoolServiceThread"};
TaskTracker task_tracker_{"Test"};
TaskTracker task_tracker_;
DelayedTaskManager delayed_task_manager_;
test::MockPooledTaskRunnerDelegate mock_pooled_task_runner_delegate_ = {
task_tracker_.GetTrackedRef(), &delayed_task_manager_};
......
......@@ -23,7 +23,6 @@
#include "base/task/task_features.h"
#include "base/task/thread_pool/pooled_parallel_task_runner.h"
#include "base/task/thread_pool/pooled_sequenced_task_runner.h"
#include "base/task/thread_pool/service_thread.h"
#include "base/task/thread_pool/task.h"
#include "base/task/thread_pool/task_source.h"
#include "base/task/thread_pool/task_source_sort_key.h"
......@@ -71,13 +70,11 @@ bool g_synchronous_thread_start_for_testing = false;
} // namespace
ThreadPoolImpl::ThreadPoolImpl(StringPiece histogram_label)
: ThreadPoolImpl(histogram_label,
std::make_unique<TaskTrackerImpl>(histogram_label)) {}
: ThreadPoolImpl(histogram_label, std::make_unique<TaskTrackerImpl>()) {}
ThreadPoolImpl::ThreadPoolImpl(StringPiece histogram_label,
std::unique_ptr<TaskTrackerImpl> task_tracker)
: task_tracker_(std::move(task_tracker)),
service_thread_(std::make_unique<ServiceThread>(task_tracker_.get())),
single_thread_task_runner_manager_(task_tracker_->GetTrackedRef(),
&delayed_task_manager_),
has_disable_best_effort_switch_(HasDisableBestEffortTasksSwitch()),
......@@ -159,21 +156,21 @@ void ThreadPoolImpl::Start(const ThreadPoolInstance::InitParams& init_params,
MessagePumpType::DEFAULT;
#endif
service_thread_options.timer_slack = TIMER_SLACK_MAXIMUM;
CHECK(service_thread_->StartWithOptions(service_thread_options));
CHECK(service_thread_.StartWithOptions(service_thread_options));
if (g_synchronous_thread_start_for_testing)
service_thread_->WaitUntilThreadStarted();
service_thread_.WaitUntilThreadStarted();
#if defined(OS_POSIX) && !defined(OS_NACL_SFI)
// Needs to happen after starting the service thread to get its
// task_runner().
task_tracker_->set_io_thread_task_runner(service_thread_->task_runner());
task_tracker_->set_io_thread_task_runner(service_thread_.task_runner());
#endif // defined(OS_POSIX) && !defined(OS_NACL_SFI)
// Update the CanRunPolicy based on |has_disable_best_effort_switch_|.
UpdateCanRunPolicy();
// Needs to happen after starting the service thread to get its task_runner().
auto service_thread_task_runner = service_thread_->task_runner();
auto service_thread_task_runner = service_thread_.task_runner();
delayed_task_manager_.Start(service_thread_task_runner);
single_thread_task_runner_manager_.Start(worker_thread_observer);
......@@ -317,7 +314,7 @@ void ThreadPoolImpl::Shutdown() {
// being guaranteed to happen anyways, stopping right away is valid behavior
// and avoids the more complex alternative of shutting down the service thread
// atomically during TaskTracker shutdown.
service_thread_->Stop();
service_thread_.Stop();
task_tracker_->StartShutdown();
......@@ -345,7 +342,7 @@ void ThreadPoolImpl::JoinForTesting() {
// tasks scheduled by the DelayedTaskManager might be posted between joining
// those workers and stopping the service thread which will cause a CHECK. See
// https://crbug.com/771701.
service_thread_->Stop();
service_thread_.Stop();
single_thread_task_runner_manager_.JoinForTesting();
foreground_thread_group_->JoinForTesting();
if (background_thread_group_)
......
......@@ -24,6 +24,7 @@
#include "base/task/thread_pool/environment_config.h"
#include "base/task/thread_pool/pooled_single_thread_task_runner_manager.h"
#include "base/task/thread_pool/pooled_task_runner_delegate.h"
#include "base/task/thread_pool/service_thread.h"
#include "base/task/thread_pool/task_source.h"
#include "base/task/thread_pool/task_tracker.h"
#include "base/task/thread_pool/thread_group.h"
......@@ -42,8 +43,6 @@
namespace base {
class Thread;
namespace internal {
// Default ThreadPoolInstance implementation. This class is thread-safe.
......@@ -155,7 +154,7 @@ class BASE_EXPORT ThreadPoolImpl : public ThreadPoolInstance,
bool ShouldYield(const TaskSource* task_source) override;
const std::unique_ptr<TaskTrackerImpl> task_tracker_;
std::unique_ptr<Thread> service_thread_;
ServiceThread service_thread_;
DelayedTaskManager delayed_task_manager_;
PooledSingleThreadTaskRunnerManager single_thread_task_runner_manager_;
......
......@@ -52,7 +52,7 @@ class ThreadPoolWorkerStackTest : public testing::Test {
}
private:
TaskTracker task_tracker_{"Test"};
TaskTracker task_tracker_;
protected:
scoped_refptr<WorkerThread> worker_a_;
......
......@@ -270,7 +270,7 @@ class ThreadPoolWorkerTest : public testing::TestWithParam<int> {
EXPECT_LE(num_run_tasks_, created_sequences_.size());
}
TaskTracker task_tracker_{"Test"};
TaskTracker task_tracker_;
// Synchronizes access to all members below.
mutable CheckedLock lock_;
......@@ -521,7 +521,7 @@ class MockedControllableCleanupDelegate : public ControllableCleanupDelegate {
// Verify that calling WorkerThread::Cleanup() from GetWork() causes
// the WorkerThread's thread to exit.
TEST(ThreadPoolWorkerTest, WorkerCleanupFromGetWork) {
TaskTracker task_tracker("Test");
TaskTracker task_tracker;
// Will be owned by WorkerThread.
MockedControllableCleanupDelegate* delegate =
new StrictMock<MockedControllableCleanupDelegate>(&task_tracker);
......@@ -542,7 +542,7 @@ TEST(ThreadPoolWorkerTest, WorkerCleanupFromGetWork) {
}
TEST(ThreadPoolWorkerTest, WorkerCleanupDuringWork) {
TaskTracker task_tracker("Test");
TaskTracker task_tracker;
// Will be owned by WorkerThread.
// No mock here as that's reasonably covered by other tests and the delegate
// may destroy on a different thread. Mocks aren't designed with that in mind.
......@@ -567,7 +567,7 @@ TEST(ThreadPoolWorkerTest, WorkerCleanupDuringWork) {
}
TEST(ThreadPoolWorkerTest, WorkerCleanupDuringWait) {
TaskTracker task_tracker("Test");
TaskTracker task_tracker;
// Will be owned by WorkerThread.
// No mock here as that's reasonably covered by other tests and the delegate
// may destroy on a different thread. Mocks aren't designed with that in mind.
......@@ -589,7 +589,7 @@ TEST(ThreadPoolWorkerTest, WorkerCleanupDuringWait) {
}
TEST(ThreadPoolWorkerTest, WorkerCleanupDuringShutdown) {
TaskTracker task_tracker("Test");
TaskTracker task_tracker;
// Will be owned by WorkerThread.
// No mock here as that's reasonably covered by other tests and the delegate
// may destroy on a different thread. Mocks aren't designed with that in mind.
......@@ -616,7 +616,7 @@ TEST(ThreadPoolWorkerTest, WorkerCleanupDuringShutdown) {
// Verify that Start() is a no-op after Cleanup().
TEST(ThreadPoolWorkerTest, CleanupBeforeStart) {
TaskTracker task_tracker("Test");
TaskTracker task_tracker;
// Will be owned by WorkerThread.
// No mock here as that's reasonably covered by other tests and the delegate
// may destroy on a different thread. Mocks aren't designed with that in mind.
......@@ -664,7 +664,7 @@ class CallJoinFromDifferentThread : public SimpleThread {
} // namespace
TEST(ThreadPoolWorkerTest, WorkerCleanupDuringJoin) {
TaskTracker task_tracker("Test");
TaskTracker task_tracker;
// Will be owned by WorkerThread.
// No mock here as that's reasonably covered by other tests and the
// delegate may destroy on a different thread. Mocks aren't designed with that
......@@ -751,7 +751,7 @@ TEST(ThreadPoolWorkerTest, BumpPriorityOfAliveThreadDuringShutdown) {
if (!CanUseBackgroundPriorityForWorkerThread())
return;
TaskTracker task_tracker("Test");
TaskTracker task_tracker;
// Block shutdown to ensure that the worker doesn't exit when StartShutdown()
// is called.
......@@ -814,7 +814,7 @@ class VerifyCallsToObserverDelegate : public WorkerThreadDefaultDelegate {
// and exits its main function.
TEST(ThreadPoolWorkerTest, WorkerThreadObserver) {
StrictMock<test::MockWorkerThreadObserver> observer;
TaskTracker task_tracker("Test");
TaskTracker task_tracker;
auto delegate = std::make_unique<VerifyCallsToObserverDelegate>(&observer);
auto worker =
MakeRefCounted<WorkerThread>(ThreadPriority::NORMAL, std::move(delegate),
......
......@@ -724,9 +724,7 @@ void TaskEnvironment::RemoveDestructionObserver(DestructionObserver* observer) {
}
TaskEnvironment::TestTaskTracker::TestTaskTracker()
: internal::ThreadPoolImpl::TaskTrackerImpl(std::string()),
can_run_tasks_cv_(&lock_),
task_completed_cv_(&lock_) {
: can_run_tasks_cv_(&lock_), task_completed_cv_(&lock_) {
// Consider threads blocked on these as idle (avoids instantiating
// ScopedBlockingCalls and confusing some //base internals tests).
can_run_tasks_cv_.declare_only_used_while_idle();
......
......@@ -330,6 +330,9 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
<histogram base="true" name="ThreadPool.HeartbeatLatencyMicroseconds"
units="microseconds" expires_after="M85">
<obsolete>
Removed 11/2020. Not actively used.
</obsolete>
<owner>fdoray@chromium.org</owner>
<owner>gab@chromium.org</owner>
<owner>robliao@chromium.org</owner>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment