V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
futex-emulation.h
1
// Copyright 2015 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_FUTEX_EMULATION_H_
6
#define V8_FUTEX_EMULATION_H_
7
8
#include <stdint.h>
9
10
#include "src/allocation.h"
11
#include "src/base/atomicops.h"
12
#include "src/base/lazy-instance.h"
13
#include "src/base/macros.h"
14
#include "src/base/platform/condition-variable.h"
15
#include "src/base/platform/mutex.h"
16
17
// Support for emulating futexes, a low-level synchronization primitive. They
18
// are natively supported by Linux, but must be emulated for other platforms.
19
// This library emulates them on all platforms using mutexes and condition
20
// variables for consistency.
21
//
22
// This is used by the Futex API defined in the SharedArrayBuffer draft spec,
23
// found here: https://github.com/tc39/ecmascript_sharedmem
24
25
namespace
v8
{
26
27
namespace
base {
28
class
TimeDelta;
29
}
// base
30
31
namespace
internal {
32
33
template
<
typename
T>
34
class
Handle;
35
class
Isolate;
36
class
JSArrayBuffer;
37
38
class
AtomicsWaitWakeHandle
{
39
public
:
40
explicit
AtomicsWaitWakeHandle
(
Isolate
* isolate) : isolate_(isolate) {}
41
42
void
Wake();
43
inline
bool
has_stopped()
const
{
return
stopped_; }
44
45
private
:
46
Isolate
* isolate_;
47
bool
stopped_ =
false
;
48
};
49
50
class
FutexWaitListNode
{
51
public
:
52
FutexWaitListNode
()
53
: prev_(
nullptr
),
54
next_(
nullptr
),
55
backing_store_(
nullptr
),
56
wait_addr_(0),
57
waiting_(
false
),
58
interrupted_(
false
) {}
59
60
void
NotifyWake();
61
62
private
:
63
friend
class
FutexEmulation
;
64
friend
class
FutexWaitList
;
65
friend
class
ResetWaitingOnScopeExit
;
66
67
base::ConditionVariable
cond_;
68
// prev_ and next_ are protected by FutexEmulation::mutex_.
69
FutexWaitListNode
* prev_;
70
FutexWaitListNode
* next_;
71
void
* backing_store_;
72
size_t
wait_addr_;
73
// waiting_ and interrupted_ are protected by FutexEmulation::mutex_
74
// if this node is currently contained in FutexEmulation::wait_list_
75
// or an AtomicsWaitWakeHandle has access to it.
76
bool
waiting_;
77
bool
interrupted_;
78
79
DISALLOW_COPY_AND_ASSIGN(
FutexWaitListNode
);
80
};
81
82
83
class
FutexWaitList
{
84
public
:
85
FutexWaitList
();
86
87
void
AddNode(
FutexWaitListNode
* node);
88
void
RemoveNode(
FutexWaitListNode
* node);
89
90
private
:
91
friend
class
FutexEmulation
;
92
93
FutexWaitListNode
* head_;
94
FutexWaitListNode
* tail_;
95
96
DISALLOW_COPY_AND_ASSIGN(
FutexWaitList
);
97
};
98
99
class
ResetWaitingOnScopeExit
{
100
public
:
101
explicit
ResetWaitingOnScopeExit
(
FutexWaitListNode
* node) : node_(node) {}
102
~
ResetWaitingOnScopeExit
() { node_->waiting_ =
false
; }
103
104
private
:
105
FutexWaitListNode
* node_;
106
107
DISALLOW_COPY_AND_ASSIGN(
ResetWaitingOnScopeExit
);
108
};
109
110
class
FutexEmulation
:
public
AllStatic
{
111
public
:
112
// Pass to Wake() to wake all waiters.
113
static
const
uint32_t
kWakeAll = UINT32_MAX;
114
115
// Check that array_buffer[addr] == value, and return "not-equal" if not. If
116
// they are equal, block execution on |isolate|'s thread until woken via
117
// |Wake|, or when the time given in |rel_timeout_ms| elapses. Note that
118
// |rel_timeout_ms| can be Infinity.
119
// If woken, return "ok", otherwise return "timed-out". The initial check and
120
// the decision to wait happen atomically.
121
static
Object
* WaitJs(
Isolate
* isolate,
Handle<JSArrayBuffer>
array_buffer,
122
size_t
addr, int32_t value,
double
rel_timeout_ms);
123
124
// Same as WaitJs above except it returns 0 (ok), 1 (not equal) and 2 (timed
125
// out) as expected by Wasm.
126
static
Object
* Wait(
Isolate
* isolate,
Handle<JSArrayBuffer>
array_buffer,
127
size_t
addr, int32_t value,
double
rel_timeout_ms);
128
129
// Wake |num_waiters_to_wake| threads that are waiting on the given |addr|.
130
// |num_waiters_to_wake| can be kWakeAll, in which case all waiters are
131
// woken. The rest of the waiters will continue to wait. The return value is
132
// the number of woken waiters.
133
static
Object
* Wake(
Handle<JSArrayBuffer>
array_buffer,
size_t
addr,
134
uint32_t
num_waiters_to_wake);
135
136
// Return the number of threads waiting on |addr|. Should only be used for
137
// testing.
138
static
Object
* NumWaitersForTesting(
Handle<JSArrayBuffer>
array_buffer,
139
size_t
addr);
140
141
private
:
142
friend
class
FutexWaitListNode
;
143
friend
class
AtomicsWaitWakeHandle
;
144
145
// `mutex_` protects the composition of `wait_list_` (i.e. no elements may be
146
// added or removed without holding this mutex), as well as the `waiting_`
147
// and `interrupted_` fields for each individual list node that is currently
148
// part of the list. It must be the mutex used together with the `cond_`
149
// condition variable of such nodes.
150
static
base::LazyMutex
mutex_;
151
static
base::LazyInstance<FutexWaitList>::type
wait_list_;
152
};
153
}
// namespace internal
154
}
// namespace v8
155
156
#endif // V8_FUTEX_EMULATION_H_
v8::internal::FutexEmulation
Definition:
futex-emulation.h:110
v8::internal::ResetWaitingOnScopeExit
Definition:
futex-emulation.h:99
v8::internal::FutexWaitList
Definition:
futex-emulation.h:83
v8
Definition:
libplatform.h:13
v8::internal::Handle
Definition:
accessors.h:19
v8::internal::Object
Definition:
objects.h:562
v8::internal::AllStatic
Definition:
globals.h:92
v8::internal::Isolate
Definition:
isolate.h:516
uint32_t
v8::base::LazyInstanceImpl
Definition:
lazy-instance.h:166
v8::base::ConditionVariable
Definition:
condition-variable.h:32
v8::internal::FutexWaitListNode
Definition:
futex-emulation.h:50
v8::internal::AtomicsWaitWakeHandle
Definition:
futex-emulation.h:38
v8
src
futex-emulation.h
Generated on Tue Dec 25 2018 14:38:50 by
1.8.14