Index: src/futex-emulation.h |
diff --git a/src/futex-emulation.h b/src/futex-emulation.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2a07f332d56fc472d3c7fef2028573780ba3bef9 |
--- /dev/null |
+++ b/src/futex-emulation.h |
@@ -0,0 +1,123 @@ |
+// Copyright 2015 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef V8_FUTEX_EMULATION_H_ |
+#define V8_FUTEX_EMULATION_H_ |
+ |
+#include <stdint.h> |
+ |
+#include "src/allocation.h" |
+#include "src/base/lazy-instance.h" |
+#include "src/base/macros.h" |
+#include "src/base/platform/condition-variable.h" |
+#include "src/base/platform/mutex.h" |
+#include "src/handles.h" |
+ |
+// Support for emulating futexes, a low-level synchronization primitive. They |
+// are natively supported by Linux, but must be emulated for other platforms. |
+// This library emulates them on all platforms using mutexes and condition |
+// variables for consistency. |
+// |
+// This is used by the Futex API defined in the SharedArrayBuffer draft spec, |
+// found here: https://github.com/lars-t-hansen/ecmascript_sharedmem |
+ |
+namespace v8 { |
+ |
+namespace base { |
+class TimeDelta; |
+} // base |
+ |
+namespace internal { |
+ |
+class Isolate; |
+ |
+class FutexWaitListNode { |
+ public: |
+ FutexWaitListNode() |
+ : prev_(nullptr), |
+ next_(nullptr), |
+ backing_store_(nullptr), |
+ wait_addr_(0), |
+ waiting_(false) {} |
+ |
+ private: |
+ friend class FutexEmulation; |
+ friend class FutexWaitList; |
+ |
+ base::ConditionVariable cond_; |
+ FutexWaitListNode* prev_; |
+ FutexWaitListNode* next_; |
+ void* backing_store_; |
+ size_t wait_addr_; |
+ bool waiting_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FutexWaitListNode); |
+}; |
+ |
+ |
+class FutexWaitList { |
+ public: |
+ FutexWaitList(); |
+ |
+ void AddNode(FutexWaitListNode* node); |
+ void RemoveNode(FutexWaitListNode* node); |
+ |
+ private: |
+ friend class FutexEmulation; |
+ |
+ FutexWaitListNode* head_; |
+ FutexWaitListNode* tail_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FutexWaitList); |
+}; |
+ |
+ |
+class FutexEmulation : public AllStatic { |
+ public: |
+ // These must match the values in src/harmony-atomics.js |
+ enum Result { |
+ kOk = 0, |
+ kNotEqual = -1, |
+ kTimedOut = -2, |
+ }; |
+ |
+ // Check that array_buffer[addr] == value, and return kNotEqual if not. If |
+ // they are equal, block execution on |isolate|'s thread until woken via |
+ // |Wake|, or when the time given in |rel_timeout_ms| elapses. Note that |
+ // |rel_timeout_ms| can be Infinity. |
+ // If woken, return kOk, otherwise return kTimedOut. The initial check and |
+ // the decision to wait happen atomically. |
+ static Object* Wait(Isolate* isolate, Handle<JSArrayBuffer> array_buffer, |
+ size_t addr, int32_t value, double rel_timeout_ms); |
+ |
+ // Wake |num_waiters_to_wake| threads that are waiting on the given |addr|. |
+ // The rest of the waiters will continue to wait. The return value is the |
+ // number of woken waiters. |
+ static Object* Wake(Isolate* isolate, Handle<JSArrayBuffer> array_buffer, |
+ size_t addr, int num_waiters_to_wake); |
+ |
+ // Check that array_buffer[addr] == value, and return kNotEqual if not. If |
+ // they are equal, wake |num_waiters_to_wake| threads that are waiting on the |
+ // given |addr|. The rest of the waiters will continue to wait, but will now |
+ // be waiting on |addr2| instead of |addr|. The return value is the number of |
+ // woken waiters or kNotEqual as described above. |
+ static Object* WakeOrRequeue(Isolate* isolate, |
+ Handle<JSArrayBuffer> array_buffer, size_t addr, |
+ int num_waiters_to_wake, int32_t value, |
+ size_t addr2); |
+ |
+ // Return the number of threads waiting on |addr|. Should only be used for |
+ // testing. |
+ static Object* NumWaitersForTesting(Isolate* isolate, |
+ Handle<JSArrayBuffer> array_buffer, |
+ size_t addr); |
+ |
+ private: |
+ static base::LazyMutex mutex_; |
+ static base::LazyInstance<FutexWaitList>::type wait_list_; |
+}; |
+} |
+} // namespace v8::internal |
+ |
+#endif // V8_FUTEX_EMULATION_H_ |