5#ifndef V8_OBJECTS_JS_ATOMICS_SYNCHRONIZATION_H_
6#define V8_OBJECTS_JS_ATOMICS_SYNCHRONIZATION_H_
23#include "torque-generated/src/objects/js-atomics-synchronization-tq.inc"
26class WaiterQueueLockGuard;
44 :
public TorqueGeneratedJSSynchronizationPrimitive<
45 JSSynchronizationPrimitive, AlwaysSharedSpaceJSObject> {
76 template <
class T,
int size>
97 using TorqueGeneratedJSSynchronizationPrimitive<
99 using TorqueGeneratedJSSynchronizationPrimitive<
110#if V8_COMPRESS_POINTERS
174 :
public TorqueGeneratedJSAtomicsMutex<JSAtomicsMutex,
175 JSSynchronizationPrimitive> {
204 std::optional<base::TimeDelta> timeout = std::nullopt);
224 static inline bool Lock(
226 std::optional<base::TimeDelta> timeout = std::nullopt);
238 std::optional<base::TimeDelta> timeout = std::nullopt);
270 DequeueMatcher matcher);
313 std::atomic<StateT>* state, std::optional<base::TimeDelta> timeout);
316 std::atomic<StateT>* state,
320 std::optional<base::TimeDelta> timeout);
323 std::atomic<StateT>* state);
327 std::atomic<StateT>* state,
330 static bool TryLockExplicit(std::atomic<StateT>* state, StateT& expected);
334 std::atomic<StateT>* state, StateT& current_state);
337 std::atomic<StateT>* state);
340 std::atomic<StateT>* state);
343 std::atomic<StateT>* state,
350 template <
typename LockSlowPathWrapper,
351 typename = std::enable_if<std::is_invocable_r_v<
352 bool, LockSlowPathWrapper, std::atomic<StateT>*>>>
355 std::optional<base::TimeDelta> timeout,
356 LockSlowPathWrapper slow_path_wrapper);
358 using TorqueGeneratedJSAtomicsMutex<
360 using TorqueGeneratedJSAtomicsMutex<
401 :
public TorqueGeneratedJSAtomicsCondition<JSAtomicsCondition,
402 JSSynchronizationPrimitive> {
411 std::optional<base::TimeDelta> timeout);
416 std::optional<base::TimeDelta> timeout);
430 DequeueMatcher matcher);
450 std::atomic<StateT>* state,
static constexpr U encode(T value)
@ kConditionVariableAsyncContextSlot
static V8_EXPORT_PRIVATE MaybeDirectHandle< JSReceiver > WaitAsync(Isolate *requester, DirectHandle< JSAtomicsCondition > cv, DirectHandle< JSAtomicsMutex > mutex, std::optional< base::TimeDelta > timeout)
static void QueueWaiter(Isolate *requester, DirectHandle< JSAtomicsCondition > cv, WaiterQueueNode *waiter)
static uint32_t DequeueExplicit(Isolate *requester, DirectHandle< JSAtomicsCondition > cv, std::atomic< StateT > *state, const DequeueAction &dequeue_action)
static void HandleAsyncNotify(WaitAsyncWaiterQueueNode *node)
std::function< uint32_t(WaiterQueueNode **)> DequeueAction
static constexpr uint32_t kAllWaiters
static void CleanupMatchingAsyncWaiters(Isolate *isolate, WaiterQueueNode *node, DequeueMatcher matcher)
static void HandleAsyncTimeout(WaitAsyncWaiterQueueNode *node)
static V8_EXPORT_PRIVATE uint32_t Notify(Isolate *requester, DirectHandle< JSAtomicsCondition > cv, uint32_t count)
static V8_EXPORT_PRIVATE bool WaitFor(Isolate *requester, DirectHandle< JSAtomicsCondition > cv, DirectHandle< JSAtomicsMutex > mutex, std::optional< base::TimeDelta > timeout)
DirectHandle< JSAtomicsMutex > mutex_
LockGuardBase(const LockGuardBase &)=delete
LockGuardBase & operator=(const LockGuardBase &)=delete
void SetCurrentThreadAsOwner()
static DirectHandle< JSPromise > LockAsyncWrapperForWait(Isolate *requester, DirectHandle< JSAtomicsMutex > mutex)
static void HandleAsyncTimeout(LockAsyncWaiterQueueNode *node)
void UnlockAsyncLockedMutex(Isolate *requester, DirectHandle< Foreign > async_locked_waiter_wrapper)
static bool TryLockExplicit(std::atomic< StateT > *state, StateT &expected)
static void HandleAsyncNotify(LockAsyncWaiterQueueNode *node)
static V8_EXPORT_PRIVATE bool MaybeEnqueueNode(Isolate *requester, DirectHandle< JSAtomicsMutex > mutex, std::atomic< StateT > *state, WaiterQueueNode *this_waiter)
static bool Lock(Isolate *requester, DirectHandle< JSAtomicsMutex > mutex, std::optional< base::TimeDelta > timeout=std::nullopt)
static constexpr StateT kLockedUncontended
V8_EXPORT_PRIVATE void UnlockSlowPath(Isolate *requester, std::atomic< StateT > *state)
static V8_EXPORT_PRIVATE bool MutexTryLock(Isolate *requester, DirectHandle< JSAtomicsMutex > mutex, std::atomic< StateT > *state)
bool LockJSMutexOrDequeueTimedOutWaiter(Isolate *requester, std::atomic< StateT > *state, WaiterQueueNode *timed_out_waiter)
static bool LockImpl(Isolate *requester, DirectHandle< JSAtomicsMutex > mutex, std::optional< base::TimeDelta > timeout, LockSlowPathWrapper slow_path_wrapper)
static DirectHandle< JSObject > CreateResultObject(Isolate *isolate, DirectHandle< Object > value, bool success)
static std::optional< WaiterQueueLockGuard > LockWaiterQueueOrJSMutex(std::atomic< StateT > *state, StateT ¤t_state)
static void CleanupMatchingAsyncWaiters(Isolate *isolate, WaiterQueueNode *node, DequeueMatcher matcher)
static bool LockOrEnqueueAsyncNode(Isolate *isolate, DirectHandle< JSAtomicsMutex > mutex, LockAsyncWaiterQueueNode *node)
void Unlock(Isolate *requester)
static bool LockAsync(Isolate *requester, DirectHandle< JSAtomicsMutex > mutex, Handle< JSPromise > internal_locked_promise, MaybeHandle< JSPromise > unlocked_promise, AsyncWaiterNodeType **waiter_node, std::optional< base::TimeDelta > timeout=std::nullopt)
V8_WARN_UNUSED_RESULT bool TryLock()
std::atomic< int32_t > * AtomicOwnerThreadIdPtr()
static bool DequeueTimedOutAsyncWaiter(Isolate *requester, DirectHandle< JSAtomicsMutex > mutex, std::atomic< StateT > *state, WaiterQueueNode *timed_out_waiter)
static bool LockAsyncSlowPath(Isolate *isolate, DirectHandle< JSAtomicsMutex > mutex, std::atomic< StateT > *state, Handle< JSPromise > internal_locked_promise, MaybeHandle< JSPromise > unlocked_promise, AsyncWaiterNodeType **waiter_node, std::optional< base::TimeDelta > timeout)
@ kUnlockedPromiseAsyncContextSlot
@ kAsyncLockedWaiterAsyncContextSlot
static V8_EXPORT_PRIVATE bool LockSlowPath(Isolate *requester, DirectHandle< JSAtomicsMutex > mutex, std::atomic< StateT > *state, std::optional< base::TimeDelta > timeout)
static constexpr StateT kUnlockedUncontended
bool IsCurrentThreadOwner()
static MaybeDirectHandle< JSPromise > LockOrEnqueuePromise(Isolate *isolate, DirectHandle< JSAtomicsMutex > mutex, DirectHandle< Object > callback, std::optional< base::TimeDelta > timeout)
static V8_INLINE bool BackoffTryLock(Isolate *requester, DirectHandle< JSAtomicsMutex > mutex, std::atomic< StateT > *state)
static void CleanupAsyncWaiterLists(Isolate *isolate, DequeueMatcher matcher)
static bool TryLockWaiterQueueExplicit(std::atomic< StateT > *state, StateT &expected)
static constexpr StateT kWaiterQueueMask
static constexpr StateT kEmptyState
WaiterQueueNode * DestructivelyGetWaiterQueueHead(Isolate *requester)
static void SetWaiterQueueStateOnly(std::atomic< StateT > *state, StateT new_state)
std::function< bool(WaiterQueueNode *)> DequeueMatcher
void SetNullWaiterQueueHead()
Tagged< Object > NumWaitersForTesting(Isolate *requester)
WaiterQueueNode ** waiter_queue_head_location() const
StateT SetWaiterQueueHead(Isolate *requester, WaiterQueueNode *waiter_head, StateT new_state)
std::atomic< StateT > * AtomicStatePtr()
static void IsolateDeinit(Isolate *isolate)
static constexpr int kEndOfTaggedFieldsOffset
LiftoffAssembler::CacheState state
detail::AsyncWaiterQueueNode< JSAtomicsMutex > LockAsyncWaiterQueueNode
detail::AsyncWaiterQueueNode< JSAtomicsCondition > WaitAsyncWaiterQueueNode
uint32_t ExternalPointerHandle
#define DECL_PRINTER(Name)
#define TQ_OBJECT_CONSTRUCTORS(Type)
#define EXPORT_DECL_VERIFIER(Name)
#define V8_EXPORT_PRIVATE
#define V8_WARN_UNUSED_RESULT