Commit 1e0d18dc authored by Etienne Pierre-doray's avatar Etienne Pierre-doray Committed by V8 LUCI CQ

[task] Expose CreateJob in v8::Platform

CreateJob() is similar to PostJob() but doesn't schedule anything
until Join() or Notify*() is called.
This allows
- CreateJob().Join() without too many worker.
- Early 'empty' CreateJob() for initialization
  without causing spurious calls to GetMaxConcurrency()

Bug: chromium:1287665
Change-Id: I8fd8b139392ad30218f0cf8f580b2d76f1078777
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3668842Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Etienne Pierre-Doray <etiennep@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81166}
parent 8bd3a441
......@@ -1056,17 +1056,33 @@ class Platform {
* thread (A=>B/B=>A deadlock) and [2] JobTask::Run or
* JobTask::GetMaxConcurrency may be invoked synchronously from JobHandle
* (B=>JobHandle::foo=>B deadlock).
*/
virtual std::unique_ptr<JobHandle> PostJob(
TaskPriority priority, std::unique_ptr<JobTask> job_task) {
auto handle = CreateJob(priority, std::move(job_task));
handle->NotifyConcurrencyIncrease();
return handle;
}
/**
* Creates and returns a JobHandle associated with a Job. Unlike PostJob(),
* this doesn't immediately schedules |worker_task| to run; the Job is then
* scheduled by calling either NotifyConcurrencyIncrease() or Join().
*
* A sufficient PostJob() implementation that uses the default Job provided in
* libplatform looks like:
* std::unique_ptr<JobHandle> PostJob(
* A sufficient CreateJob() implementation that uses the default Job provided
* in libplatform looks like:
* std::unique_ptr<JobHandle> CreateJob(
* TaskPriority priority, std::unique_ptr<JobTask> job_task) override {
* return v8::platform::NewDefaultJobHandle(
* this, priority, std::move(job_task), NumberOfWorkerThreads());
* }
*
* TODO(etiennep): Make pure virtual once custom embedders implement it.
*/
virtual std::unique_ptr<JobHandle> PostJob(
TaskPriority priority, std::unique_ptr<JobTask> job_task) = 0;
virtual std::unique_ptr<JobHandle> CreateJob(
TaskPriority priority, std::unique_ptr<JobTask> job_task) {
return nullptr;
}
/**
* Monotonically increasing time in seconds from an arbitrary fixed point in
......
......@@ -77,6 +77,16 @@ class PredictablePlatform final : public Platform {
TaskPriority priority, std::unique_ptr<JobTask> job_task) override {
// Do not call {platform_->PostJob} here, as this would create a job that
// posts tasks directly to the underlying default platform.
std::unique_ptr<JobHandle> handle =
CreateJob(priority, std::move(job_task));
handle->NotifyConcurrencyIncrease();
return handle;
}
std::unique_ptr<JobHandle> CreateJob(
TaskPriority priority, std::unique_ptr<JobTask> job_task) override {
// Do not call {platform_->PostJob} here, as this would create a job that
// posts tasks directly to the underlying default platform.
return platform::NewDefaultJobHandle(this, priority, std::move(job_task),
NumberOfWorkerThreads());
}
......@@ -190,6 +200,11 @@ class DelayedTasksPlatform final : public Platform {
return platform_->PostJob(priority, MakeDelayedJob(std::move(job_task)));
}
std::unique_ptr<JobHandle> CreateJob(
TaskPriority priority, std::unique_ptr<JobTask> job_task) override {
return platform_->CreateJob(priority, MakeDelayedJob(std::move(job_task)));
}
double MonotonicallyIncreasingTime() override {
return platform_->MonotonicallyIncreasingTime();
}
......
......@@ -214,9 +214,7 @@ void DefaultJobState::UpdatePriority(TaskPriority priority) {
}
DefaultJobHandle::DefaultJobHandle(std::shared_ptr<DefaultJobState> state)
: state_(std::move(state)) {
state_->NotifyConcurrencyIncrease();
}
: state_(std::move(state)) {}
DefaultJobHandle::~DefaultJobHandle() { DCHECK_EQ(nullptr, state_); }
......
......@@ -229,6 +229,13 @@ bool DefaultPlatform::IdleTasksEnabled(Isolate* isolate) {
std::unique_ptr<JobHandle> DefaultPlatform::PostJob(
TaskPriority priority, std::unique_ptr<JobTask> job_task) {
std::unique_ptr<JobHandle> handle = CreateJob(priority, std::move(job_task));
handle->NotifyConcurrencyIncrease();
return handle;
}
std::unique_ptr<JobHandle> DefaultPlatform::CreateJob(
TaskPriority priority, std::unique_ptr<JobTask> job_task) {
size_t num_worker_threads = NumberOfWorkerThreads();
if (priority == TaskPriority::kBestEffort && num_worker_threads > 2) {
num_worker_threads = 2;
......
......@@ -63,6 +63,8 @@ class V8_PLATFORM_EXPORT DefaultPlatform : public NON_EXPORTED_BASE(Platform) {
bool IdleTasksEnabled(Isolate* isolate) override;
std::unique_ptr<JobHandle> PostJob(
TaskPriority priority, std::unique_ptr<JobTask> job_state) override;
std::unique_ptr<JobHandle> CreateJob(
TaskPriority priority, std::unique_ptr<JobTask> job_state) override;
double MonotonicallyIncreasingTime() override;
double CurrentClockTimeMillis() override;
v8::TracingController* GetTracingController() override;
......
......@@ -498,6 +498,11 @@ std::unique_ptr<v8::JobHandle> TestPlatform::PostJob(
return CcTest::default_platform()->PostJob(priority, std::move(job_task));
}
std::unique_ptr<v8::JobHandle> TestPlatform::CreateJob(
v8::TaskPriority priority, std::unique_ptr<v8::JobTask> job_task) {
return CcTest::default_platform()->CreateJob(priority, std::move(job_task));
}
double TestPlatform::MonotonicallyIncreasingTime() {
return CcTest::default_platform()->MonotonicallyIncreasingTime();
}
......
......@@ -731,6 +731,9 @@ class TestPlatform : public v8::Platform {
std::unique_ptr<v8::JobHandle> PostJob(
v8::TaskPriority priority,
std::unique_ptr<v8::JobTask> job_task) override;
std::unique_ptr<v8::JobHandle> CreateJob(
v8::TaskPriority priority,
std::unique_ptr<v8::JobTask> job_task) override;
double MonotonicallyIncreasingTime() override;
double CurrentClockTimeMillis() override;
bool IdleTasksEnabled(v8::Isolate* isolate) override;
......
......@@ -37,6 +37,14 @@ class MockPlatform final : public TestPlatform {
std::unique_ptr<v8::JobHandle> PostJob(
v8::TaskPriority priority,
std::unique_ptr<v8::JobTask> job_task) override {
auto job_handle = CreateJob(priority, std::move(job_task));
job_handle->NotifyConcurrencyIncrease();
return job_handle;
}
std::unique_ptr<v8::JobHandle> CreateJob(
v8::TaskPriority priority,
std::unique_ptr<v8::JobTask> job_task) override {
auto orig_job_handle = v8::platform::NewDefaultJobHandle(
this, priority, std::move(job_task), 1);
auto job_handle =
......
......@@ -34,6 +34,14 @@ class MockPlatform final : public TestPlatform {
std::unique_ptr<v8::JobHandle> PostJob(
v8::TaskPriority priority,
std::unique_ptr<v8::JobTask> job_task) override {
auto job_handle = CreateJob(priority, std::move(job_task));
job_handle->NotifyConcurrencyIncrease();
return job_handle;
}
std::unique_ptr<v8::JobHandle> CreateJob(
v8::TaskPriority priority,
std::unique_ptr<v8::JobTask> job_task) override {
auto orig_job_handle = v8::platform::NewDefaultJobHandle(
this, priority, std::move(job_task), 1);
auto job_handle =
......
......@@ -106,8 +106,7 @@ class DeferredPostJob {
if (real_handle()) {
real_handle()->NotifyConcurrencyIncrease();
}
// No need to defer the NotifyConcurrencyIncrease, we'll automatically
// check concurrency when posting the job.
owner_->NotifyConcurrencyIncrease();
}
void Cancel() final {
set_cancelled();
......@@ -137,7 +136,7 @@ class DeferredPostJob {
if (deferred_handle_) deferred_handle_->ClearOwner();
}
std::unique_ptr<JobHandle> DeferPostJob(TaskPriority priority,
std::unique_ptr<JobHandle> CreateJob(TaskPriority priority,
std::unique_ptr<JobTask> job_task) {
DCHECK_NULL(job_task_);
job_task_ = std::move(job_task);
......@@ -145,12 +144,17 @@ class DeferredPostJob {
return std::make_unique<DeferredJobHandle>(this);
}
void NotifyConcurrencyIncrease() { do_post_ = true; }
bool IsPending() { return job_task_ != nullptr; }
void Clear() { job_task_.reset(); }
void DoRealPostJob(Platform* platform) {
if (do_post_)
real_handle_ = platform->PostJob(priority_, std::move(job_task_));
else
real_handle_ = platform->CreateJob(priority_, std::move(job_task_));
if (was_cancelled_) {
real_handle_->Cancel();
}
......@@ -180,6 +184,7 @@ class DeferredPostJob {
std::unique_ptr<JobHandle> real_handle_ = nullptr;
bool was_cancelled_ = false;
bool do_post_ = false;
};
class MockPlatform : public v8::Platform {
......@@ -217,7 +222,14 @@ class MockPlatform : public v8::Platform {
std::unique_ptr<JobHandle> PostJob(
TaskPriority priority, std::unique_ptr<JobTask> job_task) override {
return deferred_post_job_.DeferPostJob(priority, std::move(job_task));
auto handle = deferred_post_job_.CreateJob(priority, std::move(job_task));
deferred_post_job_.NotifyConcurrencyIncrease();
return handle;
}
std::unique_ptr<JobHandle> CreateJob(
TaskPriority priority, std::unique_ptr<JobTask> job_task) override {
return deferred_post_job_.CreateJob(priority, std::move(job_task));
}
double MonotonicallyIncreasingTime() override {
......
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