| 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 |