OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/futex-emulation.h" | 5 #include "src/futex-emulation.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/macros.h" | 9 #include "src/base/macros.h" |
10 #include "src/base/platform/time.h" | 10 #include "src/base/platform/time.h" |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 int32_t value, double rel_timeout_ms) { | 77 int32_t value, double rel_timeout_ms) { |
78 DCHECK(addr < NumberToSize(isolate, array_buffer->byte_length())); | 78 DCHECK(addr < NumberToSize(isolate, array_buffer->byte_length())); |
79 | 79 |
80 void* backing_store = array_buffer->backing_store(); | 80 void* backing_store = array_buffer->backing_store(); |
81 int32_t* p = | 81 int32_t* p = |
82 reinterpret_cast<int32_t*>(static_cast<int8_t*>(backing_store) + addr); | 82 reinterpret_cast<int32_t*>(static_cast<int8_t*>(backing_store) + addr); |
83 | 83 |
84 base::LockGuard<base::Mutex> lock_guard(mutex_.Pointer()); | 84 base::LockGuard<base::Mutex> lock_guard(mutex_.Pointer()); |
85 | 85 |
86 if (*p != value) { | 86 if (*p != value) { |
87 return Smi::FromInt(Result::kNotEqual); | 87 return isolate->heap()->not_equal(); |
88 } | 88 } |
89 | 89 |
90 FutexWaitListNode* node = isolate->futex_wait_list_node(); | 90 FutexWaitListNode* node = isolate->futex_wait_list_node(); |
91 | 91 |
92 node->backing_store_ = backing_store; | 92 node->backing_store_ = backing_store; |
93 node->wait_addr_ = addr; | 93 node->wait_addr_ = addr; |
94 node->waiting_ = true; | 94 node->waiting_ = true; |
95 | 95 |
96 bool use_timeout = rel_timeout_ms != V8_INFINITY; | 96 bool use_timeout = rel_timeout_ms != V8_INFINITY; |
97 | 97 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 } | 150 } |
151 | 151 |
152 mutex_.Pointer()->Lock(); | 152 mutex_.Pointer()->Lock(); |
153 | 153 |
154 if (node->interrupted_) { | 154 if (node->interrupted_) { |
155 // An interrupt occured while the mutex_ was unlocked. Don't wait yet. | 155 // An interrupt occured while the mutex_ was unlocked. Don't wait yet. |
156 continue; | 156 continue; |
157 } | 157 } |
158 | 158 |
159 if (!node->waiting_) { | 159 if (!node->waiting_) { |
160 result = Smi::FromInt(Result::kOk); | 160 result = isolate->heap()->ok(); |
161 break; | 161 break; |
162 } | 162 } |
163 | 163 |
164 // No interrupts, now wait. | 164 // No interrupts, now wait. |
165 if (use_timeout) { | 165 if (use_timeout) { |
166 current_time = base::TimeTicks::Now(); | 166 current_time = base::TimeTicks::Now(); |
167 if (current_time >= timeout_time) { | 167 if (current_time >= timeout_time) { |
168 result = Smi::FromInt(Result::kTimedOut); | 168 result = isolate->heap()->timed_out(); |
169 break; | 169 break; |
170 } | 170 } |
171 | 171 |
172 base::TimeDelta time_until_timeout = timeout_time - current_time; | 172 base::TimeDelta time_until_timeout = timeout_time - current_time; |
173 DCHECK(time_until_timeout.InMicroseconds() >= 0); | 173 DCHECK(time_until_timeout.InMicroseconds() >= 0); |
174 bool wait_for_result = | 174 bool wait_for_result = |
175 node->cond_.WaitFor(mutex_.Pointer(), time_until_timeout); | 175 node->cond_.WaitFor(mutex_.Pointer(), time_until_timeout); |
176 USE(wait_for_result); | 176 USE(wait_for_result); |
177 } else { | 177 } else { |
178 node->cond_.Wait(mutex_.Pointer()); | 178 node->cond_.Wait(mutex_.Pointer()); |
(...skipping 27 matching lines...) Expand all Loading... |
206 waiters_woken++; | 206 waiters_woken++; |
207 } | 207 } |
208 | 208 |
209 node = node->next_; | 209 node = node->next_; |
210 } | 210 } |
211 | 211 |
212 return Smi::FromInt(waiters_woken); | 212 return Smi::FromInt(waiters_woken); |
213 } | 213 } |
214 | 214 |
215 | 215 |
216 Object* FutexEmulation::WakeOrRequeue(Isolate* isolate, | |
217 Handle<JSArrayBuffer> array_buffer, | |
218 size_t addr, int num_waiters_to_wake, | |
219 int32_t value, size_t addr2) { | |
220 DCHECK(addr < NumberToSize(isolate, array_buffer->byte_length())); | |
221 DCHECK(addr2 < NumberToSize(isolate, array_buffer->byte_length())); | |
222 | |
223 void* backing_store = array_buffer->backing_store(); | |
224 int32_t* p = | |
225 reinterpret_cast<int32_t*>(static_cast<int8_t*>(backing_store) + addr); | |
226 | |
227 base::LockGuard<base::Mutex> lock_guard(mutex_.Pointer()); | |
228 if (*p != value) { | |
229 return Smi::FromInt(Result::kNotEqual); | |
230 } | |
231 | |
232 // Wake |num_waiters_to_wake| | |
233 int waiters_woken = 0; | |
234 FutexWaitListNode* node = wait_list_.Pointer()->head_; | |
235 while (node) { | |
236 if (backing_store == node->backing_store_ && addr == node->wait_addr_) { | |
237 if (num_waiters_to_wake > 0) { | |
238 node->waiting_ = false; | |
239 node->cond_.NotifyOne(); | |
240 --num_waiters_to_wake; | |
241 waiters_woken++; | |
242 } else { | |
243 node->wait_addr_ = addr2; | |
244 } | |
245 } | |
246 | |
247 node = node->next_; | |
248 } | |
249 | |
250 return Smi::FromInt(waiters_woken); | |
251 } | |
252 | |
253 | |
254 Object* FutexEmulation::NumWaitersForTesting(Isolate* isolate, | 216 Object* FutexEmulation::NumWaitersForTesting(Isolate* isolate, |
255 Handle<JSArrayBuffer> array_buffer, | 217 Handle<JSArrayBuffer> array_buffer, |
256 size_t addr) { | 218 size_t addr) { |
257 DCHECK(addr < NumberToSize(isolate, array_buffer->byte_length())); | 219 DCHECK(addr < NumberToSize(isolate, array_buffer->byte_length())); |
258 void* backing_store = array_buffer->backing_store(); | 220 void* backing_store = array_buffer->backing_store(); |
259 | 221 |
260 base::LockGuard<base::Mutex> lock_guard(mutex_.Pointer()); | 222 base::LockGuard<base::Mutex> lock_guard(mutex_.Pointer()); |
261 | 223 |
262 int waiters = 0; | 224 int waiters = 0; |
263 FutexWaitListNode* node = wait_list_.Pointer()->head_; | 225 FutexWaitListNode* node = wait_list_.Pointer()->head_; |
264 while (node) { | 226 while (node) { |
265 if (backing_store == node->backing_store_ && addr == node->wait_addr_ && | 227 if (backing_store == node->backing_store_ && addr == node->wait_addr_ && |
266 node->waiting_) { | 228 node->waiting_) { |
267 waiters++; | 229 waiters++; |
268 } | 230 } |
269 | 231 |
270 node = node->next_; | 232 node = node->next_; |
271 } | 233 } |
272 | 234 |
273 return Smi::FromInt(waiters); | 235 return Smi::FromInt(waiters); |
274 } | 236 } |
275 | 237 |
276 } // namespace internal | 238 } // namespace internal |
277 } // namespace v8 | 239 } // namespace v8 |
OLD | NEW |