MENU
Atomics
'Atomic operations make sure that predictable values are written and read, that operations are finished before the next operation starts and that operations are not interrupted.' – MDN
The following methods are provided by Atomics:Get and SetGet and Set Get and Set Operations Operations Operations :: :
.load()
Returns the value at the given position in the array.
.store()
Stores a given value at the given position in the array. Returns the value.
.exchange()
Stores a given value at a given position in the array. Returns the old value.
. compareExchange(typedArray, index, expectedValue, replacementValue)
Stores a given value at a given position in the array, if it equals a given value. Returns the old value.
Binary Ope Binary Ope Binary Ope rations: rations: rations:
Returns the old value.
Atomics.add() Atomics.sub() Atomics.and() A tomics.or() Atomics.xor()
RESETRUNFULL
<!DOCTYPE html><html><body><script>
var sab = new SharedArrayBuffer(1024);var ta = new Uint8Array(sab);// Operations at location 0Atomics.store(ta, 0, 12);Atomics.load(ta, 0);Atomics.compareExchange(ta, 0, 12, 15);Atomics.add(ta, 0, 20);
</script></body><html>
RESETRUNFULL
<!DOCTYPE html><html><body><script>
<!DOCTYPE html><html><head></head><body><script>
var arr = new SharedArrayBuffer(256);
new Int16Array(arr)[0]=0;
var workers=[];
for (let i=0; i<1000; i++)
workers.push(new Worker('worker.js'));
workers.forEach(
w => w.postMessage(new Int16Array(arr)));</script></body></html>
</script></body><html>
<!DOCTYPE html><html><body><script>
// worker.jsonmessage = function(e) {
e.data[0]++; // last line is 981 only? wth?!//Atomics.add(e.data,0,1); // last line is exactly 1000. right...
console.log(e.data[0]);}
</script></body><html>
Wait and Wake Operations: Wait and Wake Operations: Wait and Wake Operations:
Atomics.wait( Int32Array, index, value,
timeout )
Verifies that a given position in the array still contains a given value and sleeps awaiting or times out. Returns either "ok", "not-equal", or "timed-out". If waiting is not allowed in the calling agent then it throws an Error exception (most browsers will not allow wait() on the browser's main thread).This operation only works with a shared Int32Array and is not allowed on the main thread.
Atomics.wake( Int32Array, index, count )
Wakes up some(count) agents that are sleeping in the wait queue on the given array position. Returns the number of agents that were woken up.This operation works with a shared Int32Array only.
Atomics.isLockFree(size)
An optimization primitive that can be used to determine whether to use locks or atomic operations. Returns true, if an atomic operation on arrays of the given element size will be implemented using a hardware atomic operation (as opposed to a lock). Experts only.It returns true, if the given size is one of the BYTES_PER_ELEMENT property of integer TypedArray types.
A reading thread is sleeping and waiting on location 0 which is expected to be 0. As long as that is true, it will not go on. However, once the writing thread has stored a new value, it will be woken up by the writing thread and return the new value (123).
RESETRUNFULL
<!DOCTYPE html><html><body><script>
var sab = new SharedArrayBuffer(1024);var int32 = new Int32Array(sab);
</script></body><html>
<!DOCTYPE html><html><body><script>
Atomics.wait(int32, 0, 0);console.log(int32[0]); // 123
</script></body><html>
<!DOCTYPE html><html><body><script>
console.log(int32[0]); // 0;Atomics.store(int32, 0, 123); Atomics.wake(int32, 0, 1);
</script></body><html>
RESETRUNFULL
<!DOCTYPE html><html><body><script>
Atomics.isLockFree(1); // trueAtomics.isLockFree(2); // trueAtomics.isLockFree(3); // falseAtomics.isLockFree(4); // trueAtomics.isLockFree(5); // falseAtomics.isLockFree(6); // falseAtomics.isLockFree(7); // falseAtomics.isLockFree(8); // false
</script></body><html>
As of July 2017, SharedArrayBuffer and Atomics have not been implemented for NodeJS. In browsers, parallelism can be achieved with Web Workers. (Note that some browsers don't support Web Workers on local computers, ie. a server is needed.) If you need shared memory in NodeJS, consider using the package 'ems'.
RESETRUNFULL
<!DOCTYPE html><html><body><script>
<!DOCTYPE html><html><body><script>const worker = new Worker('worker.js');const SBUF = new SharedArrayBuffer(
10 * Int32Array.BYTES_PER_ELEMENT); // 10 elementsworker.postMessage({SBUF}); // cloneconst sa = new Int32Array(SBUF);console.log('notifying...');Atomics.store(sa, 0, 123);Atomics.wake(sa, 0, 1);</script></body></html>
</script></body><html>
<!DOCTYPE html><html><body><script>
// worker.jsself.addEventListener('message', function (event) {
const {SBUF} = event.data;
const sa = new Int32Array(SBUF); // (A)
Atomics.wait(sa,0,0);
console.log('notified');});
</script></body><html>