Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
[Atomics] Rename Atomics.futex*, remove Atomics.futexWakeOrRequeue
Browse files Browse the repository at this point in the history
* Rename Atomics.futexWait -> Atomics.wait
* Rename Atomics.futexWake -> Atomics.wake
* Remove Atomics.futexWakeOrRequeue
* Return value of Atomics.wait is now a string: "ok", "not-equal" or
  "timed-out"
* Update comments that reference URL for ecmascript_sharedmem to
  https://github.com/tc39/ecmascript_sharedmem

Review-Url: https://codereview.chromium.org/2143443002
Cr-Commit-Position: refs/heads/master@{#37727}
  • Loading branch information
binji authored and Commit bot committed Jul 13, 2016
1 parent 906cb20 commit a16ca01
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 290 deletions.
44 changes: 3 additions & 41 deletions src/futex-emulation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Object* FutexEmulation::Wait(Isolate* isolate,
base::LockGuard<base::Mutex> lock_guard(mutex_.Pointer());

if (*p != value) {
return Smi::FromInt(Result::kNotEqual);
return isolate->heap()->not_equal();
}

FutexWaitListNode* node = isolate->futex_wait_list_node();
Expand Down Expand Up @@ -157,15 +157,15 @@ Object* FutexEmulation::Wait(Isolate* isolate,
}

if (!node->waiting_) {
result = Smi::FromInt(Result::kOk);
result = isolate->heap()->ok();
break;
}

// No interrupts, now wait.
if (use_timeout) {
current_time = base::TimeTicks::Now();
if (current_time >= timeout_time) {
result = Smi::FromInt(Result::kTimedOut);
result = isolate->heap()->timed_out();
break;
}

Expand Down Expand Up @@ -213,44 +213,6 @@ Object* FutexEmulation::Wake(Isolate* isolate,
}


Object* FutexEmulation::WakeOrRequeue(Isolate* isolate,
Handle<JSArrayBuffer> array_buffer,
size_t addr, int num_waiters_to_wake,
int32_t value, size_t addr2) {
DCHECK(addr < NumberToSize(isolate, array_buffer->byte_length()));
DCHECK(addr2 < NumberToSize(isolate, array_buffer->byte_length()));

void* backing_store = array_buffer->backing_store();
int32_t* p =
reinterpret_cast<int32_t*>(static_cast<int8_t*>(backing_store) + addr);

base::LockGuard<base::Mutex> lock_guard(mutex_.Pointer());
if (*p != value) {
return Smi::FromInt(Result::kNotEqual);
}

// Wake |num_waiters_to_wake|
int waiters_woken = 0;
FutexWaitListNode* node = wait_list_.Pointer()->head_;
while (node) {
if (backing_store == node->backing_store_ && addr == node->wait_addr_) {
if (num_waiters_to_wake > 0) {
node->waiting_ = false;
node->cond_.NotifyOne();
--num_waiters_to_wake;
waiters_woken++;
} else {
node->wait_addr_ = addr2;
}
}

node = node->next_;
}

return Smi::FromInt(waiters_woken);
}


Object* FutexEmulation::NumWaitersForTesting(Isolate* isolate,
Handle<JSArrayBuffer> array_buffer,
size_t addr) {
Expand Down
23 changes: 3 additions & 20 deletions src/futex-emulation.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// variables for consistency.
//
// This is used by the Futex API defined in the SharedArrayBuffer draft spec,
// found here: https://github.com/lars-t-hansen/ecmascript_sharedmem
// found here: https://github.com/tc39/ecmascript_sharedmem

namespace v8 {

Expand Down Expand Up @@ -81,18 +81,11 @@ class FutexWaitList {

class FutexEmulation : public AllStatic {
public:
// These must match the values in src/harmony-atomics.js
enum Result {
kOk = 0,
kNotEqual = -1,
kTimedOut = -2,
};

// Check that array_buffer[addr] == value, and return kNotEqual if not. If
// Check that array_buffer[addr] == value, and return "not-equal" if not. If
// they are equal, block execution on |isolate|'s thread until woken via
// |Wake|, or when the time given in |rel_timeout_ms| elapses. Note that
// |rel_timeout_ms| can be Infinity.
// If woken, return kOk, otherwise return kTimedOut. The initial check and
// If woken, return "ok", otherwise return "timed-out". The initial check and
// the decision to wait happen atomically.
static Object* Wait(Isolate* isolate, Handle<JSArrayBuffer> array_buffer,
size_t addr, int32_t value, double rel_timeout_ms);
Expand All @@ -103,16 +96,6 @@ class FutexEmulation : public AllStatic {
static Object* Wake(Isolate* isolate, Handle<JSArrayBuffer> array_buffer,
size_t addr, int num_waiters_to_wake);

// Check that array_buffer[addr] == value, and return kNotEqual if not. If
// they are equal, wake |num_waiters_to_wake| threads that are waiting on the
// given |addr|. The rest of the waiters will continue to wait, but will now
// be waiting on |addr2| instead of |addr|. The return value is the number of
// woken waiters or kNotEqual as described above.
static Object* WakeOrRequeue(Isolate* isolate,
Handle<JSArrayBuffer> array_buffer, size_t addr,
int num_waiters_to_wake, int32_t value,
size_t addr2);

// Return the number of threads waiting on |addr|. Should only be used for
// testing.
static Object* NumWaitersForTesting(Isolate* isolate,
Expand Down
3 changes: 3 additions & 0 deletions src/heap-symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,14 @@
V(name_string, "name") \
V(nan_string, "NaN") \
V(next_string, "next") \
V(not_equal, "not-equal") \
V(null_string, "null") \
V(null_to_string, "[object Null]") \
V(number_string, "number") \
V(Number_string, "Number") \
V(object_string, "object") \
V(Object_string, "Object") \
V(ok, "ok") \
V(ownKeys_string, "ownKeys") \
V(position_string, "position") \
V(preventExtensions_string, "preventExtensions") \
Expand All @@ -129,6 +131,7 @@
V(Symbol_string, "Symbol") \
V(this_string, "this") \
V(throw_string, "throw") \
V(timed_out, "timed-out") \
V(toJSON_string, "toJSON") \
V(toString_string, "toString") \
V(true_string, "true") \
Expand Down
35 changes: 6 additions & 29 deletions src/js/harmony-atomics.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,7 @@ function AtomicsIsLockFreeJS(size) {
return %_AtomicsIsLockFree(size);
}

// Futexes

function AtomicsFutexWaitJS(ia, index, value, timeout) {
function AtomicsWaitJS(ia, index, value, timeout) {
CheckSharedInteger32TypedArray(ia);
index = ValidateIndex(index, %_TypedArrayGetLength(ia));
if (IS_UNDEFINED(timeout)) {
Expand All @@ -123,27 +121,14 @@ function AtomicsFutexWaitJS(ia, index, value, timeout) {
timeout = MaxSimple(0, timeout);
}
}
return %AtomicsFutexWait(ia, index, value, timeout);
return %AtomicsWait(ia, index, value, timeout);
}

function AtomicsFutexWakeJS(ia, index, count) {
function AtomicsWakeJS(ia, index, count) {
CheckSharedInteger32TypedArray(ia);
index = ValidateIndex(index, %_TypedArrayGetLength(ia));
count = MaxSimple(0, TO_INTEGER(count));
return %AtomicsFutexWake(ia, index, count);
}

function AtomicsFutexWakeOrRequeueJS(ia, index1, count, value, index2) {
CheckSharedInteger32TypedArray(ia);
index1 = ValidateIndex(index1, %_TypedArrayGetLength(ia));
count = MaxSimple(0, TO_INTEGER(count));
value = TO_INT32(value);
index2 = ValidateIndex(index2, %_TypedArrayGetLength(ia));
if (index1 < 0 || index1 >= %_TypedArrayGetLength(ia) ||
index2 < 0 || index2 >= %_TypedArrayGetLength(ia)) {
return UNDEFINED;
}
return %AtomicsFutexWakeOrRequeue(ia, index1, count, value, index2);
return %AtomicsWake(ia, index, count);
}

// -------------------------------------------------------------------
Expand All @@ -154,13 +139,6 @@ var Atomics = global.Atomics;

%AddNamedProperty(Atomics, toStringTagSymbol, "Atomics", READ_ONLY | DONT_ENUM);

// These must match the values in src/futex-emulation.h
utils.InstallConstants(Atomics, [
"OK", 0,
"NOTEQUAL", -1,
"TIMEDOUT", -2,
]);

utils.InstallFunctions(Atomics, DONT_ENUM, [
// TODO(binji): remove the rest of the (non futex) Atomics functions as they
// become builtins.
Expand All @@ -172,9 +150,8 @@ utils.InstallFunctions(Atomics, DONT_ENUM, [
"xor", AtomicsXorJS,
"exchange", AtomicsExchangeJS,
"isLockFree", AtomicsIsLockFreeJS,
"futexWait", AtomicsFutexWaitJS,
"futexWake", AtomicsFutexWakeJS,
"futexWakeOrRequeue", AtomicsFutexWakeOrRequeueJS,
"wait", AtomicsWaitJS,
"wake", AtomicsWakeJS,
]);

})
2 changes: 1 addition & 1 deletion src/runtime/runtime-atomics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

// Implement Atomic accesses to SharedArrayBuffers as defined in the
// SharedArrayBuffer draft spec, found here
// https://github.com/lars-t-hansen/ecmascript_sharedmem
// https://github.com/tc39/ecmascript_sharedmem

namespace v8 {
namespace internal {
Expand Down
32 changes: 4 additions & 28 deletions src/runtime/runtime-futex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@

// Implement Futex API for SharedArrayBuffers as defined in the
// SharedArrayBuffer draft spec, found here:
// https://github.com/lars-t-hansen/ecmascript_sharedmem
// https://github.com/tc39/ecmascript_sharedmem

namespace v8 {
namespace internal {

RUNTIME_FUNCTION(Runtime_AtomicsFutexWait) {
RUNTIME_FUNCTION(Runtime_AtomicsWait) {
HandleScope scope(isolate);
DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
Expand All @@ -35,8 +35,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsFutexWait) {
return FutexEmulation::Wait(isolate, array_buffer, addr, value, timeout);
}


RUNTIME_FUNCTION(Runtime_AtomicsFutexWake) {
RUNTIME_FUNCTION(Runtime_AtomicsWake) {
HandleScope scope(isolate);
DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
Expand All @@ -52,30 +51,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsFutexWake) {
return FutexEmulation::Wake(isolate, array_buffer, addr, count);
}


RUNTIME_FUNCTION(Runtime_AtomicsFutexWakeOrRequeue) {
HandleScope scope(isolate);
DCHECK(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
CONVERT_SIZE_ARG_CHECKED(index1, 1);
CONVERT_INT32_ARG_CHECKED(count, 2);
CONVERT_INT32_ARG_CHECKED(value, 3);
CONVERT_SIZE_ARG_CHECKED(index2, 4);
CHECK(sta->GetBuffer()->is_shared());
CHECK_LT(index1, NumberToSize(isolate, sta->length()));
CHECK_LT(index2, NumberToSize(isolate, sta->length()));
CHECK_EQ(sta->type(), kExternalInt32Array);

Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
size_t addr1 = (index1 << 2) + NumberToSize(isolate, sta->byte_offset());
size_t addr2 = (index2 << 2) + NumberToSize(isolate, sta->byte_offset());

return FutexEmulation::WakeOrRequeue(isolate, array_buffer, addr1, count,
value, addr2);
}


RUNTIME_FUNCTION(Runtime_AtomicsFutexNumWaitersForTesting) {
RUNTIME_FUNCTION(Runtime_AtomicsNumWaitersForTesting) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
Expand Down
12 changes: 4 additions & 8 deletions src/runtime/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,10 @@ namespace internal {
F(AtomicsOr, 3, 1) \
F(AtomicsXor, 3, 1) \
F(AtomicsExchange, 3, 1) \
F(AtomicsIsLockFree, 1, 1)

#define FOR_EACH_INTRINSIC_FUTEX(F) \
F(AtomicsFutexWait, 4, 1) \
F(AtomicsFutexWake, 3, 1) \
F(AtomicsFutexWakeOrRequeue, 5, 1) \
F(AtomicsFutexNumWaitersForTesting, 2, 1)
F(AtomicsIsLockFree, 1, 1) \
F(AtomicsWait, 4, 1) \
F(AtomicsWake, 3, 1) \
F(AtomicsNumWaitersForTesting, 2, 1)

#define FOR_EACH_INTRINSIC_CLASSES(F) \
F(ThrowNonMethodError, 0, 1) \
Expand Down Expand Up @@ -966,7 +963,6 @@ namespace internal {
FOR_EACH_INTRINSIC_FORIN(F) \
FOR_EACH_INTRINSIC_INTERPRETER(F) \
FOR_EACH_INTRINSIC_FUNCTION(F) \
FOR_EACH_INTRINSIC_FUTEX(F) \
FOR_EACH_INTRINSIC_GENERATOR(F) \
FOR_EACH_INTRINSIC_I18N(F) \
FOR_EACH_INTRINSIC_INTERNAL(F) \
Expand Down
2 changes: 1 addition & 1 deletion test/cctest/test-api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25043,7 +25043,7 @@ TEST(FutexInterruption) {
CompileRun(
"var ab = new SharedArrayBuffer(4);"
"var i32a = new Int32Array(ab);"
"Atomics.futexWait(i32a, 0, 0);");
"Atomics.wait(i32a, 0, 0);");
CHECK(try_catch.HasTerminated());
timeout_thread.Join();
}
Expand Down
Loading

0 comments on commit a16ca01

Please sign in to comment.