Chromium Code Reviews| 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 |