v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
default-job.h
Go to the documentation of this file.
1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_LIBPLATFORM_DEFAULT_JOB_H_
6#define V8_LIBPLATFORM_DEFAULT_JOB_H_
7
8#include <atomic>
9#include <memory>
10
12#include "include/v8-platform.h"
15
16namespace v8 {
17namespace platform {
18
20 : public std::enable_shared_from_this<DefaultJobState> {
21 public:
23 public:
24 explicit JobDelegate(DefaultJobState* outer, bool is_joining_thread = false)
25 : outer_(outer), is_joining_thread_(is_joining_thread) {}
27
28 void NotifyConcurrencyIncrease() override {
29 outer_->NotifyConcurrencyIncrease();
30 }
31 bool ShouldYield() override {
32 // After {ShouldYield} returned true, the job is expected to return and
33 // not call {ShouldYield} again. This resembles a similar DCHECK in the
34 // gin platform.
35 DCHECK(!was_told_to_yield_);
36 // Thread-safe but may return an outdated result.
37 was_told_to_yield_ |=
38 outer_->is_canceled_.load(std::memory_order_relaxed);
39 return was_told_to_yield_;
40 }
41 uint8_t GetTaskId() override;
42 bool IsJoiningThread() const override { return is_joining_thread_; }
43
44 private:
45 static constexpr uint8_t kInvalidTaskId =
46 std::numeric_limits<uint8_t>::max();
47
49 uint8_t task_id_ = kInvalidTaskId;
51 bool was_told_to_yield_ = false;
52 };
53
54 DefaultJobState(Platform* platform, std::unique_ptr<JobTask> job_task,
55 TaskPriority priority, size_t num_worker_threads);
56 virtual ~DefaultJobState();
57
58 void NotifyConcurrencyIncrease();
59 uint8_t AcquireTaskId();
60 void ReleaseTaskId(uint8_t task_id);
61
62 void Join();
63 void CancelAndWait();
64 void CancelAndDetach();
65 bool IsActive();
66
67 // Must be called before running |job_task_| for the first time. If it returns
68 // true, then the worker thread must contribute and must call DidRunTask(), or
69 // false if it should return.
70 bool CanRunFirstTask();
71 // Must be called after running |job_task_|. Returns true if the worker thread
72 // must contribute again, or false if it should return.
73 bool DidRunTask();
74
75 void UpdatePriority(TaskPriority);
76
77 private:
78 // Returns GetMaxConcurrency() capped by the number of threads used by this
79 // job.
80 size_t CappedMaxConcurrency(size_t worker_count) const;
81
82 void CallOnWorkerThread(TaskPriority priority, std::unique_ptr<Task> task);
83
85 std::unique_ptr<JobTask> job_task_;
86
87 // All members below are protected by |mutex_|.
90 // Number of workers running this job.
91 size_t active_workers_ = 0;
92 // Number of posted tasks that aren't running this job yet.
93 size_t pending_tasks_ = 0;
94 // Indicates if the job is canceled.
95 std::atomic_bool is_canceled_{false};
96 // Number of worker threads available to schedule the worker task.
98 // Signaled when a worker returns.
100
101 std::atomic<uint32_t> assigned_task_ids_{0};
102};
103
105 public:
106 explicit DefaultJobHandle(std::shared_ptr<DefaultJobState> state);
107 ~DefaultJobHandle() override;
108
111
113 state_->NotifyConcurrencyIncrease();
114 }
115
116 void Join() override;
117 void Cancel() override;
118 void CancelAndDetach() override;
119 bool IsActive() override;
120 bool IsValid() override { return state_ != nullptr; }
121
122 bool UpdatePriorityEnabled() const override { return true; }
123
124 void UpdatePriority(TaskPriority) override;
125
126 private:
127 std::shared_ptr<DefaultJobState> state_;
128};
129
130class DefaultJobWorker : public Task {
131 public:
132 DefaultJobWorker(std::weak_ptr<DefaultJobState> state, JobTask* job_task)
133 : state_(std::move(state)), job_task_(job_task) {}
134 ~DefaultJobWorker() override = default;
135
138
139 void Run() override {
140 auto shared_state = state_.lock();
141 if (!shared_state) return;
142 if (!shared_state->CanRunFirstTask()) return;
143 do {
144 // Scope of |delegate| must not outlive DidRunTask() so that associated
145 // state is freed before the worker becomes inactive.
146 DefaultJobState::JobDelegate delegate(shared_state.get());
147 job_task_->Run(&delegate);
148 } while (shared_state->DidRunTask());
149 }
150
151 private:
152 friend class DefaultJob;
153
154 std::weak_ptr<DefaultJobState> state_;
156};
157
158} // namespace platform
159} // namespace v8
160
161#endif // V8_LIBPLATFORM_DEFAULT_JOB_H_
virtual void Run(JobDelegate *delegate)=0
DefaultJobHandle & operator=(const DefaultJobHandle &)=delete
void NotifyConcurrencyIncrease() override
bool UpdatePriorityEnabled() const override
std::shared_ptr< DefaultJobState > state_
DefaultJobHandle(const DefaultJobHandle &)=delete
JobDelegate(DefaultJobState *outer, bool is_joining_thread=false)
Definition default-job.h:24
std::unique_ptr< JobTask > job_task_
Definition default-job.h:85
base::ConditionVariable worker_released_condition_
Definition default-job.h:99
DefaultJobWorker(std::weak_ptr< DefaultJobState > state, JobTask *job_task)
std::weak_ptr< DefaultJobState > state_
DefaultJobWorker & operator=(const DefaultJobWorker &)=delete
DefaultJobWorker(const DefaultJobWorker &)=delete
~DefaultJobWorker() override=default
enum v8::internal::@1270::DeoptimizableCodeIterator::@67 state_
#define V8_PLATFORM_EXPORT
size_t priority
STL namespace.
TaskPriority
Definition v8-platform.h:24
#define DCHECK(condition)
Definition logging.h:482