[vm] Use std::unique_ptr for ThreadPool::Task
Updates #37244.
Change-Id: I32a5180a17fe43be5e18367d784cf756dffc6aeb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106009
Commit-Queue: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: RĂ©gis Crelier <regis@google.com>
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 88d50b8..436e895 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -245,14 +245,7 @@
// Since this is a call to Isolate.spawn, copy the parent isolate's code.
state->isolate_flags()->copy_parent_code = true;
- ThreadPool::Task* spawn_task =
- new SpawnIsolateTask(isolate, std::move(state));
-
- if (!Dart::thread_pool()->Run(spawn_task)) {
- // Running on the thread pool failed. Clean up everything.
- delete spawn_task;
- spawn_task = NULL;
- }
+ Dart::thread_pool()->Run<SpawnIsolateTask>(isolate, std::move(state));
return Object::null();
}
}
@@ -373,14 +366,7 @@
// Since this is a call to Isolate.spawnUri, don't copy the parent's code.
state->isolate_flags()->copy_parent_code = false;
- ThreadPool::Task* spawn_task =
- new SpawnIsolateTask(isolate, std::move(state));
-
- if (!Dart::thread_pool()->Run(spawn_task)) {
- // Running on the thread pool failed. Clean up everything.
- delete spawn_task;
- spawn_task = NULL;
- }
+ Dart::thread_pool()->Run<SpawnIsolateTask>(isolate, std::move(state));
return Object::null();
}
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index e5b7b35..1a5213c 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -1389,8 +1389,7 @@
if (running_ || !done_) return;
running_ = true;
done_ = false;
- bool task_started =
- Dart::thread_pool()->Run(new BackgroundCompilerTask(this));
+ bool task_started = Dart::thread_pool()->Run<BackgroundCompilerTask>(this);
if (!task_started) {
running_ = false;
done_ = true;
diff --git a/runtime/vm/heap/compactor.cc b/runtime/vm/heap/compactor.cc
index 06ac415..45f566e 100644
--- a/runtime/vm/heap/compactor.cc
+++ b/runtime/vm/heap/compactor.cc
@@ -234,9 +234,9 @@
intptr_t next_forwarding_task = 0;
for (intptr_t task_index = 0; task_index < num_tasks; task_index++) {
- Dart::thread_pool()->Run(new CompactorTask(
+ Dart::thread_pool()->Run<CompactorTask>(
thread()->isolate(), this, &barrier, &next_forwarding_task,
- heads[task_index], &tails[task_index], freelist));
+ heads[task_index], &tails[task_index], freelist);
}
// Plan pages.
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index ec644c0..01149d5 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -804,8 +804,8 @@
&deferred_marking_stack_);
// Begin marking on a helper thread.
- bool result = Dart::thread_pool()->Run(
- new ConcurrentMarkTask(this, isolate_, page_space, visitors_[i]));
+ bool result = Dart::thread_pool()->Run<ConcurrentMarkTask>(
+ this, isolate_, page_space, visitors_[i]);
ASSERT(result);
}
@@ -862,8 +862,8 @@
isolate_, page_space, &marking_stack_, &deferred_marking_stack_);
}
- bool result = Dart::thread_pool()->Run(new ParallelMarkTask(
- this, isolate_, &marking_stack_, &barrier, visitor, &num_busy));
+ bool result = Dart::thread_pool()->Run<ParallelMarkTask>(
+ this, isolate_, &marking_stack_, &barrier, visitor, &num_busy);
ASSERT(result);
}
bool more_to_mark = false;
diff --git a/runtime/vm/heap/sweeper.cc b/runtime/vm/heap/sweeper.cc
index b1e385f..1d267ac 100644
--- a/runtime/vm/heap/sweeper.cc
+++ b/runtime/vm/heap/sweeper.cc
@@ -182,8 +182,8 @@
HeapPage* first,
HeapPage* last,
FreeList* freelist) {
- bool result = Dart::thread_pool()->Run(new ConcurrentSweeperTask(
- isolate, isolate->heap()->old_space(), first, last, freelist));
+ bool result = Dart::thread_pool()->Run<ConcurrentSweeperTask>(
+ isolate, isolate->heap()->old_space(), first, last, freelist);
ASSERT(result);
}
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc
index b019598c..2b0f84f 100644
--- a/runtime/vm/isolate_test.cc
+++ b/runtime/vm/isolate_test.cc
@@ -130,7 +130,7 @@
isolate->heap()->barrier_done());
// Start all tasks. They will busy-wait until interrupted in the first round.
for (intptr_t task = 0; task < InterruptChecker::kTaskCount; task++) {
- Dart::thread_pool()->Run(new InterruptChecker(thread, &barrier));
+ Dart::thread_pool()->Run<InterruptChecker>(thread, &barrier);
}
// Wait for all tasks to get ready for the first round.
barrier.Sync();
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index abf5036..e1b8c7c 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -232,7 +232,7 @@
KernelIsolate::InitializingFailed();
return;
}
- bool task_started = Dart::thread_pool()->Run(new RunKernelTask());
+ bool task_started = Dart::thread_pool()->Run<RunKernelTask>();
ASSERT(task_started);
}
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index 06fd9e2..122fb58 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -114,7 +114,7 @@
start_callback_ = start_callback;
end_callback_ = end_callback;
callback_data_ = data;
- task_running_ = pool_->Run(new MessageHandlerTask(this));
+ task_running_ = pool_->Run<MessageHandlerTask>(this);
ASSERT(task_running_);
}
@@ -157,7 +157,7 @@
if ((pool_ != NULL) && !task_running_) {
ASSERT(!delete_me_);
- task_running_ = pool_->Run(new MessageHandlerTask(this));
+ task_running_ = pool_->Run<MessageHandlerTask>(this);
ASSERT(task_running_);
}
}
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 8a223ee..d76e551 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -483,7 +483,7 @@
ServiceIsolate::InitializingFailed();
return;
}
- bool task_started = Dart::thread_pool()->Run(new RunServiceTask());
+ bool task_started = Dart::thread_pool()->Run<RunServiceTask>();
ASSERT(task_started);
}
diff --git a/runtime/vm/thread_barrier_test.cc b/runtime/vm/thread_barrier_test.cc
index 42bc53b..c937eeb2 100644
--- a/runtime/vm/thread_barrier_test.cc
+++ b/runtime/vm/thread_barrier_test.cc
@@ -45,7 +45,7 @@
{
ThreadBarrier barrier(kNumTasks + 1, monitor, monitor_done);
for (intptr_t i = 0; i < kNumTasks; ++i) {
- Dart::thread_pool()->Run(new FuzzTask(kNumRounds, &barrier, i + 1));
+ Dart::thread_pool()->Run<FuzzTask>(kNumRounds, &barrier, i + 1);
}
for (intptr_t i = 0; i < kNumRounds; ++i) {
barrier.Sync();
diff --git a/runtime/vm/thread_pool.cc b/runtime/vm/thread_pool.cc
index 3a085ae..6f43097 100644
--- a/runtime/vm/thread_pool.cc
+++ b/runtime/vm/thread_pool.cc
@@ -30,7 +30,7 @@
Shutdown();
}
-bool ThreadPool::Run(Task* task) {
+bool ThreadPool::RunImpl(std::unique_ptr<Task> task) {
Worker* worker = NULL;
bool new_worker = false;
{
@@ -63,7 +63,7 @@
// Release ThreadPool::mutex_ before calling Worker functions.
ASSERT(worker != NULL);
- worker->SetTask(task);
+ worker->SetTask(std::move(task));
if (new_worker) {
// Call StartThread after we've assigned the first task.
worker->StartThread();
@@ -314,7 +314,7 @@
ThreadPool::Worker::Worker(ThreadPool* pool)
: pool_(pool),
- task_(NULL),
+ task_(nullptr),
id_(OSThread::kInvalidThreadId),
done_(false),
owned_(false),
@@ -332,7 +332,7 @@
// Must call SetTask before StartThread.
{ // NOLINT
MonitorLocker ml(&monitor_);
- ASSERT(task_ != NULL);
+ ASSERT(task_ != nullptr);
}
#endif
int result = OSThread::Start("Dart ThreadPool Worker", &Worker::Main,
@@ -342,10 +342,10 @@
}
}
-void ThreadPool::Worker::SetTask(Task* task) {
+void ThreadPool::Worker::SetTask(std::unique_ptr<Task> task) {
MonitorLocker ml(&monitor_);
- ASSERT(task_ == NULL);
- task_ = task;
+ ASSERT(task_ == nullptr);
+ task_ = std::move(task);
ml.Notify();
}
@@ -372,18 +372,17 @@
MonitorLocker ml(&monitor_);
int64_t idle_start;
while (true) {
- ASSERT(task_ != NULL);
- Task* task = task_;
- task_ = NULL;
+ ASSERT(task_ != nullptr);
+ std::unique_ptr<Task> task = std::move(task_);
// Release monitor while handling the task.
ml.Exit();
task->Run();
ASSERT(Isolate::Current() == NULL);
- delete task;
+ task.reset();
ml.Enter();
- ASSERT(task_ == NULL);
+ ASSERT(task_ == nullptr);
if (IsDone()) {
return false;
}
@@ -392,7 +391,7 @@
idle_start = OS::GetCurrentMonotonicMicros();
while (true) {
Monitor::WaitResult result = ml.WaitMicros(ComputeTimeout(idle_start));
- if (task_ != NULL) {
+ if (task_ != nullptr) {
// We've found a task. Process it, regardless of whether the
// worker is done_.
break;
diff --git a/runtime/vm/thread_pool.h b/runtime/vm/thread_pool.h
index 6fbe0d7..5a1ff54 100644
--- a/runtime/vm/thread_pool.h
+++ b/runtime/vm/thread_pool.h
@@ -5,6 +5,9 @@
#ifndef RUNTIME_VM_THREAD_POOL_H_
#define RUNTIME_VM_THREAD_POOL_H_
+#include <memory>
+#include <utility>
+
#include "vm/allocation.h"
#include "vm/globals.h"
#include "vm/os_thread.h"
@@ -35,7 +38,10 @@
~ThreadPool();
// Runs a task on the thread pool.
- bool Run(Task* task);
+ template <typename T, typename... Args>
+ bool Run(Args&&... args) {
+ return RunImpl(std::unique_ptr<Task>(new T(std::forward<Args>(args)...)));
+ }
// Some simple stats.
uint64_t workers_running() const { return count_running_; }
@@ -49,7 +55,7 @@
explicit Worker(ThreadPool* pool);
// Sets a task on the worker.
- void SetTask(Task* task);
+ void SetTask(std::unique_ptr<Task> task);
// Starts the thread for the worker. This should only be called
// after a task has been set by the initial call to SetTask().
@@ -76,7 +82,7 @@
// Fields owned by Worker.
Monitor monitor_;
ThreadPool* pool_;
- Task* task_;
+ std::unique_ptr<Task> task_;
ThreadId id_;
bool done_;
@@ -110,6 +116,7 @@
DISALLOW_COPY_AND_ASSIGN(JoinList);
};
+ bool RunImpl(std::unique_ptr<Task> task);
void Shutdown();
// Expensive. Use only in assertions.
diff --git a/runtime/vm/thread_pool_test.cc b/runtime/vm/thread_pool_test.cc
index 1706a99..ab197f5 100644
--- a/runtime/vm/thread_pool_test.cc
+++ b/runtime/vm/thread_pool_test.cc
@@ -44,7 +44,7 @@
ThreadPool thread_pool;
Monitor sync;
bool done = true;
- thread_pool.Run(new TestTask(&sync, &done));
+ thread_pool.Run<TestTask>(&sync, &done);
{
MonitorLocker ml(&sync);
done = false;
@@ -68,7 +68,7 @@
for (int i = 0; i < kTaskCount; i++) {
done[i] = true;
- thread_pool.Run(new TestTask(&sync[i], &done[i]));
+ thread_pool.Run<TestTask>(&sync[i], &done[i]);
}
for (int i = 0; i < kTaskCount; i++) {
MonitorLocker ml(&sync[i]);
@@ -124,7 +124,7 @@
// Run a single task.
for (int i = 0; i < kTaskCount; i++) {
- thread_pool->Run(new SleepTask(&sync, &started_count, &slept_count, 2));
+ thread_pool->Run<SleepTask>(&sync, &started_count, &slept_count, 2);
}
{
@@ -162,7 +162,7 @@
// Run a worker.
Monitor sync;
bool done = true;
- thread_pool.Run(new TestTask(&sync, &done));
+ thread_pool.Run<TestTask>(&sync, &done);
EXPECT_EQ(1U, thread_pool.workers_started());
EXPECT_EQ(0U, thread_pool.workers_stopped());
{
@@ -197,11 +197,10 @@
// Spawn 0-2 children.
if (todo_ > 0) {
- pool_->Run(
- new SpawnTask(pool_, sync_, todo_ - child_todo, total_, done_));
+ pool_->Run<SpawnTask>(pool_, sync_, todo_ - child_todo, total_, done_);
}
if (todo_ > 1) {
- pool_->Run(new SpawnTask(pool_, sync_, child_todo, total_, done_));
+ pool_->Run<SpawnTask>(pool_, sync_, child_todo, total_, done_);
}
{
@@ -226,8 +225,8 @@
Monitor sync;
const int kTotalTasks = 500;
int done = 0;
- thread_pool.Run(
- new SpawnTask(&thread_pool, &sync, kTotalTasks, kTotalTasks, &done));
+ thread_pool.Run<SpawnTask>(&thread_pool, &sync, kTotalTasks, kTotalTasks,
+ &done);
{
MonitorLocker ml(&sync);
while (done < kTotalTasks) {
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index 1030795..edbc632 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -180,8 +180,8 @@
isolate->heap()->DisableGrowthControl();
for (int i = 0; i < kTaskCount; i++) {
done[i] = false;
- Dart::thread_pool()->Run(
- new TaskWithZoneAllocation(isolate, &sync[i], &done[i], i));
+ Dart::thread_pool()->Run<TaskWithZoneAllocation>(isolate, &sync[i],
+ &done[i], i);
}
bool in_isolate = true;
for (int i = 0; i < kTaskCount; i++) {
@@ -302,8 +302,8 @@
EXPECT(isolate->heap()->GrowthControlState());
isolate->heap()->DisableGrowthControl();
for (intptr_t i = 0; i < kTaskCount; i++) {
- Dart::thread_pool()->Run(new SimpleTaskWithZoneAllocation(
- (i + 1), isolate, &threads[i], &sync, &monitor, &done_count, &wait));
+ Dart::thread_pool()->Run<SimpleTaskWithZoneAllocation>(
+ (i + 1), isolate, &threads[i], &sync, &monitor, &done_count, &wait);
}
// Wait until all spawned tasks finish their memory operations.
{
@@ -497,8 +497,8 @@
}
for (int i = 0; i < ICDataTestTask::kTaskCount; i++) {
- Dart::thread_pool()->Run(
- new ICDataTestTask(isolate, ic_datas, &monitor, &exited, &done));
+ Dart::thread_pool()->Run<ICDataTestTask>(isolate, ic_datas, &monitor,
+ &exited, &done);
}
for (int i = 0; i < 0x10000; i++) {
@@ -630,8 +630,8 @@
intptr_t total_done = 0;
intptr_t exited = 0;
for (int i = 0; i < SafepointTestTask::kTaskCount; i++) {
- Dart::thread_pool()->Run(new SafepointTestTask(
- isolate, &monitor, &expected_count, &total_done, &exited));
+ Dart::thread_pool()->Run<SafepointTestTask>(
+ isolate, &monitor, &expected_count, &total_done, &exited);
}
// Run Dart code on the main thread long enough to allow all helpers
// to get their verification done and exit. Use a specific UserTag
@@ -681,8 +681,8 @@
intptr_t total_done = 0;
intptr_t exited = 0;
for (int i = 0; i < SafepointTestTask::kTaskCount; i++) {
- Dart::thread_pool()->Run(new SafepointTestTask(
- isolate, &monitor, &expected_count, &total_done, &exited));
+ Dart::thread_pool()->Run<SafepointTestTask>(
+ isolate, &monitor, &expected_count, &total_done, &exited);
}
String& label = String::Handle(String::New("foo"));
UserTag& tag = UserTag::Handle(UserTag::New(label));
@@ -802,8 +802,8 @@
intptr_t total_done = 0;
intptr_t exited = 0;
for (int i = 0; i < SafepointTestTask::kTaskCount; i++) {
- Dart::thread_pool()->Run(new SafepointTestTask(
- isolate, &monitor, &expected_count, &total_done, &exited));
+ Dart::thread_pool()->Run<SafepointTestTask>(
+ isolate, &monitor, &expected_count, &total_done, &exited);
}
bool all_helpers = false;
do {
@@ -833,8 +833,8 @@
intptr_t total_done = 0;
intptr_t exited = 0;
for (int i = 0; i < SafepointTestTask::kTaskCount; i++) {
- Dart::thread_pool()->Run(new SafepointTestTask(
- isolate, &monitor, &expected_count, &total_done, &exited));
+ Dart::thread_pool()->Run<SafepointTestTask>(
+ isolate, &monitor, &expected_count, &total_done, &exited);
}
bool all_helpers = false;
do {
@@ -899,7 +899,7 @@
Monitor done_monitor;
bool done = false;
Isolate* isolate = thread->isolate();
- Dart::thread_pool()->Run(new AllocAndGCTask(isolate, &done_monitor, &done));
+ Dart::thread_pool()->Run<AllocAndGCTask>(isolate, &done_monitor, &done);
{
while (true) {
TransitionVMToBlocked transition(thread);
@@ -951,8 +951,8 @@
Isolate* isolate = thread->isolate();
for (int i = 0; i < NUMBER_TEST_THREADS; i++) {
done[i] = false;
- Dart::thread_pool()->Run(
- new AllocateGlobsOfMemoryTask(isolate, &done_monitor[i], &done[i]));
+ Dart::thread_pool()->Run<AllocateGlobsOfMemoryTask>(
+ isolate, &done_monitor[i], &done[i]);
}
for (int i = 0; i < NUMBER_TEST_THREADS; i++) {