UNPKG

multithreading

Version:

The missing standard library for multithreading in JavaScript (Works in the browser, Node.js, Deno, Bun).

124 lines (123 loc) 6.78 kB
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _SemaphoreGuard_amount, _SemaphoreGuard_controller, _SemaphoreGuard_released, _Semaphore_instances, _a, _Semaphore_state, _Semaphore_controller, _Semaphore_release; import { register, Serializable, toDeserialized, toSerialized, } from "../shared.js"; export const INTERNAL_SEMAPHORE_CONTROLLER = Symbol("Thread.InternalSemaphoreController"); const IDX_PERMITS = 0; const IDX_WAITERS = 1; const META_SIZE = 2; export class SemaphoreGuard { constructor(amount, controller) { _SemaphoreGuard_amount.set(this, void 0); _SemaphoreGuard_controller.set(this, void 0); _SemaphoreGuard_released.set(this, false); __classPrivateFieldSet(this, _SemaphoreGuard_amount, amount, "f"); __classPrivateFieldSet(this, _SemaphoreGuard_controller, controller, "f"); } get [(_SemaphoreGuard_amount = new WeakMap(), _SemaphoreGuard_controller = new WeakMap(), _SemaphoreGuard_released = new WeakMap(), INTERNAL_SEMAPHORE_CONTROLLER)]() { return __classPrivateFieldGet(this, _SemaphoreGuard_controller, "f"); } get amount() { return __classPrivateFieldGet(this, _SemaphoreGuard_amount, "f"); } [Symbol.dispose]() { if (!__classPrivateFieldGet(this, _SemaphoreGuard_released, "f")) { __classPrivateFieldSet(this, _SemaphoreGuard_released, true, "f"); __classPrivateFieldGet(this, _SemaphoreGuard_controller, "f").release(__classPrivateFieldGet(this, _SemaphoreGuard_amount, "f")); } } dispose() { this[Symbol.dispose](); } } export class Semaphore extends Serializable { constructor(initialCount, _buffer) { super(); _Semaphore_instances.add(this); _Semaphore_state.set(this, void 0); _Semaphore_controller.set(this, void 0); if (_buffer) { __classPrivateFieldSet(this, _Semaphore_state, new Int32Array(_buffer), "f"); } else { __classPrivateFieldSet(this, _Semaphore_state, new Int32Array(new SharedArrayBuffer(META_SIZE * Int32Array.BYTES_PER_ELEMENT)), "f"); __classPrivateFieldGet(this, _Semaphore_state, "f")[IDX_PERMITS] = initialCount; __classPrivateFieldGet(this, _Semaphore_state, "f")[IDX_WAITERS] = 0; } __classPrivateFieldSet(this, _Semaphore_controller, { release: (amount) => __classPrivateFieldGet(this, _Semaphore_instances, "m", _Semaphore_release).call(this, amount), }, "f"); } get [(_Semaphore_state = new WeakMap(), _Semaphore_controller = new WeakMap(), _Semaphore_instances = new WeakSet(), INTERNAL_SEMAPHORE_CONTROLLER)]() { return __classPrivateFieldGet(this, _Semaphore_controller, "f"); } tryAcquire(amount = 1) { const current = Atomics.load(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_PERMITS); if (current >= amount) { const result = Atomics.compareExchange(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_PERMITS, current, current - amount); if (result === current) { return new SemaphoreGuard(amount, __classPrivateFieldGet(this, _Semaphore_controller, "f")); } } return null; } blockingAcquire(amount = 1) { while (true) { const current = Atomics.load(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_PERMITS); if (current >= amount) { const result = Atomics.compareExchange(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_PERMITS, current, current - amount); if (result === current) { return new SemaphoreGuard(amount, __classPrivateFieldGet(this, _Semaphore_controller, "f")); } } else { Atomics.add(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_WAITERS, 1); Atomics.wait(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_PERMITS, current); Atomics.sub(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_WAITERS, 1); } } } async acquire(amount = 1) { while (true) { const current = Atomics.load(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_PERMITS); if (current >= amount) { const result = Atomics.compareExchange(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_PERMITS, current, current - amount); if (result === current) { return new SemaphoreGuard(amount, __classPrivateFieldGet(this, _Semaphore_controller, "f")); } } else { Atomics.add(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_WAITERS, 1); const res = Atomics.waitAsync(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_PERMITS, current); if (res.async) { await res.value; } Atomics.sub(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_WAITERS, 1); } } } [(_Semaphore_release = function _Semaphore_release(amount) { Atomics.add(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_PERMITS, amount); if (Atomics.load(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_WAITERS) > 0) { Atomics.notify(__classPrivateFieldGet(this, _Semaphore_state, "f"), IDX_PERMITS, amount); } }, toSerialized)]() { return [__classPrivateFieldGet(this, _Semaphore_state, "f").buffer]; } static [toDeserialized](buffer) { return new _a(0, buffer); } } _a = Semaphore; (() => { register(3, _a); })();