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/tc39/ecmascript_sharedmem
16 
17 namespace v8 {
18 namespace internal {
19 
RUNTIME_FUNCTION(Runtime_AtomicsWait)20 RUNTIME_FUNCTION(Runtime_AtomicsWait) {
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(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(sta->byte_offset());
34 
35   return FutexEmulation::Wait(isolate, array_buffer, addr, value, timeout);
36 }
37 
RUNTIME_FUNCTION(Runtime_AtomicsWake)38 RUNTIME_FUNCTION(Runtime_AtomicsWake) {
39   HandleScope scope(isolate);
40   DCHECK(args.length() == 3);
41   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
42   CONVERT_SIZE_ARG_CHECKED(index, 1);
43   CONVERT_INT32_ARG_CHECKED(count, 2);
44   CHECK(sta->GetBuffer()->is_shared());
45   CHECK_LT(index, NumberToSize(sta->length()));
46   CHECK_EQ(sta->type(), kExternalInt32Array);
47 
48   Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
49   size_t addr = (index << 2) + NumberToSize(sta->byte_offset());
50 
51   return FutexEmulation::Wake(isolate, array_buffer, addr, count);
52 }
53 
RUNTIME_FUNCTION(Runtime_AtomicsNumWaitersForTesting)54 RUNTIME_FUNCTION(Runtime_AtomicsNumWaitersForTesting) {
55   HandleScope scope(isolate);
56   DCHECK(args.length() == 2);
57   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
58   CONVERT_SIZE_ARG_CHECKED(index, 1);
59   CHECK(sta->GetBuffer()->is_shared());
60   CHECK_LT(index, NumberToSize(sta->length()));
61   CHECK_EQ(sta->type(), kExternalInt32Array);
62 
63   Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
64   size_t addr = (index << 2) + NumberToSize(sta->byte_offset());
65 
66   return FutexEmulation::NumWaitersForTesting(isolate, array_buffer, addr);
67 }
68 }  // namespace internal
69 }  // namespace v8
70