v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
parked-scope.h
Go to the documentation of this file.
1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_HEAP_PARKED_SCOPE_H_
6#define V8_HEAP_PARKED_SCOPE_H_
7
8#include <optional>
9
14#include "src/heap/local-heap.h"
15
16namespace v8 {
17namespace internal {
18
19// Scope that explicitly parks a thread, prohibiting access to the heap and the
20// creation of handles. Do not use this directly! Use the family of
21// ExecuteWhileParked methods, instead.
23 private:
24 explicit ParkedScope(LocalIsolate* local_isolate)
25 : ParkedScope(local_isolate->heap()) {}
26 explicit ParkedScope(LocalHeap* local_heap) : local_heap_(local_heap) {
27 ++local_heap_->nested_parked_scopes_;
28 local_heap_->Park();
29 }
30
32 DCHECK_LT(0, local_heap_->nested_parked_scopes_);
33 --local_heap_->nested_parked_scopes_;
34 local_heap_->Unpark();
35 }
36
38
39 friend class LocalHeap;
40};
41
42// Scope that explicitly unparks a thread, allowing access to the heap and the
43// creation of handles.
45 public:
46 explicit UnparkedScope(LocalIsolate* local_isolate)
47 : UnparkedScope(local_isolate->heap()) {}
48 explicit UnparkedScope(LocalHeap* local_heap) : local_heap_(local_heap) {
49 local_heap_->Unpark();
50 }
51
52 ~UnparkedScope() { local_heap_->Park(); }
53
54 private:
56};
57
58// Scope that explicitly unparks a background thread, allowing access to the
59// heap and the creation of handles. It has no effect on the main thread.
61 public:
63 : UnparkedScopeIfOnBackground(local_isolate->heap()) {}
64 explicit UnparkedScopeIfOnBackground(LocalHeap* local_heap) {
65 if (!local_heap->is_main_thread()) scope_.emplace(local_heap);
66 }
67
68 private:
69 std::optional<UnparkedScope> scope_;
70};
71
72// Scope that automatically parks the thread while blocking on the given
73// base::Mutex.
75 public:
76 explicit V8_INLINE ParkedMutexGuard(LocalIsolate* local_isolate,
78 explicit V8_INLINE ParkedMutexGuard(LocalHeap* local_heap,
80
83
84 ~ParkedMutexGuard() { mutex_->Unlock(); }
85
86 private:
88};
89
90// Scope that automatically parks the thread while blocking on the given
91// base::RecursiveMutex.
107
109 public:
111 bool enable_mutex);
113 bool enable_mutex);
114
117
119 if (!mutex_) return;
120
121 mutex_->Unlock();
122 }
123
124 private:
125 base::Mutex* mutex_ = nullptr;
126};
127
128// A subclass of base::ConditionVariable that automatically parks the thread
129// while waiting.
131 : public base::ConditionVariable {
132 public:
136
137 V8_INLINE void ParkedWait(LocalIsolate* local_isolate, base::Mutex* mutex);
138 V8_INLINE void ParkedWait(LocalHeap* local_heap, base::Mutex* mutex);
139
141 USE(scope);
142 Wait(mutex);
143 }
144
145 V8_INLINE bool ParkedWaitFor(LocalIsolate* local_isolate, base::Mutex* mutex,
146 const base::TimeDelta& rel_time)
148 V8_INLINE bool ParkedWaitFor(LocalHeap* local_heap, base::Mutex* mutex,
149 const base::TimeDelta& rel_time)
151
153 const base::TimeDelta& rel_time) V8_WARN_UNUSED_RESULT {
154 USE(scope);
155 return WaitFor(mutex, rel_time);
156 }
157
158 private:
159 using base::ConditionVariable::Wait;
160 using base::ConditionVariable::WaitFor;
161};
162
163// A subclass of base::Semaphore that automatically parks the thread while
164// waiting.
166 public:
167 explicit ParkingSemaphore(int count) : base::Semaphore(count) {}
170
171 V8_INLINE void ParkedWait(LocalIsolate* local_isolate);
172 V8_INLINE void ParkedWait(LocalHeap* local_heap);
173
174 void ParkedWait(const ParkedScope& scope) {
175 USE(scope);
176 Wait();
177 }
178
179 V8_INLINE bool ParkedWaitFor(LocalIsolate* local_isolate,
180 const base::TimeDelta& rel_time)
182 V8_INLINE bool ParkedWaitFor(LocalHeap* local_heap,
183 const base::TimeDelta& rel_time)
185
186 bool ParkedWaitFor(const ParkedScope& scope,
187 const base::TimeDelta& rel_time) {
188 USE(scope);
189 return WaitFor(rel_time);
190 }
191
192 private:
193 using base::Semaphore::Wait;
194 using base::Semaphore::WaitFor;
195};
196
198 public:
199 explicit ParkingThread(const Options& options) : v8::base::Thread(options) {}
200
201 V8_INLINE void ParkedJoin(LocalIsolate* local_isolate);
202 V8_INLINE void ParkedJoin(LocalHeap* local_heap);
203
204 void ParkedJoin(const ParkedScope& scope) {
205 USE(scope);
206 Join();
207 }
208
209 template <typename ThreadCollection>
210 static V8_INLINE void ParkedJoinAll(LocalIsolate* local_isolate,
211 const ThreadCollection& threads);
212 template <typename ThreadCollection>
213 static V8_INLINE void ParkedJoinAll(LocalHeap* local_heap,
214 const ThreadCollection& threads);
215
216 template <typename ThreadCollection>
217 static void ParkedJoinAll(const ParkedScope& scope,
218 const ThreadCollection& threads) {
219 USE(scope);
220 for (auto& thread : threads) thread->Join();
221 }
222
223 private:
225};
226
227} // namespace internal
228} // namespace v8
229
230#endif // V8_HEAP_PARKED_SCOPE_H_
Thread(const Options &options)
bool is_main_thread() const
Definition local-heap.h:194
ParkedMutexGuardIf(const ParkedMutexGuardIf &)=delete
ParkedMutexGuardIf & operator=(const ParkedMutexGuardIf &)=delete
ParkedMutexGuard(const ParkedMutexGuard &)=delete
ParkedMutexGuard & operator=(const ParkedMutexGuard &)=delete
ParkedRecursiveMutexGuard(const ParkedRecursiveMutexGuard &)=delete
ParkedRecursiveMutexGuard & operator=(const ParkedRecursiveMutexGuard &)=delete
ParkedScope(LocalHeap *local_heap)
ParkedScope(LocalIsolate *local_isolate)
LocalHeap *const local_heap_
void ParkedWait(const ParkedScope &scope, base::Mutex *mutex)
ParkingConditionVariable & operator=(const ParkingConditionVariable &)=delete
ParkingConditionVariable(const ParkingConditionVariable &)=delete
bool ParkedWaitFor(const ParkedScope &scope, base::Mutex *mutex, const base::TimeDelta &rel_time) V8_WARN_UNUSED_RESULT
ParkingSemaphore & operator=(const ParkingSemaphore &)=delete
bool ParkedWaitFor(const ParkedScope &scope, const base::TimeDelta &rel_time)
void ParkedWait(const ParkedScope &scope)
ParkingSemaphore(const ParkingSemaphore &)=delete
V8_INLINE void ParkedJoin(LocalIsolate *local_isolate)
void ParkedJoin(const ParkedScope &scope)
ParkingThread(const Options &options)
static void ParkedJoinAll(const ParkedScope &scope, const ThreadCollection &threads)
static V8_INLINE void ParkedJoinAll(LocalIsolate *local_isolate, const ThreadCollection &threads)
UnparkedScopeIfOnBackground(LocalIsolate *local_isolate)
UnparkedScopeIfOnBackground(LocalHeap *local_heap)
std::optional< UnparkedScope > scope_
UnparkedScope(LocalIsolate *local_isolate)
LocalHeap *const local_heap_
UnparkedScope(LocalHeap *local_heap)
base::Mutex & mutex_
DeclarationScope * scope_
base::Mutex mutex
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define USE(...)
Definition macros.h:293
#define V8_INLINE
Definition v8config.h:500
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671
#define V8_NODISCARD
Definition v8config.h:693