atomics-sync
Version:
JavaScript multithreading synchronization library
3 lines (2 loc) • 6.29 kB
JavaScript
!function(r,E){"object"==typeof exports&&"undefined"!=typeof module?E(exports):"function"==typeof define&&define.amd?define(["exports"],E):E((r="undefined"!=typeof globalThis?globalThis:r||self)["atomics-sync"]={})}(this,function(r){"use strict";class E extends Error{constructor(r){super(r),this.name="DeadlockError"}}class t extends Error{constructor(r){super(r),this.name="PermissionError"}}class e extends Error{constructor(r){super(r),this.name="InvalidError"}}const o=2147483647,n=-2147483648,{compareExchange:i,wait:a,notify:c,store:s,load:T}=Atomics;class N{static init(){const r=new Int32Array(new SharedArrayBuffer(2*Int32Array.BYTES_PER_ELEMENT));return s(r,N.INDEX_STATE,N.STATE_UNLOCKED),s(r,N.INDEX_OWNER,N.OWNER_EMPTY),r}static lock(r,E){for(N.checkThreadIdBeforeLock(r,E);;){if(i(r,N.INDEX_STATE,N.STATE_UNLOCKED,N.STATE_LOCKED)===N.STATE_UNLOCKED)return void s(r,N.INDEX_OWNER,E);a(r,N.INDEX_STATE,N.STATE_LOCKED)}}static timedLock(r,E,t){for(N.checkThreadIdBeforeLock(r,E);;){if(i(r,N.INDEX_STATE,N.STATE_UNLOCKED,N.STATE_LOCKED)===N.STATE_UNLOCKED)return s(r,N.INDEX_OWNER,E),!0;const e=t-Date.now();if("timed-out"===a(r,N.INDEX_STATE,N.STATE_LOCKED,e))return!1}}static tryLock(r,E){return N.checkThreadIdBeforeLock(r,E),i(r,N.INDEX_STATE,N.STATE_UNLOCKED,N.STATE_LOCKED)===N.STATE_UNLOCKED&&(s(r,N.INDEX_OWNER,E),!0)}static unlock(r,E){if(N.checkThreadIdIsValid(E),T(r,N.INDEX_OWNER)!==E)throw new t("current thread is not owner of mutex");if(s(r,N.INDEX_OWNER,N.OWNER_EMPTY),i(r,N.INDEX_STATE,N.STATE_LOCKED,N.STATE_UNLOCKED)===N.STATE_UNLOCKED)throw new t("mutex was not locked");c(r,N.INDEX_STATE,1)}static checkThreadIdBeforeLock(r,t){if(N.checkThreadIdIsValid(t),T(r,N.INDEX_OWNER)===t)throw new E("thread already owns this mutex")}static checkThreadIdIsValid(r){if(!Number.isInteger(r))throw new e("threadId should be int32");if(r<n||r>o)throw new RangeError("threadId is out of int32 range");if(r===N.OWNER_EMPTY)throw new e("threadId is empty owner")}}N.OWNER_EMPTY=0,N.STATE_UNLOCKED=0,N.STATE_LOCKED=1,N.INDEX_STATE=0,N.INDEX_OWNER=1;const{compareExchange:_,wait:I,notify:d,store:D,load:A}=Atomics;class u{static init(r){if(!Number.isInteger(r))throw new e("initial value should be int32");if(r<0||r>o)throw new RangeError("initial value should be greater or equal zero and less or equal maximum int32 value");const E=new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));return D(E,u.INDEX_VALUE,r),E}static wait(r){for(;;){const E=A(r,u.INDEX_VALUE);if(E>0){if(_(r,u.INDEX_VALUE,E,E-1)===E)return}else I(r,u.INDEX_VALUE,E)}}static timedWait(r,E){for(;;){const t=A(r,u.INDEX_VALUE);if(t>0){if(_(r,u.INDEX_VALUE,t,t-1)===t)return!0}else{const e=E-Date.now();if("timed-out"===I(r,u.INDEX_VALUE,t,e))return!1}}}static tryWait(r){for(;;){const E=A(r,u.INDEX_VALUE);if(0===E)return!1;if(_(r,u.INDEX_VALUE,E,E-1)===E)return!0}}static post(r){for(;;){const E=A(r,u.INDEX_VALUE);if(E===o)throw new RangeError("maximum limit reached for semaphore value");if(_(r,u.INDEX_VALUE,E,E+1)===E)return void(0===E&&d(r,u.INDEX_VALUE,1))}}static getValue(r){return A(r,u.INDEX_VALUE)}}u.INDEX_VALUE=0;const{wait:f,notify:h}=Atomics;class l{static init(){return new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT))}static signal(r){h(r,0,1)}static broadcast(r){h(r,0)}static wait(r,E,t){N.unlock(E,t),f(r,0,0),N.lock(E,t)}static timedWait(r,E,t,e){try{return N.unlock(E,t),"timed-out"!==f(r,0,0,e-Date.now())}finally{N.lock(E,t)}}}const{store:X,load:O,add:w}=Atomics;class L{static init(r){L.validateCount(r);const E=new BigInt64Array(new SharedArrayBuffer(3*BigInt64Array.BYTES_PER_ELEMENT));X(E,L.INDEX_COUNT,BigInt(r)),X(E,L.INDEX_WAITED,0n),X(E,L.INDEX_GENERATION,0n);return{barrier:E,mutex:N.init(),cond:l.init()}}static wait(r,E){N.lock(r.mutex,E);const t=O(r.barrier,L.INDEX_GENERATION),e=O(r.barrier,L.INDEX_COUNT),o=w(r.barrier,L.INDEX_WAITED,1n)+1n;try{if(o>=e)return X(r.barrier,L.INDEX_WAITED,0n),w(r.barrier,L.INDEX_GENERATION,1n),l.broadcast(r.cond),!0;for(;O(r.barrier,L.INDEX_GENERATION)===t;)l.wait(r.cond,r.mutex,E);return!1}finally{N.unlock(r.mutex,E)}}static validateCount(r){if(!Number.isInteger(r))throw new e("count should be integer");if(r<=0)throw new RangeError("count should be greater zero")}}L.INDEX_COUNT=0,L.INDEX_WAITED=1,L.INDEX_GENERATION=2;const{compareExchange:S,store:m,load:U}=Atomics;class C{static init(){const r=new Int32Array(new SharedArrayBuffer(2*Int32Array.BYTES_PER_ELEMENT));return m(r,C.INDEX_STATE,C.STATE_UNLOCKED),m(r,C.INDEX_OWNER,C.OWNER_EMPTY),r}static lock(r,E){for(C.checkThreadIdBeforeLock(r,E);;){if(S(r,C.INDEX_STATE,C.STATE_UNLOCKED,C.STATE_LOCKED)===C.STATE_UNLOCKED)return void m(r,C.INDEX_OWNER,E);"function"==typeof Atomics.pause&&Atomics.pause()}}static tryLock(r,E){return C.checkThreadIdBeforeLock(r,E),S(r,C.INDEX_STATE,C.STATE_UNLOCKED,C.STATE_LOCKED)===C.STATE_UNLOCKED&&(m(r,C.INDEX_OWNER,E),!0)}static unlock(r,E){if(C.checkThreadIdIsValid(E),U(r,C.INDEX_OWNER)!==E)throw new t("current thread is not owner of lock");if(m(r,C.INDEX_OWNER,C.OWNER_EMPTY),S(r,C.INDEX_STATE,C.STATE_LOCKED,C.STATE_UNLOCKED)===C.STATE_UNLOCKED)throw new t("lock was not locked")}static checkThreadIdBeforeLock(r,t){if(C.checkThreadIdIsValid(t),U(r,C.INDEX_OWNER)===t)throw new E("thread already owns this lock")}static checkThreadIdIsValid(r){if(!Number.isInteger(r))throw new e("threadId should be int32");if(r<n||r>o)throw new RangeError("threadId is out of int32 range");if(r===C.OWNER_EMPTY)throw new e("threadId is empty owner")}}C.OWNER_EMPTY=0,C.STATE_UNLOCKED=0,C.STATE_LOCKED=1,C.INDEX_STATE=0,C.INDEX_OWNER=1;const{compareExchange:k,store:y}=Atomics;class R{static init(){const r=new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));return y(r,R.INDEX_EXECUTED,R.EXECUTED_NO),r}static execute(r,E){k(r,R.INDEX_EXECUTED,R.EXECUTED_NO,R.EXECUTED_YES)===R.EXECUTED_NO&&E()}static isExecuted(r){return Atomics.load(r,R.INDEX_EXECUTED)===R.EXECUTED_YES}}R.INDEX_EXECUTED=0,R.EXECUTED_NO=0,R.EXECUTED_YES=1,r.Barrier=L,r.Condition=l,r.DeadlockError=E,r.INT32_MAX_VALUE=o,r.INT32_MIN_VALUE=n,r.InvalidError=e,r.Mutex=N,r.Once=R,r.PermissionError=t,r.Semaphore=u,r.SpinLock=C,Object.defineProperty(r,"__esModule",{value:!0})});
//# sourceMappingURL=atomics-sync.umd.min.js.map