OLD | NEW |
---|---|
(Empty) | |
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/macros.h" | |
12 #include "src/base/platform/condition-variable.h" | |
13 #include "src/base/platform/mutex.h" | |
14 #include "src/handles.h" | |
15 | |
16 // Support for emulating futexes, a low-level synchronization primitive. They | |
17 // are natively supported by Linux, but must be emulated for other platforms. | |
18 // This library emulates them on all platforms using mutexes and condition | |
19 // variables for consistency. | |
20 // | |
21 // This is used by the Futex API defined in the SharedArrayBuffer draft spec, | |
22 // found here | |
23 // https://docs.google.com/document/d/1NDGA_gZJ7M7w1Bh8S0AoDyEqwDdRh4uSoTPSNn77P Fk | |
24 | |
25 namespace v8 { | |
26 | |
27 namespace base { | |
28 class TimeDelta; | |
29 } // base | |
30 | |
31 namespace internal { | |
32 | |
33 class Isolate; | |
34 | |
35 class FutexWaitListNode { | |
36 public: | |
37 FutexWaitListNode() | |
38 : prev_(NULL), | |
Jarin
2015/07/10 12:11:39
NULL -> nullptr in new code, please.
binji
2015/07/14 19:24:36
Done.
| |
39 next_(NULL), | |
40 backing_store_(NULL), | |
41 wait_addr_(0), | |
42 waiting_(false) {} | |
43 | |
44 private: | |
45 friend class FutexEmulation; | |
46 friend class FutexWaitList; | |
47 | |
48 base::ConditionVariable cond_; | |
49 FutexWaitListNode* prev_; | |
50 FutexWaitListNode* next_; | |
51 void* backing_store_; | |
52 size_t wait_addr_; | |
53 bool waiting_; | |
54 | |
55 DISALLOW_COPY_AND_ASSIGN(FutexWaitListNode); | |
56 }; | |
57 | |
58 | |
59 class FutexWaitList { | |
60 public: | |
61 FutexWaitList(); | |
62 | |
63 void AddNode(FutexWaitListNode* node); | |
64 void RemoveNode(FutexWaitListNode* node); | |
65 | |
66 private: | |
67 friend class FutexEmulation; | |
68 | |
69 FutexWaitListNode* head_; | |
70 FutexWaitListNode* tail_; | |
71 | |
72 DISALLOW_COPY_AND_ASSIGN(FutexWaitList); | |
73 }; | |
74 | |
75 | |
76 class FutexEmulation : public AllStatic { | |
77 public: | |
78 // These must match the values in src/harmony-atomics.js | |
79 enum class Result { | |
80 kOk = 0, | |
81 kNotEqual = -1, | |
82 kTimedOut = -2, | |
83 }; | |
84 | |
85 // Check that array_buffer[addr] == value, and return kNotEqual if not. If | |
86 // they are equal, block execution on |isolate|'s thread until woken via | |
87 // |Wake|, then return kOk. The initial check and the decision to wait happen | |
88 // atomically. | |
89 static Result Wait(Isolate* isolate, Handle<JSArrayBuffer> array_buffer, | |
90 size_t addr, int32_t value); | |
91 | |
92 // Check that array_buffer[addr] == value, and return kNotEqual if not. If | |
93 // they are equal, block execution on |isolate|'s thread until woken via | |
94 // |Wake|, or when the time given in |rel_timeout| elapses. If woken, return | |
95 // kOk, otherwise return kTimedOut. The initial check and the decision to | |
96 // wait happen atomically. | |
97 static Result Wait(Isolate* isolate, Handle<JSArrayBuffer> array_buffer, | |
98 size_t addr, int32_t value, | |
99 const base::TimeDelta& rel_timeout); | |
100 | |
101 // Wake |num_waiters_to_wake| threads that are waiting on the given |addr|. | |
102 // The rest of the waiters will continue to wait. The return value is the | |
103 // number of woken waiters. | |
104 static int Wake(Isolate* isolate, Handle<JSArrayBuffer> array_buffer, | |
105 size_t addr, int num_waiters_to_wake); | |
106 | |
107 // Check that array_buffer[addr] == value, and return kNotEqual if not. If | |
108 // they are equal, wake |num_waiters_to_wake| threads that are waiting on the | |
109 // given |addr|. The rest of the waiters will continue to wait, but will now | |
110 // be waiting on |addr2| instead of |addr|. The return value is the number of | |
111 // woken waiters or kNotEqual as described above. | |
112 static int WakeOrRequeue(Isolate* isolate, Handle<JSArrayBuffer> array_buffer, | |
113 size_t addr, int num_waiters_to_wake, int32_t value, | |
114 size_t addr2); | |
115 | |
116 // Return the number of threads waiting on |addr|. Should only be used for | |
117 // testing. | |
118 static int NumWaitersForTesting(Isolate* isolate, | |
119 Handle<JSArrayBuffer> array_buffer, | |
120 size_t addr); | |
121 | |
122 private: | |
123 static base::LazyMutex mutex_; | |
124 static FutexWaitList wait_list_; | |
125 }; | |
126 } | |
127 } // namespace v8::internal | |
128 | |
129 #endif // V8_FUTEX_EMULATION_H_ | |
OLD | NEW |