Chromium Code Reviews| Index: src/futex-emulation.h |
| diff --git a/src/futex-emulation.h b/src/futex-emulation.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..8ef80ca25c2eef3775e6c0696f5e8f445a8d5877 |
| --- /dev/null |
| +++ b/src/futex-emulation.h |
| @@ -0,0 +1,129 @@ |
| +// 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/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://docs.google.com/document/d/1NDGA_gZJ7M7w1Bh8S0AoDyEqwDdRh4uSoTPSNn77PFk |
| + |
| +namespace v8 { |
| + |
| +namespace base { |
| +class TimeDelta; |
| +} // base |
| + |
| +namespace internal { |
| + |
| +class Isolate; |
| + |
| +class FutexWaitListNode { |
| + public: |
| + FutexWaitListNode() |
| + : prev_(NULL), |
|
Jarin
2015/07/10 12:11:39
NULL -> nullptr in new code, please.
binji
2015/07/14 19:24:36
Done.
|
| + next_(NULL), |
| + backing_store_(NULL), |
| + 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 class 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|, then return kOk. The initial check and the decision to wait happen |
| + // atomically. |
| + static Result Wait(Isolate* isolate, Handle<JSArrayBuffer> array_buffer, |
| + size_t addr, int32_t value); |
| + |
| + // 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| elapses. If woken, return |
| + // kOk, otherwise return kTimedOut. The initial check and the decision to |
| + // wait happen atomically. |
| + static Result Wait(Isolate* isolate, Handle<JSArrayBuffer> array_buffer, |
| + size_t addr, int32_t value, |
| + const base::TimeDelta& rel_timeout); |
| + |
| + // 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 int 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 int 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 int NumWaitersForTesting(Isolate* isolate, |
| + Handle<JSArrayBuffer> array_buffer, |
| + size_t addr); |
| + |
| + private: |
| + static base::LazyMutex mutex_; |
| + static FutexWaitList wait_list_; |
| +}; |
| +} |
| +} // namespace v8::internal |
| + |
| +#endif // V8_FUTEX_EMULATION_H_ |