Home | History | Annotate | Download | only in runtime
      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 #include "src/runtime/runtime-utils.h"
      6 
      7 #include "src/arguments.h"
      8 #include "src/base/platform/time.h"
      9 #include "src/conversions-inl.h"
     10 #include "src/futex-emulation.h"
     11 #include "src/globals.h"
     12 
     13 // Implement Futex API for SharedArrayBuffers as defined in the
     14 // SharedArrayBuffer draft spec, found here:
     15 // https://github.com/lars-t-hansen/ecmascript_sharedmem
     16 
     17 namespace v8 {
     18 namespace internal {
     19 
     20 RUNTIME_FUNCTION(Runtime_AtomicsFutexWait) {
     21   HandleScope scope(isolate);
     22   DCHECK(args.length() == 4);
     23   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
     24   CONVERT_SIZE_ARG_CHECKED(index, 1);
     25   CONVERT_INT32_ARG_CHECKED(value, 2);
     26   CONVERT_DOUBLE_ARG_CHECKED(timeout, 3);
     27   CHECK(sta->GetBuffer()->is_shared());
     28   CHECK_LT(index, NumberToSize(isolate, sta->length()));
     29   CHECK_EQ(sta->type(), kExternalInt32Array);
     30   CHECK(timeout == V8_INFINITY || !std::isnan(timeout));
     31 
     32   Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
     33   size_t addr = (index << 2) + NumberToSize(isolate, sta->byte_offset());
     34 
     35   return FutexEmulation::Wait(isolate, array_buffer, addr, value, timeout);
     36 }
     37 
     38 
     39 RUNTIME_FUNCTION(Runtime_AtomicsFutexWake) {
     40   HandleScope scope(isolate);
     41   DCHECK(args.length() == 3);
     42   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
     43   CONVERT_SIZE_ARG_CHECKED(index, 1);
     44   CONVERT_INT32_ARG_CHECKED(count, 2);
     45   CHECK(sta->GetBuffer()->is_shared());
     46   CHECK_LT(index, NumberToSize(isolate, sta->length()));
     47   CHECK_EQ(sta->type(), kExternalInt32Array);
     48 
     49   Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
     50   size_t addr = (index << 2) + NumberToSize(isolate, sta->byte_offset());
     51 
     52   return FutexEmulation::Wake(isolate, array_buffer, addr, count);
     53 }
     54 
     55 
     56 RUNTIME_FUNCTION(Runtime_AtomicsFutexWakeOrRequeue) {
     57   HandleScope scope(isolate);
     58   DCHECK(args.length() == 5);
     59   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
     60   CONVERT_SIZE_ARG_CHECKED(index1, 1);
     61   CONVERT_INT32_ARG_CHECKED(count, 2);
     62   CONVERT_INT32_ARG_CHECKED(value, 3);
     63   CONVERT_SIZE_ARG_CHECKED(index2, 4);
     64   CHECK(sta->GetBuffer()->is_shared());
     65   CHECK_LT(index1, NumberToSize(isolate, sta->length()));
     66   CHECK_LT(index2, NumberToSize(isolate, sta->length()));
     67   CHECK_EQ(sta->type(), kExternalInt32Array);
     68 
     69   Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
     70   size_t addr1 = (index1 << 2) + NumberToSize(isolate, sta->byte_offset());
     71   size_t addr2 = (index2 << 2) + NumberToSize(isolate, sta->byte_offset());
     72 
     73   return FutexEmulation::WakeOrRequeue(isolate, array_buffer, addr1, count,
     74                                        value, addr2);
     75 }
     76 
     77 
     78 RUNTIME_FUNCTION(Runtime_AtomicsFutexNumWaitersForTesting) {
     79   HandleScope scope(isolate);
     80   DCHECK(args.length() == 2);
     81   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
     82   CONVERT_SIZE_ARG_CHECKED(index, 1);
     83   CHECK(sta->GetBuffer()->is_shared());
     84   CHECK_LT(index, NumberToSize(isolate, sta->length()));
     85   CHECK_EQ(sta->type(), kExternalInt32Array);
     86 
     87   Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
     88   size_t addr = (index << 2) + NumberToSize(isolate, sta->byte_offset());
     89 
     90   return FutexEmulation::NumWaitersForTesting(isolate, array_buffer, addr);
     91 }
     92 }  // namespace internal
     93 }  // namespace v8
     94