Skip to content

Instantly share code, notes, and snippets.

@empijei
Created March 22, 2019 18:41
Show Gist options
  • Save empijei/cbc3e34c918ec1f1a3c189f313aa7070 to your computer and use it in GitHub Desktop.
Save empijei/cbc3e34c918ec1f1a3c189f313aa7070 to your computer and use it in GitHub Desktop.
semaphore.js
class Semaphore {
constructor(size, opt_sab) {
this._sab = opt_sab || new SharedArrayBuffer(4);
this._sema = new Int32Array(this._sab);
this._size = size;
}
static connect(sema) {
return new Semaphore(sema._size, sema._sab);
}
// acquire does not check for overflow.
acquire() {
let count = Atomics.load(this._sema,0);
for(;;) {
if (count + 1 > this._size) {
Atomics.wait(this._sema, 0, count);
count = Atomics.load(this._sema,0);
continue;
}
let old = Atomics.compareExchange(this._sema, 0, count, count+1)
if (old == count){
return;
}
count = old;
}
}
release() {
if (Atomics.sub(this._sema, 0, 1) < 0){
throw new Error('Semaphore is in inconsistent state: negative count.');
}
Atomics.notify(this._sema, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment