6 #include <unordered_map> 8 #include "include/v8-platform.h" 9 #include "src/base/logging.h" 10 #include "src/base/macros.h" 11 #include "src/base/platform/mutex.h" 12 #include "src/base/platform/platform.h" 13 #include "src/base/platform/time.h" 14 #include "src/base/template-utils.h" 15 #include "src/base/utils/random-number-generator.h" 16 #include "src/d8-platforms.h" 23 : platform_(std::move(platform)) {
24 DCHECK_NOT_NULL(platform_);
28 return platform_->GetPageAllocator();
32 platform_->OnCriticalMemoryPressure();
36 return platform_->OnCriticalMemoryPressure(length);
40 v8::Isolate* isolate)
override {
41 return platform_->GetForegroundTaskRunner(isolate);
53 double delay_in_seconds)
override {
57 void CallOnForegroundThread(v8::Isolate* isolate,
Task* task)
override {
62 void CallDelayedOnForegroundThread(v8::Isolate* isolate, Task* task,
63 double delay_in_seconds)
override {
68 void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task)
override {
75 return synthetic_time_in_sec_ += 0.00001;
83 return platform_->GetTracingController();
86 Platform* platform()
const {
return platform_.get(); }
89 double synthetic_time_in_sec_ = 0.0;
90 std::unique_ptr<Platform> platform_;
92 DISALLOW_COPY_AND_ASSIGN(PredictablePlatform);
95 std::unique_ptr<Platform> MakePredictablePlatform(
96 std::unique_ptr<Platform> platform) {
97 return base::make_unique<PredictablePlatform>(std::move(platform));
103 : platform_(std::move(platform)) {
104 DCHECK_NOT_NULL(platform_);
109 : platform_(std::move(platform)), rng_(random_seed) {
110 DCHECK_NOT_NULL(platform_);
115 DCHECK_EQ(0, delayed_task_runners_.size());
119 return platform_->GetPageAllocator();
123 platform_->OnCriticalMemoryPressure();
127 return platform_->OnCriticalMemoryPressure(length);
131 v8::Isolate* isolate)
override {
132 std::shared_ptr<TaskRunner> runner =
133 platform_->GetForegroundTaskRunner(isolate);
135 base::MutexGuard lock_guard(&mutex_);
137 std::weak_ptr<DelayedTaskRunner>& weak_delayed_runner =
138 delayed_task_runners_[runner.get()];
139 std::shared_ptr<DelayedTaskRunner> delayed_runner =
140 weak_delayed_runner.lock();
142 if (!delayed_runner) {
144 delayed_runner.reset(
new DelayedTaskRunner(runner,
this),
145 DelayedTaskRunnerDeleter{});
146 weak_delayed_runner = delayed_runner;
149 return std::move(delayed_runner);
153 return platform_->NumberOfWorkerThreads();
157 platform_->CallOnWorkerThread(MakeDelayedTask(std::move(task)));
161 double delay_in_seconds)
override {
162 platform_->CallDelayedOnWorkerThread(MakeDelayedTask(std::move(task)),
166 void CallOnForegroundThread(v8::Isolate* isolate,
Task* task)
override {
171 void CallDelayedOnForegroundThread(v8::Isolate* isolate, Task* task,
172 double delay_in_seconds)
override {
177 void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task)
override {
183 return platform_->IdleTasksEnabled(isolate);
187 return platform_->MonotonicallyIncreasingTime();
191 return platform_->CurrentClockTimeMillis();
195 return platform_->GetTracingController();
199 class DelayedTaskRunnerDeleter;
200 class DelayedTaskRunner final :
public TaskRunner {
202 DelayedTaskRunner(std::shared_ptr<TaskRunner> task_runner,
204 : task_runner_(task_runner), platform_(platform) {}
206 void PostTask(std::unique_ptr<Task> task)
final {
207 task_runner_->PostTask(platform_->MakeDelayedTask(std::move(task)));
210 void PostDelayedTask(std::unique_ptr<Task> task,
211 double delay_in_seconds)
final {
212 task_runner_->PostDelayedTask(platform_->MakeDelayedTask(std::move(task)),
216 void PostIdleTask(std::unique_ptr<IdleTask> task)
final {
217 task_runner_->PostIdleTask(
218 platform_->MakeDelayedIdleTask(std::move(task)));
224 friend class DelayedTaskRunnerDeleter;
225 std::shared_ptr<TaskRunner> task_runner_;
226 DelayedTasksPlatform* platform_;
229 class DelayedTaskRunnerDeleter {
231 void operator()(DelayedTaskRunner* runner)
const {
232 TaskRunner* original_runner = runner->task_runner_.get();
233 base::MutexGuard lock_guard(&runner->platform_->mutex_);
234 auto& delayed_task_runners = runner->platform_->delayed_task_runners_;
235 DCHECK_EQ(1, delayed_task_runners.count(original_runner));
236 delayed_task_runners.erase(original_runner);
240 class DelayedTask :
public Task {
242 DelayedTask(std::unique_ptr<Task> task, int32_t delay_ms)
243 : task_(
std::move(task)), delay_ms_(delay_ms) {}
245 base::OS::Sleep(base::TimeDelta::FromMicroseconds(delay_ms_));
250 std::unique_ptr<Task> task_;
254 class DelayedIdleTask :
public IdleTask {
256 DelayedIdleTask(std::unique_ptr<IdleTask> task, int32_t delay_ms)
257 : task_(
std::move(task)), delay_ms_(delay_ms) {}
258 void Run(
double deadline_in_seconds)
final {
259 base::OS::Sleep(base::TimeDelta::FromMicroseconds(delay_ms_));
260 task_->Run(deadline_in_seconds);
264 std::unique_ptr<IdleTask> task_;
268 std::unique_ptr<Platform> platform_;
274 base::RandomNumberGenerator rng_;
275 std::unordered_map<TaskRunner*, std::weak_ptr<DelayedTaskRunner>>
276 delayed_task_runners_;
278 int32_t GetRandomDelayInMilliseconds() {
279 base::MutexGuard lock_guard(&mutex_);
280 double delay_fraction = rng_.NextDouble();
283 return 1e5 * (delay_fraction * delay_fraction);
286 std::unique_ptr<Task> MakeDelayedTask(std::unique_ptr<Task> task) {
287 return base::make_unique<DelayedTask>(std::move(task),
288 GetRandomDelayInMilliseconds());
291 std::unique_ptr<IdleTask> MakeDelayedIdleTask(
292 std::unique_ptr<IdleTask> task) {
293 return base::make_unique<DelayedIdleTask>(std::move(task),
294 GetRandomDelayInMilliseconds());
297 DISALLOW_COPY_AND_ASSIGN(DelayedTasksPlatform);
300 std::unique_ptr<Platform> MakeDelayedTasksPlatform(
301 std::unique_ptr<Platform> platform,
int64_t random_seed) {
303 return base::make_unique<DelayedTasksPlatform>(std::move(platform),
306 return base::make_unique<DelayedTasksPlatform>(std::move(platform));