![]() |
|
|||
File indexing completed on 2025-02-22 10:42:26
0001 // Copyright 2020 the V8 project authors. All rights reserved. 0002 // Use of this source code is governed by a BSD-style license that can be 0003 // found in the LICENSE file. 0004 0005 #ifndef INCLUDE_CPPGC_PLATFORM_H_ 0006 #define INCLUDE_CPPGC_PLATFORM_H_ 0007 0008 #include <memory> 0009 0010 #include "cppgc/source-location.h" 0011 #include "v8-platform.h" // NOLINT(build/include_directory) 0012 #include "v8config.h" // NOLINT(build/include_directory) 0013 0014 namespace cppgc { 0015 0016 // TODO(v8:10346): Create separate includes for concepts that are not 0017 // V8-specific. 0018 using IdleTask = v8::IdleTask; 0019 using JobHandle = v8::JobHandle; 0020 using JobDelegate = v8::JobDelegate; 0021 using JobTask = v8::JobTask; 0022 using PageAllocator = v8::PageAllocator; 0023 using Task = v8::Task; 0024 using TaskPriority = v8::TaskPriority; 0025 using TaskRunner = v8::TaskRunner; 0026 using TracingController = v8::TracingController; 0027 0028 /** 0029 * Platform interface used by Heap. Contains allocators and executors. 0030 */ 0031 class V8_EXPORT Platform { 0032 public: 0033 virtual ~Platform() = default; 0034 0035 /** 0036 * \returns the allocator used by cppgc to allocate its heap and various 0037 * support structures. Returning nullptr results in using the `PageAllocator` 0038 * provided by `cppgc::InitializeProcess()` instead. 0039 */ 0040 virtual PageAllocator* GetPageAllocator() = 0; 0041 0042 /** 0043 * Monotonically increasing time in seconds from an arbitrary fixed point in 0044 * the past. This function is expected to return at least 0045 * millisecond-precision values. For this reason, 0046 * it is recommended that the fixed point be no further in the past than 0047 * the epoch. 0048 **/ 0049 virtual double MonotonicallyIncreasingTime() = 0; 0050 0051 /** 0052 * Foreground task runner that should be used by a Heap. 0053 */ 0054 virtual std::shared_ptr<TaskRunner> GetForegroundTaskRunner() { 0055 return nullptr; 0056 } 0057 0058 /** 0059 * Posts `job_task` to run in parallel. Returns a `JobHandle` associated with 0060 * the `Job`, which can be joined or canceled. 0061 * This avoids degenerate cases: 0062 * - Calling `CallOnWorkerThread()` for each work item, causing significant 0063 * overhead. 0064 * - Fixed number of `CallOnWorkerThread()` calls that split the work and 0065 * might run for a long time. This is problematic when many components post 0066 * "num cores" tasks and all expect to use all the cores. In these cases, 0067 * the scheduler lacks context to be fair to multiple same-priority requests 0068 * and/or ability to request lower priority work to yield when high priority 0069 * work comes in. 0070 * A canonical implementation of `job_task` looks like: 0071 * \code 0072 * class MyJobTask : public JobTask { 0073 * public: 0074 * MyJobTask(...) : worker_queue_(...) {} 0075 * // JobTask implementation. 0076 * void Run(JobDelegate* delegate) override { 0077 * while (!delegate->ShouldYield()) { 0078 * // Smallest unit of work. 0079 * auto work_item = worker_queue_.TakeWorkItem(); // Thread safe. 0080 * if (!work_item) return; 0081 * ProcessWork(work_item); 0082 * } 0083 * } 0084 * 0085 * size_t GetMaxConcurrency() const override { 0086 * return worker_queue_.GetSize(); // Thread safe. 0087 * } 0088 * }; 0089 * 0090 * // ... 0091 * auto handle = PostJob(TaskPriority::kUserVisible, 0092 * std::make_unique<MyJobTask>(...)); 0093 * handle->Join(); 0094 * \endcode 0095 * 0096 * `PostJob()` and methods of the returned JobHandle/JobDelegate, must never 0097 * be called while holding a lock that could be acquired by `JobTask::Run()` 0098 * or `JobTask::GetMaxConcurrency()` -- that could result in a deadlock. This 0099 * is because (1) `JobTask::GetMaxConcurrency()` may be invoked while holding 0100 * internal lock (A), hence `JobTask::GetMaxConcurrency()` can only use a lock 0101 * (B) if that lock is *never* held while calling back into `JobHandle` from 0102 * any thread (A=>B/B=>A deadlock) and (2) `JobTask::Run()` or 0103 * `JobTask::GetMaxConcurrency()` may be invoked synchronously from 0104 * `JobHandle` (B=>JobHandle::foo=>B deadlock). 0105 * 0106 * A sufficient `PostJob()` implementation that uses the default Job provided 0107 * in libplatform looks like: 0108 * \code 0109 * std::unique_ptr<JobHandle> PostJob( 0110 * TaskPriority priority, std::unique_ptr<JobTask> job_task) override { 0111 * return std::make_unique<DefaultJobHandle>( 0112 * std::make_shared<DefaultJobState>( 0113 * this, std::move(job_task), kNumThreads)); 0114 * } 0115 * \endcode 0116 */ 0117 virtual std::unique_ptr<JobHandle> PostJob( 0118 TaskPriority priority, std::unique_ptr<JobTask> job_task) { 0119 return nullptr; 0120 } 0121 0122 /** 0123 * Returns an instance of a `TracingController`. This must be non-nullptr. The 0124 * default implementation returns an empty `TracingController` that consumes 0125 * trace data without effect. 0126 */ 0127 virtual TracingController* GetTracingController(); 0128 }; 0129 0130 /** 0131 * Process-global initialization of the garbage collector. Must be called before 0132 * creating a Heap. 0133 * 0134 * Can be called multiple times when paired with `ShutdownProcess()`. 0135 * 0136 * \param page_allocator The allocator used for maintaining meta data. Must stay 0137 * always alive and not change between multiple calls to InitializeProcess. If 0138 * no allocator is provided, a default internal version will be used. 0139 * \param desired_heap_size Desired amount of virtual address space to reserve 0140 * for the heap, in bytes. Actual size will be clamped to minimum and maximum 0141 * values based on compile-time settings and may be rounded up. If this 0142 * parameter is zero, a default value will be used. 0143 */ 0144 V8_EXPORT void InitializeProcess(PageAllocator* page_allocator = nullptr, 0145 size_t desired_heap_size = 0); 0146 0147 /** 0148 * Must be called after destroying the last used heap. Some process-global 0149 * metadata may not be returned and reused upon a subsequent 0150 * `InitializeProcess()` call. 0151 */ 0152 V8_EXPORT void ShutdownProcess(); 0153 0154 namespace internal { 0155 0156 V8_EXPORT void Fatal(const std::string& reason = std::string(), 0157 const SourceLocation& = SourceLocation::Current()); 0158 0159 } // namespace internal 0160 0161 } // namespace cppgc 0162 0163 #endif // INCLUDE_CPPGC_PLATFORM_H_
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |