UNPKG

atomics-sync

Version:

JavaScript multithreading synchronization library

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