Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example of using compareExchange return value #33972

Merged
merged 1 commit into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Atomics.compareExchange(typedArray, index, expectedValue, replacementValue)

### Return value

The old value at the given position (`typedArray[index]`).
The old value at the given position (`typedArray[index]`). If the return value is equal to `expectedValue`, the exchange was successful; otherwise, the exchange failed.

### Exceptions

Expand All @@ -52,6 +52,25 @@ Atomics.compareExchange(ta, 0, 7, 12); // returns 7, the old value
Atomics.load(ta, 0); // 12
```

### Checking the return value

[Compare-and-swap](https://en.wikipedia.org/wiki/Compare-and-swap) guarantees that the new value is calculated based on up-to-date information; if the value had been updated by another thread in the meantime, the write would fail. Therefore, you should check the return value of `compareExchange()` to check if it has failed, and retry if necessary.

Here is one example of an atomic adder (same functionality as {{jsxref("Atomics.add()")}}), adapted from the linked Wikipedia article:

```js
function add(mem, index, value) {
let done = false;
while (!done) {
const value = Atomics.load(mem, index);
done = Atomics.compareExchange(p, value, value + a) === value;
}
return value + a;
}
```

It first reads the value at the given index, then tries to update it with the new value. It keeps retrying until it successfully updates the value.

## Specifications

{{Specifications}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@ browser-compat: javascript.builtins.Atomics.isLockFree

{{JSRef}}

The **`Atomics.isLockFree()`** static
method is used to determine whether the `Atomics` methods use locks
or atomic hardware operations when applied to typed arrays with the given element
byte size.
It returns `false` if the given size is not one of the [BYTES_PER_ELEMENT](/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT)
property of integer TypedArray types.
The **`Atomics.isLockFree()`** static method is used to determine whether the `Atomics` methods use locks or atomic hardware operations when applied to typed arrays with the given element byte size. It is intended as an optimization primitive, so that high-performance algorithms can determine whether to use locks or atomic operations in critical sections. If an atomic primitive is not lock-free, it is often more efficient for an algorithm to provide its own locking.

{{EmbedInteractiveExample("pages/js/atomics-islockfree.html")}}

Expand All @@ -31,19 +26,22 @@ Atomics.isLockFree(size)

A `true` or `false` value indicating whether the operation is lock free.

- Always `true` if `size` is 4, because all known platforms support 4-byte atomic operations.
- Always `false` if the given size is not one of the [`BYTES_PER_ELEMENT`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT) property of integer TypedArray types.

## Examples

### Using isLockFree

```js
Atomics.isLockFree(1); // true
Atomics.isLockFree(2); // true
Atomics.isLockFree(1); // true (platform-dependent)
Atomics.isLockFree(2); // true (platform-dependent)
Atomics.isLockFree(3); // false
Atomics.isLockFree(4); // true
Atomics.isLockFree(5); // false
Atomics.isLockFree(6); // false
Atomics.isLockFree(7); // false
Atomics.isLockFree(8); // true
Atomics.isLockFree(8); // true (platform-dependent)
```

## Specifications
Expand Down