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