11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/d8/d8-platforms.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <memory>
81cb0ef41Sopenharmony_ci#include <unordered_map>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include "include/libplatform/libplatform.h"
111cb0ef41Sopenharmony_ci#include "include/v8-platform.h"
121cb0ef41Sopenharmony_ci#include "src/base/logging.h"
131cb0ef41Sopenharmony_ci#include "src/base/macros.h"
141cb0ef41Sopenharmony_ci#include "src/base/platform/mutex.h"
151cb0ef41Sopenharmony_ci#include "src/base/platform/platform.h"
161cb0ef41Sopenharmony_ci#include "src/base/platform/time.h"
171cb0ef41Sopenharmony_ci#include "src/base/utils/random-number-generator.h"
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_cinamespace v8 {
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ciclass PredictablePlatform final : public Platform {
221cb0ef41Sopenharmony_ci public:
231cb0ef41Sopenharmony_ci  explicit PredictablePlatform(std::unique_ptr<Platform> platform)
241cb0ef41Sopenharmony_ci      : platform_(std::move(platform)) {
251cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(platform_);
261cb0ef41Sopenharmony_ci  }
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci  PredictablePlatform(const PredictablePlatform&) = delete;
291cb0ef41Sopenharmony_ci  PredictablePlatform& operator=(const PredictablePlatform&) = delete;
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci  PageAllocator* GetPageAllocator() override {
321cb0ef41Sopenharmony_ci    return platform_->GetPageAllocator();
331cb0ef41Sopenharmony_ci  }
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  void OnCriticalMemoryPressure() override {
361cb0ef41Sopenharmony_ci    platform_->OnCriticalMemoryPressure();
371cb0ef41Sopenharmony_ci  }
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  bool OnCriticalMemoryPressure(size_t length) override {
401cb0ef41Sopenharmony_ci    return platform_->OnCriticalMemoryPressure(length);
411cb0ef41Sopenharmony_ci  }
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  std::shared_ptr<TaskRunner> GetForegroundTaskRunner(
441cb0ef41Sopenharmony_ci      v8::Isolate* isolate) override {
451cb0ef41Sopenharmony_ci    return platform_->GetForegroundTaskRunner(isolate);
461cb0ef41Sopenharmony_ci  }
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  int NumberOfWorkerThreads() override {
491cb0ef41Sopenharmony_ci    // The predictable platform executes everything on the main thread, but we
501cb0ef41Sopenharmony_ci    // still pretend to have the default number of worker threads to not
511cb0ef41Sopenharmony_ci    // unnecessarily change behaviour of the platform.
521cb0ef41Sopenharmony_ci    return platform_->NumberOfWorkerThreads();
531cb0ef41Sopenharmony_ci  }
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  void CallOnWorkerThread(std::unique_ptr<Task> task) override {
561cb0ef41Sopenharmony_ci    // We post worker tasks on the foreground task runner of the
571cb0ef41Sopenharmony_ci    // {kProcessGlobalPredictablePlatformWorkerTaskQueue} isolate. The task
581cb0ef41Sopenharmony_ci    // queue of the {kProcessGlobalPredictablePlatformWorkerTaskQueue} isolate
591cb0ef41Sopenharmony_ci    // is then executed on the main thread to achieve predictable behavior.
601cb0ef41Sopenharmony_ci    //
611cb0ef41Sopenharmony_ci    // In this context here it is okay to call {GetForegroundTaskRunner} from a
621cb0ef41Sopenharmony_ci    // background thread. The reason is that code is executed sequentially with
631cb0ef41Sopenharmony_ci    // the PredictablePlatform, and that the {DefaultPlatform} does not access
641cb0ef41Sopenharmony_ci    // the isolate but only uses it as the key in a HashMap.
651cb0ef41Sopenharmony_ci    GetForegroundTaskRunner(kProcessGlobalPredictablePlatformWorkerTaskQueue)
661cb0ef41Sopenharmony_ci        ->PostTask(std::move(task));
671cb0ef41Sopenharmony_ci  }
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  void CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
701cb0ef41Sopenharmony_ci                                 double delay_in_seconds) override {
711cb0ef41Sopenharmony_ci    // Never run delayed tasks.
721cb0ef41Sopenharmony_ci  }
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  bool IdleTasksEnabled(Isolate* isolate) override { return false; }
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci  std::unique_ptr<JobHandle> PostJob(
771cb0ef41Sopenharmony_ci      TaskPriority priority, std::unique_ptr<JobTask> job_task) override {
781cb0ef41Sopenharmony_ci    // Do not call {platform_->PostJob} here, as this would create a job that
791cb0ef41Sopenharmony_ci    // posts tasks directly to the underlying default platform.
801cb0ef41Sopenharmony_ci    return platform::NewDefaultJobHandle(this, priority, std::move(job_task),
811cb0ef41Sopenharmony_ci                                         NumberOfWorkerThreads());
821cb0ef41Sopenharmony_ci  }
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  double MonotonicallyIncreasingTime() override {
851cb0ef41Sopenharmony_ci    // In predictable mode, there should be no (observable) concurrency, but we
861cb0ef41Sopenharmony_ci    // still run some tests that explicitly specify '--predictable' in the
871cb0ef41Sopenharmony_ci    // '--isolates' variant, where several threads run the same test in
881cb0ef41Sopenharmony_ci    // different isolates. To avoid TSan issues in that scenario we use atomic
891cb0ef41Sopenharmony_ci    // increments here.
901cb0ef41Sopenharmony_ci    uint64_t synthetic_time =
911cb0ef41Sopenharmony_ci        synthetic_time_.fetch_add(1, std::memory_order_relaxed);
921cb0ef41Sopenharmony_ci    return 1e-5 * synthetic_time;
931cb0ef41Sopenharmony_ci  }
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  double CurrentClockTimeMillis() override {
961cb0ef41Sopenharmony_ci    return MonotonicallyIncreasingTime() * base::Time::kMillisecondsPerSecond;
971cb0ef41Sopenharmony_ci  }
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci  v8::TracingController* GetTracingController() override {
1001cb0ef41Sopenharmony_ci    return platform_->GetTracingController();
1011cb0ef41Sopenharmony_ci  }
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci  Platform* platform() const { return platform_.get(); }
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci private:
1061cb0ef41Sopenharmony_ci  std::atomic<uint64_t> synthetic_time_{0};
1071cb0ef41Sopenharmony_ci  std::unique_ptr<Platform> platform_;
1081cb0ef41Sopenharmony_ci};
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_cistd::unique_ptr<Platform> MakePredictablePlatform(
1111cb0ef41Sopenharmony_ci    std::unique_ptr<Platform> platform) {
1121cb0ef41Sopenharmony_ci  return std::make_unique<PredictablePlatform>(std::move(platform));
1131cb0ef41Sopenharmony_ci}
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ciclass DelayedTasksPlatform final : public Platform {
1161cb0ef41Sopenharmony_ci public:
1171cb0ef41Sopenharmony_ci  explicit DelayedTasksPlatform(std::unique_ptr<Platform> platform)
1181cb0ef41Sopenharmony_ci      : platform_(std::move(platform)) {
1191cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(platform_);
1201cb0ef41Sopenharmony_ci  }
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  explicit DelayedTasksPlatform(std::unique_ptr<Platform> platform,
1231cb0ef41Sopenharmony_ci                                int64_t random_seed)
1241cb0ef41Sopenharmony_ci      : platform_(std::move(platform)), rng_(random_seed) {
1251cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(platform_);
1261cb0ef41Sopenharmony_ci  }
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  DelayedTasksPlatform(const DelayedTasksPlatform&) = delete;
1291cb0ef41Sopenharmony_ci  DelayedTasksPlatform& operator=(const DelayedTasksPlatform&) = delete;
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  ~DelayedTasksPlatform() override {
1321cb0ef41Sopenharmony_ci    // When the platform shuts down, all task runners must be freed.
1331cb0ef41Sopenharmony_ci    DCHECK_EQ(0, delayed_task_runners_.size());
1341cb0ef41Sopenharmony_ci  }
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  PageAllocator* GetPageAllocator() override {
1371cb0ef41Sopenharmony_ci    return platform_->GetPageAllocator();
1381cb0ef41Sopenharmony_ci  }
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  void OnCriticalMemoryPressure() override {
1411cb0ef41Sopenharmony_ci    platform_->OnCriticalMemoryPressure();
1421cb0ef41Sopenharmony_ci  }
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci  bool OnCriticalMemoryPressure(size_t length) override {
1451cb0ef41Sopenharmony_ci    return platform_->OnCriticalMemoryPressure(length);
1461cb0ef41Sopenharmony_ci  }
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci  std::shared_ptr<TaskRunner> GetForegroundTaskRunner(
1491cb0ef41Sopenharmony_ci      v8::Isolate* isolate) override {
1501cb0ef41Sopenharmony_ci    std::shared_ptr<TaskRunner> runner =
1511cb0ef41Sopenharmony_ci        platform_->GetForegroundTaskRunner(isolate);
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci    base::MutexGuard lock_guard(&mutex_);
1541cb0ef41Sopenharmony_ci    // Check if we can re-materialize the weak ptr in our map.
1551cb0ef41Sopenharmony_ci    std::weak_ptr<DelayedTaskRunner>& weak_delayed_runner =
1561cb0ef41Sopenharmony_ci        delayed_task_runners_[runner.get()];
1571cb0ef41Sopenharmony_ci    std::shared_ptr<DelayedTaskRunner> delayed_runner =
1581cb0ef41Sopenharmony_ci        weak_delayed_runner.lock();
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci    if (!delayed_runner) {
1611cb0ef41Sopenharmony_ci      // Create a new {DelayedTaskRunner} and keep a weak reference in our map.
1621cb0ef41Sopenharmony_ci      delayed_runner.reset(new DelayedTaskRunner(runner, this),
1631cb0ef41Sopenharmony_ci                           DelayedTaskRunnerDeleter{});
1641cb0ef41Sopenharmony_ci      weak_delayed_runner = delayed_runner;
1651cb0ef41Sopenharmony_ci    }
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci    return std::move(delayed_runner);
1681cb0ef41Sopenharmony_ci  }
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci  int NumberOfWorkerThreads() override {
1711cb0ef41Sopenharmony_ci    return platform_->NumberOfWorkerThreads();
1721cb0ef41Sopenharmony_ci  }
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci  void CallOnWorkerThread(std::unique_ptr<Task> task) override {
1751cb0ef41Sopenharmony_ci    platform_->CallOnWorkerThread(MakeDelayedTask(std::move(task)));
1761cb0ef41Sopenharmony_ci  }
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_ci  void CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
1791cb0ef41Sopenharmony_ci                                 double delay_in_seconds) override {
1801cb0ef41Sopenharmony_ci    platform_->CallDelayedOnWorkerThread(MakeDelayedTask(std::move(task)),
1811cb0ef41Sopenharmony_ci                                         delay_in_seconds);
1821cb0ef41Sopenharmony_ci  }
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci  bool IdleTasksEnabled(Isolate* isolate) override {
1851cb0ef41Sopenharmony_ci    return platform_->IdleTasksEnabled(isolate);
1861cb0ef41Sopenharmony_ci  }
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci  std::unique_ptr<JobHandle> PostJob(
1891cb0ef41Sopenharmony_ci      TaskPriority priority, std::unique_ptr<JobTask> job_task) override {
1901cb0ef41Sopenharmony_ci    return platform_->PostJob(priority, MakeDelayedJob(std::move(job_task)));
1911cb0ef41Sopenharmony_ci  }
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ci  double MonotonicallyIncreasingTime() override {
1941cb0ef41Sopenharmony_ci    return platform_->MonotonicallyIncreasingTime();
1951cb0ef41Sopenharmony_ci  }
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci  double CurrentClockTimeMillis() override {
1981cb0ef41Sopenharmony_ci    return platform_->CurrentClockTimeMillis();
1991cb0ef41Sopenharmony_ci  }
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ci  v8::TracingController* GetTracingController() override {
2021cb0ef41Sopenharmony_ci    return platform_->GetTracingController();
2031cb0ef41Sopenharmony_ci  }
2041cb0ef41Sopenharmony_ci
2051cb0ef41Sopenharmony_ci private:
2061cb0ef41Sopenharmony_ci  class DelayedTaskRunnerDeleter;
2071cb0ef41Sopenharmony_ci  class DelayedTaskRunner final : public TaskRunner {
2081cb0ef41Sopenharmony_ci   public:
2091cb0ef41Sopenharmony_ci    DelayedTaskRunner(std::shared_ptr<TaskRunner> task_runner,
2101cb0ef41Sopenharmony_ci                      DelayedTasksPlatform* platform)
2111cb0ef41Sopenharmony_ci        : task_runner_(task_runner), platform_(platform) {}
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_ci    void PostTask(std::unique_ptr<Task> task) final {
2141cb0ef41Sopenharmony_ci      task_runner_->PostTask(platform_->MakeDelayedTask(std::move(task)));
2151cb0ef41Sopenharmony_ci    }
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_ci    void PostNonNestableTask(std::unique_ptr<Task> task) final {
2181cb0ef41Sopenharmony_ci      task_runner_->PostNonNestableTask(
2191cb0ef41Sopenharmony_ci          platform_->MakeDelayedTask(std::move(task)));
2201cb0ef41Sopenharmony_ci    }
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_ci    void PostDelayedTask(std::unique_ptr<Task> task,
2231cb0ef41Sopenharmony_ci                         double delay_in_seconds) final {
2241cb0ef41Sopenharmony_ci      task_runner_->PostDelayedTask(platform_->MakeDelayedTask(std::move(task)),
2251cb0ef41Sopenharmony_ci                                    delay_in_seconds);
2261cb0ef41Sopenharmony_ci    }
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci    void PostIdleTask(std::unique_ptr<IdleTask> task) final {
2291cb0ef41Sopenharmony_ci      task_runner_->PostIdleTask(
2301cb0ef41Sopenharmony_ci          platform_->MakeDelayedIdleTask(std::move(task)));
2311cb0ef41Sopenharmony_ci    }
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_ci    bool IdleTasksEnabled() final { return task_runner_->IdleTasksEnabled(); }
2341cb0ef41Sopenharmony_ci
2351cb0ef41Sopenharmony_ci    bool NonNestableTasksEnabled() const final {
2361cb0ef41Sopenharmony_ci      return task_runner_->NonNestableTasksEnabled();
2371cb0ef41Sopenharmony_ci    }
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ci   private:
2401cb0ef41Sopenharmony_ci    friend class DelayedTaskRunnerDeleter;
2411cb0ef41Sopenharmony_ci    std::shared_ptr<TaskRunner> task_runner_;
2421cb0ef41Sopenharmony_ci    DelayedTasksPlatform* platform_;
2431cb0ef41Sopenharmony_ci  };
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ci  class DelayedTaskRunnerDeleter {
2461cb0ef41Sopenharmony_ci   public:
2471cb0ef41Sopenharmony_ci    void operator()(DelayedTaskRunner* runner) const {
2481cb0ef41Sopenharmony_ci      TaskRunner* original_runner = runner->task_runner_.get();
2491cb0ef41Sopenharmony_ci      base::MutexGuard lock_guard(&runner->platform_->mutex_);
2501cb0ef41Sopenharmony_ci      auto& delayed_task_runners = runner->platform_->delayed_task_runners_;
2511cb0ef41Sopenharmony_ci      DCHECK_EQ(1, delayed_task_runners.count(original_runner));
2521cb0ef41Sopenharmony_ci      delayed_task_runners.erase(original_runner);
2531cb0ef41Sopenharmony_ci    }
2541cb0ef41Sopenharmony_ci  };
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ci  class DelayedTask final : public Task {
2571cb0ef41Sopenharmony_ci   public:
2581cb0ef41Sopenharmony_ci    DelayedTask(std::unique_ptr<Task> task, int32_t delay_ms)
2591cb0ef41Sopenharmony_ci        : task_(std::move(task)), delay_ms_(delay_ms) {}
2601cb0ef41Sopenharmony_ci
2611cb0ef41Sopenharmony_ci    void Run() override {
2621cb0ef41Sopenharmony_ci      base::OS::Sleep(base::TimeDelta::FromMicroseconds(delay_ms_));
2631cb0ef41Sopenharmony_ci      task_->Run();
2641cb0ef41Sopenharmony_ci    }
2651cb0ef41Sopenharmony_ci
2661cb0ef41Sopenharmony_ci   private:
2671cb0ef41Sopenharmony_ci    std::unique_ptr<Task> task_;
2681cb0ef41Sopenharmony_ci    int32_t delay_ms_;
2691cb0ef41Sopenharmony_ci  };
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_ci  class DelayedIdleTask final : public IdleTask {
2721cb0ef41Sopenharmony_ci   public:
2731cb0ef41Sopenharmony_ci    DelayedIdleTask(std::unique_ptr<IdleTask> task, int32_t delay_ms)
2741cb0ef41Sopenharmony_ci        : task_(std::move(task)), delay_ms_(delay_ms) {}
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci    void Run(double deadline_in_seconds) override {
2771cb0ef41Sopenharmony_ci      base::OS::Sleep(base::TimeDelta::FromMicroseconds(delay_ms_));
2781cb0ef41Sopenharmony_ci      task_->Run(deadline_in_seconds);
2791cb0ef41Sopenharmony_ci    }
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci   private:
2821cb0ef41Sopenharmony_ci    std::unique_ptr<IdleTask> task_;
2831cb0ef41Sopenharmony_ci    int32_t delay_ms_;
2841cb0ef41Sopenharmony_ci  };
2851cb0ef41Sopenharmony_ci
2861cb0ef41Sopenharmony_ci  class DelayedJob final : public JobTask {
2871cb0ef41Sopenharmony_ci   public:
2881cb0ef41Sopenharmony_ci    DelayedJob(std::unique_ptr<JobTask> job_task, int32_t delay_ms)
2891cb0ef41Sopenharmony_ci        : job_task_(std::move(job_task)), delay_ms_(delay_ms) {}
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ci    void Run(JobDelegate* delegate) override {
2921cb0ef41Sopenharmony_ci      // If this job is being executed via worker tasks (as e.g. the
2931cb0ef41Sopenharmony_ci      // {DefaultJobHandle} implementation does it), the worker task would
2941cb0ef41Sopenharmony_ci      // already include a delay. In order to not depend on that, we add our own
2951cb0ef41Sopenharmony_ci      // delay here anyway.
2961cb0ef41Sopenharmony_ci      base::OS::Sleep(base::TimeDelta::FromMicroseconds(delay_ms_));
2971cb0ef41Sopenharmony_ci      job_task_->Run(delegate);
2981cb0ef41Sopenharmony_ci    }
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ci    size_t GetMaxConcurrency(size_t worker_count) const override {
3011cb0ef41Sopenharmony_ci      return job_task_->GetMaxConcurrency(worker_count);
3021cb0ef41Sopenharmony_ci    }
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci   private:
3051cb0ef41Sopenharmony_ci    std::unique_ptr<JobTask> job_task_;
3061cb0ef41Sopenharmony_ci    int32_t delay_ms_;
3071cb0ef41Sopenharmony_ci  };
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_ci  std::unique_ptr<Platform> platform_;
3101cb0ef41Sopenharmony_ci
3111cb0ef41Sopenharmony_ci  // The Mutex protects the RNG, which is used by foreground and background
3121cb0ef41Sopenharmony_ci  // threads, and the {delayed_task_runners_} map might be accessed concurrently
3131cb0ef41Sopenharmony_ci  // by the shared_ptr destructor.
3141cb0ef41Sopenharmony_ci  base::Mutex mutex_;
3151cb0ef41Sopenharmony_ci  base::RandomNumberGenerator rng_;
3161cb0ef41Sopenharmony_ci  std::unordered_map<TaskRunner*, std::weak_ptr<DelayedTaskRunner>>
3171cb0ef41Sopenharmony_ci      delayed_task_runners_;
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_ci  int32_t GetRandomDelayInMilliseconds() {
3201cb0ef41Sopenharmony_ci    base::MutexGuard lock_guard(&mutex_);
3211cb0ef41Sopenharmony_ci    double delay_fraction = rng_.NextDouble();
3221cb0ef41Sopenharmony_ci    // Sleep up to 100ms (100000us). Square {delay_fraction} to shift
3231cb0ef41Sopenharmony_ci    // distribution towards shorter sleeps.
3241cb0ef41Sopenharmony_ci    return 1e5 * (delay_fraction * delay_fraction);
3251cb0ef41Sopenharmony_ci  }
3261cb0ef41Sopenharmony_ci
3271cb0ef41Sopenharmony_ci  std::unique_ptr<Task> MakeDelayedTask(std::unique_ptr<Task> task) {
3281cb0ef41Sopenharmony_ci    return std::make_unique<DelayedTask>(std::move(task),
3291cb0ef41Sopenharmony_ci                                         GetRandomDelayInMilliseconds());
3301cb0ef41Sopenharmony_ci  }
3311cb0ef41Sopenharmony_ci
3321cb0ef41Sopenharmony_ci  std::unique_ptr<IdleTask> MakeDelayedIdleTask(
3331cb0ef41Sopenharmony_ci      std::unique_ptr<IdleTask> task) {
3341cb0ef41Sopenharmony_ci    return std::make_unique<DelayedIdleTask>(std::move(task),
3351cb0ef41Sopenharmony_ci                                             GetRandomDelayInMilliseconds());
3361cb0ef41Sopenharmony_ci  }
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ci  std::unique_ptr<JobTask> MakeDelayedJob(std::unique_ptr<JobTask> task) {
3391cb0ef41Sopenharmony_ci    return std::make_unique<DelayedJob>(std::move(task),
3401cb0ef41Sopenharmony_ci                                        GetRandomDelayInMilliseconds());
3411cb0ef41Sopenharmony_ci  }
3421cb0ef41Sopenharmony_ci};
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_cistd::unique_ptr<Platform> MakeDelayedTasksPlatform(
3451cb0ef41Sopenharmony_ci    std::unique_ptr<Platform> platform, int64_t random_seed) {
3461cb0ef41Sopenharmony_ci  if (random_seed) {
3471cb0ef41Sopenharmony_ci    return std::make_unique<DelayedTasksPlatform>(std::move(platform),
3481cb0ef41Sopenharmony_ci                                                  random_seed);
3491cb0ef41Sopenharmony_ci  }
3501cb0ef41Sopenharmony_ci  return std::make_unique<DelayedTasksPlatform>(std::move(platform));
3511cb0ef41Sopenharmony_ci}
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_ci}  // namespace v8
354