|
|
|||
File indexing completed on 2026-09-14 09:12:38
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 GetForegroundTaskRunner(TaskPriority::kUserBlocking); 0056 } 0057 0058 /** 0059 * Returns a TaskRunner with a specific |priority| which can be used to post a 0060 * task on the foreground thread. 0061 */ 0062 virtual std::shared_ptr<TaskRunner> GetForegroundTaskRunner( 0063 TaskPriority priority) { 0064 return nullptr; 0065 } 0066 0067 /** 0068 * Posts `job_task` to run in parallel. Returns a `JobHandle` associated with 0069 * the `Job`, which can be joined or canceled. 0070 * This avoids degenerate cases: 0071 * - Calling `CallOnWorkerThread()` for each work item, causing significant 0072 * overhead. 0073 * - Fixed number of `CallOnWorkerThread()` calls that split the work and 0074 * might run for a long time. This is problematic when many components post 0075 * "num cores" tasks and all expect to use all the cores. In these cases, 0076 * the scheduler lacks context to be fair to multiple same-priority requests 0077 * and/or ability to request lower priority work to yield when high priority 0078 * work comes in. 0079 * A canonical implementation of `job_task` looks like: 0080 * \code 0081 * class MyJobTask : public JobTask { 0082 * public: 0083 * MyJobTask(...) : worker_queue_(...) {} 0084 * // JobTask implementation. 0085 * void Run(JobDelegate* delegate) override { 0086 * while (!delegate->ShouldYield()) { 0087 * // Smallest unit of work. 0088 * auto work_item = worker_queue_.TakeWorkItem(); // Thread safe. 0089 * if (!work_item) return; 0090 * ProcessWork(work_item); 0091 * } 0092 * } 0093 * 0094 * size_t GetMaxConcurrency() const override { 0095 * return worker_queue_.GetSize(); // Thread safe. 0096 * } 0097 * }; 0098 * 0099 * // ... 0100 * auto handle = PostJob(TaskPriority::kUserVisible, 0101 * std::make_unique<MyJobTask>(...)); 0102 * handle->Join(); 0103 * \endcode 0104 * 0105 * `PostJob()` and methods of the returned JobHandle/JobDelegate, must never 0106 * be called while holding a lock that could be acquired by `JobTask::Run()` 0107 * or `JobTask::GetMaxConcurrency()` -- that could result in a deadlock. This 0108 * is because (1) `JobTask::GetMaxConcurrency()` may be invoked while holding 0109 * internal lock (A), hence `JobTask::GetMaxConcurrency()` can only use a lock 0110 * (B) if that lock is *never* held while calling back into `JobHandle` from 0111 * any thread (A=>B/B=>A deadlock) and (2) `JobTask::Run()` or 0112 * `JobTask::GetMaxConcurrency()` may be invoked synchronously from 0113 * `JobHandle` (B=>JobHandle::foo=>B deadlock). 0114 * 0115 * A sufficient `PostJob()` implementation that uses the default Job provided 0116 * in libplatform looks like: 0117 * \code 0118 * std::unique_ptr<JobHandle> PostJob( 0119 * TaskPriority priority, std::unique_ptr<JobTask> job_task) override { 0120 * return std::make_unique<DefaultJobHandle>( 0121 * std::make_shared<DefaultJobState>( 0122 * this, std::move(job_task), kNumThreads)); 0123 * } 0124 * \endcode 0125 */ 0126 virtual std::unique_ptr<JobHandle> PostJob( 0127 TaskPriority priority, std::unique_ptr<JobTask> job_task) { 0128 return nullptr; 0129 } 0130 0131 /** 0132 * Returns an instance of a `TracingController`. This must be non-nullptr. The 0133 * default implementation returns an empty `TracingController` that consumes 0134 * trace data without effect. 0135 */ 0136 virtual TracingController* GetTracingController(); 0137 }; 0138 0139 V8_EXPORT bool IsInitialized(); 0140 0141 /** 0142 * Process-global initialization of the garbage collector. Must be called before 0143 * creating a Heap. 0144 * 0145 * Can be called multiple times when paired with `ShutdownProcess()`. 0146 * 0147 * \param page_allocator The allocator used for maintaining meta data. Must stay 0148 * always alive and not change between multiple calls to InitializeProcess. If 0149 * no allocator is provided, a default internal version will be used. 0150 * \param desired_heap_size Desired amount of virtual address space to reserve 0151 * for the heap, in bytes. Actual size will be clamped to minimum and maximum 0152 * values based on compile-time settings and may be rounded up. If this 0153 * parameter is zero, a default value will be used. 0154 */ 0155 V8_EXPORT void InitializeProcess(PageAllocator* page_allocator = nullptr, 0156 size_t desired_heap_size = 0); 0157 0158 /** 0159 * Must be called after destroying the last used heap. Some process-global 0160 * metadata may not be returned and reused upon a subsequent 0161 * `InitializeProcess()` call. 0162 */ 0163 V8_EXPORT void ShutdownProcess(); 0164 0165 namespace internal { 0166 0167 V8_EXPORT void Fatal(const std::string& reason = std::string(), 0168 SourceLocation = SourceLocation::Current()); 0169 0170 } // namespace internal 0171 0172 } // namespace cppgc 0173 0174 #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 |
|