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