type IntArray = Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array;
class SharedQueue {
_data: A;
_wait: Int32Array;
constructor(props: SharedQueueProps) {
this._data = props.data;
this._wait = props.wait || new Int32Array(new MaybeSharedArrayBuffer(4 * 2));
}
static from(props: SharedQueueProps) {
return new SharedQueue(props);
}
to(): SharedQueueProps {
return {data: this._data, wait: this._wait};
}
enqueue(v: number) {
let head = Atomics.load(this._wait, 0), tail = Atomics.load(this._wait, 1);
head ? head-- : (head = this._data.length);
if (head != tail) {
Atomics.store(this._data, tail++, v);
Atomics.store(this._wait, 1, tail);
Atomics.notify(this._wait, 1, 1);
return 1;
}
else return 0;
}
enqueueAll(vs: IntArray) {
let head = Atomics.load(this._wait, 0), tail = Atomics.load(this._wait, 1);
head ? head-- : (head = this._data.length);
var i: number;
for (i = 0; head != tail && i < vs.length; i++) {
Atomics.store(this._data, tail++, vs[i]);
}
if (i > 0) {
Atomics.store(this._wait, 1, tail);
Atomics.notify(this._wait, 1, 1);
}
return i;
}
wait() {
let head = Atomics.load(this._wait, 0), tail = Atomics.load(this._wait, 1);
while (head == tail) {
Atomics.wait(this._wait, 1, tail);
tail = Atomics.load(this._wait, 1);
}
}
dequeue() {
this.wait();
let head = Atomics.load(this._wait, 0),
top = Atomics.load(this._data, head++)
Atomics.store(this._wait, 0, head);
Atomics.notify(this._wait, 0, 1);
return top;
}
dequeueSome(count: number, out: A, offset: number): number {
if (count == 0) return 0;
this.wait();
let head = Atomics.load(this._wait, 0), tail = Atomics.load(this._wait, 1);
var i: number;
for (i = 0; head != tail && offset < count; i++) {
out[offset++] = Atomics.load(this._data, head++);
if (tail >= this._data.length) tail = 0;
}
Atomics.store(this._wait, 0, head);
Atomics.notify(this._wait, 0, 1);
return i;
}
isEmpty() {
let head = Atomics.load(this._wait, 0), tail = Atomics.load(this._wait, 1);
return head == tail;
}
}
type SharedQueueProps = { data: A, wait?: Int32Array };
const MaybeSharedArrayBuffer = typeof SharedArrayBuffer != 'undefined'
? SharedArrayBuffer : ArrayBuffer;
export { SharedQueue, SharedQueueProps }