diff --git a/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-no-operation.js b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-no-operation.js
new file mode 100644
index 0000000000..175efad849
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-no-operation.js
@@ -0,0 +1,71 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-atomics.waitasync
+description: >
+  Test that Atomics.waitAsync returns the right result when it timed out and that
+  the time to time out is reasonable.
+info: |
+  AddWaiter ( WL, waiterRecord )
+
+  5. Append waiterRecord as the last element of WL.[[Waiters]]
+  6. If waiterRecord.[[Timeout]] is finite, then in parallel,
+    a. Wait waiterRecord.[[Timeout]] milliseconds.
+    b. Perform TriggerTimeout(WL, waiterRecord).
+
+  TriggerTimeout( WL, waiterRecord )
+
+  3. If waiterRecord is in WL.[[Waiters]], then
+    a. Set waiterRecord.[[Result]] to "timed-out".
+    b. Perform RemoveWaiter(WL, waiterRecord).
+    c. Perform NotifyWaiter(WL, waiterRecord).
+  4. Perform LeaveCriticalSection(WL).
+
+includes: [atomicsHelper.js]
+features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics]
+---*/
+
+const RUNNING = 1;
+const TIMEOUT = $262.agent.timeouts.small;
+
+const i32a = new Int32Array(
+  new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)
+);
+
+$262.agent.start(`
+  $262.agent.receiveBroadcast(async (sab, id) => {
+    const i32a = new Int32Array(sab);
+    Atomics.add(i32a, ${RUNNING}, 1);
+
+    const before = $262.agent.monotonicNow();
+    const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value;
+    const duration = $262.agent.monotonicNow() - before;
+    $262.agent.report(duration);
+    $262.agent.report(unpark);
+    $262.agent.leaving();
+  });
+`);
+
+$262.agent.safeBroadcast(i32a);
+$262.agent.waitUntil(i32a, RUNNING, 1);
+$262.agent.tryYield();
+
+// NO OPERATION OCCURS HERE!
+
+assert(
+  $262.agent.getReport() >= TIMEOUT,
+  'The result of `(lapse >= TIMEOUT)` is true'
+);
+
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.wait(i32a, 0, 0, ${TIMEOUT}).value resolves to "timed-out"'
+);
+
+assert.sameValue(
+  Atomics.notify(i32a, 0),
+  0,
+  'Atomics.notify(i32a, 0) returns 0'
+);
diff --git a/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-add.js b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-add.js
new file mode 100644
index 0000000000..fcdcf4c824
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-add.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-atomics.waitasync
+description: >
+  Waiter does not spuriously notify on index which is subject to Add operation
+info: |
+  AddWaiter ( WL, waiterRecord )
+
+  5. Append waiterRecord as the last element of WL.[[Waiters]]
+  6. If waiterRecord.[[Timeout]] is finite, then in parallel,
+    a. Wait waiterRecord.[[Timeout]] milliseconds.
+    b. Perform TriggerTimeout(WL, waiterRecord).
+
+  TriggerTimeout( WL, waiterRecord )
+
+  3. If waiterRecord is in WL.[[Waiters]], then
+    a. Set waiterRecord.[[Result]] to "timed-out".
+    b. Perform RemoveWaiter(WL, waiterRecord).
+    c. Perform NotifyWaiter(WL, waiterRecord).
+  4. Perform LeaveCriticalSection(WL).
+
+includes: [atomicsHelper.js]
+features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics]
+---*/
+
+const RUNNING = 1;
+const TIMEOUT = $262.agent.timeouts.small;
+
+const i32a = new Int32Array(
+  new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)
+);
+
+$262.agent.start(`
+  $262.agent.receiveBroadcast(async (sab, id) => {
+    const i32a = new Int32Array(sab);
+    Atomics.add(i32a, ${RUNNING}, 1);
+
+    const before = $262.agent.monotonicNow();
+    const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value;
+    const duration = $262.agent.monotonicNow() - before;
+    $262.agent.report(duration);
+    $262.agent.report(unpark);
+    $262.agent.leaving();
+  });
+`);
+
+$262.agent.safeBroadcast(i32a);
+$262.agent.waitUntil(i32a, RUNNING, 1);
+$262.agent.tryYield();
+
+Atomics.add(i32a, 0, 1);
+
+assert(
+  $262.agent.getReport() >= TIMEOUT,
+  'The result of `(lapse >= TIMEOUT)` is true'
+);
+
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.wait(i32a, 0, 0, ${TIMEOUT}).value resolves to "timed-out"'
+);
+
+assert.sameValue(
+  Atomics.notify(i32a, 0),
+  0,
+  'Atomics.notify(i32a, 0) returns 0'
+);
diff --git a/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-and.js b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-and.js
new file mode 100644
index 0000000000..fbef19cbcc
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-and.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-atomics.waitasync
+description: >
+  Waiter does not spuriously notify on index which is subject to And operation
+info: |
+  AddWaiter ( WL, waiterRecord )
+
+  5. Append waiterRecord as the last element of WL.[[Waiters]]
+  6. If waiterRecord.[[Timeout]] is finite, then in parallel,
+    a. Wait waiterRecord.[[Timeout]] milliseconds.
+    b. Perform TriggerTimeout(WL, waiterRecord).
+
+  TriggerTimeout( WL, waiterRecord )
+
+  3. If waiterRecord is in WL.[[Waiters]], then
+    a. Set waiterRecord.[[Result]] to "timed-out".
+    b. Perform RemoveWaiter(WL, waiterRecord).
+    c. Perform NotifyWaiter(WL, waiterRecord).
+  4. Perform LeaveCriticalSection(WL).
+
+includes: [atomicsHelper.js]
+features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics]
+---*/
+
+const RUNNING = 1;
+const TIMEOUT = $262.agent.timeouts.small;
+
+const i32a = new Int32Array(
+  new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)
+);
+
+$262.agent.start(`
+  $262.agent.receiveBroadcast(async (sab, id) => {
+    const i32a = new Int32Array(sab);
+    Atomics.add(i32a, ${RUNNING}, 1);
+
+    const before = $262.agent.monotonicNow();
+    const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value;
+    const duration = $262.agent.monotonicNow() - before;
+    $262.agent.report(duration);
+    $262.agent.report(unpark);
+    $262.agent.leaving();
+  });
+`);
+
+$262.agent.safeBroadcast(i32a);
+$262.agent.waitUntil(i32a, RUNNING, 1);
+$262.agent.tryYield();
+
+Atomics.and(i32a, 0, 1);
+
+assert(
+  $262.agent.getReport() >= TIMEOUT,
+  'The result of `(lapse >= TIMEOUT)` is true'
+);
+
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.wait(i32a, 0, 0, ${TIMEOUT}).value resolves to "timed-out"'
+);
+
+assert.sameValue(
+  Atomics.notify(i32a, 0),
+  0,
+  'Atomics.notify(i32a, 0) returns 0'
+);
diff --git a/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-compareExchange.js b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-compareExchange.js
new file mode 100644
index 0000000000..ca2e858032
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-compareExchange.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-atomics.waitasync
+description: >
+  Waiter does not spuriously notify on index which is subject to compareExchange operation
+info: |
+  AddWaiter ( WL, waiterRecord )
+
+  5. Append waiterRecord as the last element of WL.[[Waiters]]
+  6. If waiterRecord.[[Timeout]] is finite, then in parallel,
+    a. Wait waiterRecord.[[Timeout]] milliseconds.
+    b. Perform TriggerTimeout(WL, waiterRecord).
+
+  TriggerTimeout( WL, waiterRecord )
+
+  3. If waiterRecord is in WL.[[Waiters]], then
+    a. Set waiterRecord.[[Result]] to "timed-out".
+    b. Perform RemoveWaiter(WL, waiterRecord).
+    c. Perform NotifyWaiter(WL, waiterRecord).
+  4. Perform LeaveCriticalSection(WL).
+
+includes: [atomicsHelper.js]
+features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics]
+---*/
+
+const RUNNING = 1;
+const TIMEOUT = $262.agent.timeouts.small;
+
+const i32a = new Int32Array(
+  new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)
+);
+
+$262.agent.start(`
+  $262.agent.receiveBroadcast(async (sab, id) => {
+    const i32a = new Int32Array(sab);
+    Atomics.add(i32a, ${RUNNING}, 1);
+
+    const before = $262.agent.monotonicNow();
+    const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value;
+    const duration = $262.agent.monotonicNow() - before;
+    $262.agent.report(duration);
+    $262.agent.report(unpark);
+    $262.agent.leaving();
+  });
+`);
+
+$262.agent.safeBroadcast(i32a);
+$262.agent.waitUntil(i32a, RUNNING, 1);
+$262.agent.tryYield();
+
+Atomics.compareExchange(i32a, 0, 0, 1);
+
+assert(
+  $262.agent.getReport() >= TIMEOUT,
+  'The result of `(lapse >= TIMEOUT)` is true'
+);
+
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.wait(i32a, 0, 0, ${TIMEOUT}).value resolves to "timed-out"'
+);
+
+assert.sameValue(
+  Atomics.notify(i32a, 0),
+  0,
+  'Atomics.notify(i32a, 0) returns 0'
+);
diff --git a/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-exchange.js b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-exchange.js
new file mode 100644
index 0000000000..a945fef6e8
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-exchange.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-atomics.waitasync
+description: >
+  Waiter does not spuriously notify on index which is subject to exchange operation
+info: |
+  AddWaiter ( WL, waiterRecord )
+
+  5. Append waiterRecord as the last element of WL.[[Waiters]]
+  6. If waiterRecord.[[Timeout]] is finite, then in parallel,
+    a. Wait waiterRecord.[[Timeout]] milliseconds.
+    b. Perform TriggerTimeout(WL, waiterRecord).
+
+  TriggerTimeout( WL, waiterRecord )
+
+  3. If waiterRecord is in WL.[[Waiters]], then
+    a. Set waiterRecord.[[Result]] to "timed-out".
+    b. Perform RemoveWaiter(WL, waiterRecord).
+    c. Perform NotifyWaiter(WL, waiterRecord).
+  4. Perform LeaveCriticalSection(WL).
+
+includes: [atomicsHelper.js]
+features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics]
+---*/
+
+const RUNNING = 1;
+const TIMEOUT = $262.agent.timeouts.small;
+
+const i32a = new Int32Array(
+  new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)
+);
+
+$262.agent.start(`
+  $262.agent.receiveBroadcast(async (sab, id) => {
+    const i32a = new Int32Array(sab);
+    Atomics.add(i32a, ${RUNNING}, 1);
+
+    const before = $262.agent.monotonicNow();
+    const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value;
+    const duration = $262.agent.monotonicNow() - before;
+    $262.agent.report(duration);
+    $262.agent.report(unpark);
+    $262.agent.leaving();
+  });
+`);
+
+$262.agent.safeBroadcast(i32a);
+$262.agent.waitUntil(i32a, RUNNING, 1);
+$262.agent.tryYield();
+
+Atomics.exchange(i32a, 0, 1);
+
+assert(
+  $262.agent.getReport() >= TIMEOUT,
+  'The result of `(lapse >= TIMEOUT)` is true'
+);
+
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.wait(i32a, 0, 0, ${TIMEOUT}).value resolves to "timed-out"'
+);
+
+assert.sameValue(
+  Atomics.notify(i32a, 0),
+  0,
+  'Atomics.notify(i32a, 0) returns 0'
+);
diff --git a/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-or.js b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-or.js
new file mode 100644
index 0000000000..89cc22af73
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-or.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-atomics.waitasync
+description: >
+  Waiter does not spuriously notify on index which is subject to Or operation
+info: |
+  AddWaiter ( WL, waiterRecord )
+
+  5. Append waiterRecord as the last element of WL.[[Waiters]]
+  6. If waiterRecord.[[Timeout]] is finite, then in parallel,
+    a. Wait waiterRecord.[[Timeout]] milliseconds.
+    b. Perform TriggerTimeout(WL, waiterRecord).
+
+  TriggerTimeout( WL, waiterRecord )
+
+  3. If waiterRecord is in WL.[[Waiters]], then
+    a. Set waiterRecord.[[Result]] to "timed-out".
+    b. Perform RemoveWaiter(WL, waiterRecord).
+    c. Perform NotifyWaiter(WL, waiterRecord).
+  4. Perform LeaveCriticalSection(WL).
+
+includes: [atomicsHelper.js]
+features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics]
+---*/
+
+const RUNNING = 1;
+const TIMEOUT = $262.agent.timeouts.small;
+
+const i32a = new Int32Array(
+  new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)
+);
+
+$262.agent.start(`
+  $262.agent.receiveBroadcast(async (sab, id) => {
+    const i32a = new Int32Array(sab);
+    Atomics.add(i32a, ${RUNNING}, 1);
+
+    const before = $262.agent.monotonicNow();
+    const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value;
+    const duration = $262.agent.monotonicNow() - before;
+    $262.agent.report(duration);
+    $262.agent.report(unpark);
+    $262.agent.leaving();
+  });
+`);
+
+$262.agent.safeBroadcast(i32a);
+$262.agent.waitUntil(i32a, RUNNING, 1);
+$262.agent.tryYield();
+
+Atomics.or(i32a, 0, 1);
+
+assert(
+  $262.agent.getReport() >= TIMEOUT,
+  'The result of `(lapse >= TIMEOUT)` is true'
+);
+
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.wait(i32a, 0, 0, ${TIMEOUT}).value resolves to "timed-out"'
+);
+
+assert.sameValue(
+  Atomics.notify(i32a, 0),
+  0,
+  'Atomics.notify(i32a, 0) returns 0'
+);
diff --git a/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-store.js b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-store.js
new file mode 100644
index 0000000000..a8907be7a4
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-store.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-atomics.waitasync
+description: >
+  Waiter does not spuriously notify on index which is subject to Store operation
+info: |
+  AddWaiter ( WL, waiterRecord )
+
+  5. Append waiterRecord as the last element of WL.[[Waiters]]
+  6. If waiterRecord.[[Timeout]] is finite, then in parallel,
+    a. Wait waiterRecord.[[Timeout]] milliseconds.
+    b. Perform TriggerTimeout(WL, waiterRecord).
+
+  TriggerTimeout( WL, waiterRecord )
+
+  3. If waiterRecord is in WL.[[Waiters]], then
+    a. Set waiterRecord.[[Result]] to "timed-out".
+    b. Perform RemoveWaiter(WL, waiterRecord).
+    c. Perform NotifyWaiter(WL, waiterRecord).
+  4. Perform LeaveCriticalSection(WL).
+
+includes: [atomicsHelper.js]
+features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics]
+---*/
+
+const RUNNING = 1;
+const TIMEOUT = $262.agent.timeouts.small;
+
+const i32a = new Int32Array(
+  new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)
+);
+
+$262.agent.start(`
+  $262.agent.receiveBroadcast(async (sab, id) => {
+    const i32a = new Int32Array(sab);
+    Atomics.add(i32a, ${RUNNING}, 1);
+
+    const before = $262.agent.monotonicNow();
+    const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value;
+    const duration = $262.agent.monotonicNow() - before;
+    $262.agent.report(duration);
+    $262.agent.report(unpark);
+    $262.agent.leaving();
+  });
+`);
+
+$262.agent.safeBroadcast(i32a);
+$262.agent.waitUntil(i32a, RUNNING, 1);
+$262.agent.tryYield();
+
+Atomics.store(i32a, 0, 0x111111);
+
+assert(
+  $262.agent.getReport() >= TIMEOUT,
+  'The result of `(lapse >= TIMEOUT)` is true'
+);
+
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.wait(i32a, 0, 0, ${TIMEOUT}).value resolves to "timed-out"'
+);
+
+assert.sameValue(
+  Atomics.notify(i32a, 0),
+  0,
+  'Atomics.notify(i32a, 0) returns 0'
+);
diff --git a/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-sub.js b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-sub.js
new file mode 100644
index 0000000000..a40475170e
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-sub.js
@@ -0,0 +1,71 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-atomics.waitasync
+description: >
+  Waiter does not spuriously notify on index which is subject to Sub operation
+info: |
+
+  AddWaiter ( WL, waiterRecord )
+
+  5. Append waiterRecord as the last element of WL.[[Waiters]]
+  6. If waiterRecord.[[Timeout]] is finite, then in parallel,
+    a. Wait waiterRecord.[[Timeout]] milliseconds.
+    b. Perform TriggerTimeout(WL, waiterRecord).
+
+  TriggerTimeout( WL, waiterRecord )
+
+  3. If waiterRecord is in WL.[[Waiters]], then
+    a. Set waiterRecord.[[Result]] to "timed-out".
+    b. Perform RemoveWaiter(WL, waiterRecord).
+    c. Perform NotifyWaiter(WL, waiterRecord).
+  4. Perform LeaveCriticalSection(WL).
+
+includes: [atomicsHelper.js]
+features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics]
+---*/
+
+const RUNNING = 1;
+const TIMEOUT = $262.agent.timeouts.small;
+
+const i32a = new Int32Array(
+  new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)
+);
+
+$262.agent.start(`
+  $262.agent.receiveBroadcast(async (sab, id) => {
+    const i32a = new Int32Array(sab);
+    Atomics.add(i32a, ${RUNNING}, 1);
+
+    const before = $262.agent.monotonicNow();
+    const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value;
+    const duration = $262.agent.monotonicNow() - before;
+    $262.agent.report(duration);
+    $262.agent.report(unpark);
+    $262.agent.leaving();
+  });
+`);
+
+$262.agent.safeBroadcast(i32a);
+$262.agent.waitUntil(i32a, RUNNING, 1);
+$262.agent.tryYield();
+
+Atomics.sub(i32a, 0, 1);
+
+assert(
+  $262.agent.getReport() >= TIMEOUT,
+  'The result of `(lapse >= TIMEOUT)` is true'
+);
+
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.wait(i32a, 0, 0, ${TIMEOUT}).value resolves to "timed-out"'
+);
+
+assert.sameValue(
+  Atomics.notify(i32a, 0),
+  0,
+  'Atomics.notify(i32a, 0) returns 0'
+);
diff --git a/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-xor.js b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-xor.js
new file mode 100644
index 0000000000..66fcdaac9a
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-xor.js
@@ -0,0 +1,71 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-atomics.waitasync
+description: >
+  Waiter does not spuriously notify on index which is subject to xor operation
+info: |
+
+  AddWaiter ( WL, waiterRecord )
+
+  5. Append waiterRecord as the last element of WL.[[Waiters]]
+  6. If waiterRecord.[[Timeout]] is finite, then in parallel,
+    a. Wait waiterRecord.[[Timeout]] milliseconds.
+    b. Perform TriggerTimeout(WL, waiterRecord).
+
+  TriggerTimeout( WL, waiterRecord )
+
+  3. If waiterRecord is in WL.[[Waiters]], then
+    a. Set waiterRecord.[[Result]] to "timed-out".
+    b. Perform RemoveWaiter(WL, waiterRecord).
+    c. Perform NotifyWaiter(WL, waiterRecord).
+  4. Perform LeaveCriticalSection(WL).
+
+includes: [atomicsHelper.js]
+features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics]
+---*/
+
+const RUNNING = 1;
+const TIMEOUT = $262.agent.timeouts.small;
+
+const i32a = new Int32Array(
+  new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)
+);
+
+$262.agent.start(`
+  $262.agent.receiveBroadcast(async (sab, id) => {
+    const i32a = new Int32Array(sab);
+    Atomics.add(i32a, ${RUNNING}, 1);
+
+    const before = $262.agent.monotonicNow();
+    const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value;
+    const duration = $262.agent.monotonicNow() - before;
+    $262.agent.report(duration);
+    $262.agent.report(unpark);
+    $262.agent.leaving();
+  });
+`);
+
+$262.agent.safeBroadcast(i32a);
+$262.agent.waitUntil(i32a, RUNNING, 1);
+$262.agent.tryYield();
+
+Atomics.xor(i32a, 0, 1);
+
+assert(
+  $262.agent.getReport() >= TIMEOUT,
+  'The result of `(lapse >= TIMEOUT)` is true'
+);
+
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.wait(i32a, 0, 0, ${TIMEOUT}).value resolves to "timed-out"'
+);
+
+assert.sameValue(
+  Atomics.notify(i32a, 0),
+  0,
+  'Atomics.notify(i32a, 0) returns 0'
+);