Skip to content

Commit c1fa547

Browse files
committed
Fix Atomics.wait usage, do it in worker thread + use Int32Array + use timeout 10ms
1 parent d62c831 commit c1fa547

File tree

5 files changed

+49
-27
lines changed

5 files changed

+49
-27
lines changed

jsaddleJS/jsaddle.js

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,9 @@ function jsaddleHandlerMsgs (msgs) {
328328
var jsaddleMsgSharedBuf = new SharedArrayBuffer(10*1024*1024);
329329
var jsaddleMsgBufArray = new Uint8Array(jsaddleMsgSharedBuf);
330330
var jsaddleMsgBufArray32 = new Uint32Array(jsaddleMsgSharedBuf);
331+
// Atomics.wait need Int32
332+
var jsaddleMsgBufArrayInt32 = new Int32Array(jsaddleMsgSharedBuf);
333+
var jsaddle_sendMsgWorker = new Worker('jsaddle_sendMsgWorker.js');
331334

332335
function sendAPI (msg) {
333336
var str = JSON.stringify(msg);
@@ -338,32 +341,19 @@ function sendAPI (msg) {
338341
dataview.setUint32(0, size);
339342
const uint8 = new Uint8Array(b);
340343
uint8.set(a, 4);
341-
// non-blocking
342-
appendMsgToSharedBuf(uint8);
343-
}
344-
345-
async function appendMsgToSharedBuf(buf) {
346-
var isAlreadyLocked = Atomics.compareExchange(jsaddleMsgBufArray32, 0, 0, 1);
347-
if (isAlreadyLocked === 1) {
348-
Atomics.wait(jsaddleMsgBufArray32, 0, 0);
349-
appendMsgToSharedBuf(buf);
350-
} else {
351-
var len = buf.byteLength;
352-
var prevLen = jsaddleMsgBufArray32[1];
353-
var totalLen = len + prevLen;
354-
var startOffset = prevLen + 8; // Two 32 bit uint
355-
var i = len;
356-
while (i--) jsaddleMsgBufArray[startOffset + i] = buf[i];
357-
jsaddleMsgBufArray32[1] = totalLen;
358-
// Release the lock
359-
jsaddleMsgBufArray32[0] = 0;
360-
}
344+
jsaddle_sendMsgWorker.postMessage({
345+
buf: b,
346+
jsaddleMsgBufArrayInt32: jsaddleMsgBufArrayInt32,
347+
jsaddleMsgBufArray32: jsaddleMsgBufArray32,
348+
jsaddleMsgBufArray: jsaddleMsgBufArray
349+
}, [b]);
361350
}
362351

363352
function jsaddleJsInit() {
364353
return {
365354
jsaddleListener: channel.port2,
366355
jsaddleMsgBufArray: jsaddleMsgBufArray,
367-
jsaddleMsgBufArray32: jsaddleMsgBufArray32
356+
jsaddleMsgBufArray32: jsaddleMsgBufArray32,
357+
jsaddleMsgBufArrayInt32: jsaddleMsgBufArrayInt32
368358
};
369359
}

jsaddleJS/jsaddle_sendMsgWorker.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Atomics.wait is not possible on main thread
2+
// so this worker takes the messages from jsaddle.js and appends to the SharedArrayBuffer
3+
4+
onmessage = function (msg) {
5+
var jsaddleMsgBufArrayInt32 = msg.data.jsaddleMsgBufArrayInt32;
6+
var jsaddleMsgBufArray32 = msg.data.jsaddleMsgBufArray32;
7+
var jsaddleMsgBufArray = msg.data.jsaddleMsgBufArray;
8+
const uint8 = new Uint8Array(msg.data.buf);
9+
var appendMsgToSharedBuf = function () {
10+
var isAlreadyLocked = Atomics.compareExchange(jsaddleMsgBufArrayInt32, 0, 0, 10);
11+
if (isAlreadyLocked === 1) {
12+
Atomics.wait(jsaddleMsgBufArrayInt32, 0, 0, 10);
13+
appendMsgToSharedBuf();
14+
} else {
15+
var len = uint8.length;
16+
var prevLen = jsaddleMsgBufArray32[1];
17+
var totalLen = len + prevLen;
18+
var startOffset = prevLen + 8; // Two 32 bit uint
19+
var i = len;
20+
while (i--) jsaddleMsgBufArray[startOffset + i] = uint8[i];
21+
jsaddleMsgBufArray32[1] = totalLen;
22+
// Release the lock
23+
jsaddleMsgBufArrayInt32[0] = 0;
24+
}
25+
};
26+
appendMsgToSharedBuf();
27+
}

src/JSaddleDevice.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ export class JSaddleDevice implements Device {
1111
constructor(
1212
jsaddleListener: MessagePort,
1313
jsaddleMsgBufArray: Uint8Array,
14-
jsaddleMsgBufArray32: Uint32Array) {
14+
jsaddleMsgBufArray32: Uint32Array,
15+
jsaddleMsgBufArrayInt32: Int32Array
16+
) {
1517
this._file = new JSaddleDeviceFile(this, jsaddleListener
16-
, jsaddleMsgBufArray, jsaddleMsgBufArray32);
18+
, jsaddleMsgBufArray, jsaddleMsgBufArray32, jsaddleMsgBufArrayInt32);
1719
}
1820

1921
public open(flag: FileFlag): File {
@@ -31,7 +33,8 @@ export class JSaddleDeviceFile extends BaseFile implements File {
3133
private _Device: JSaddleDevice,
3234
private _jsaddleListener: MessagePort,
3335
private _jsaddleMsgBufArray: Uint8Array,
34-
private _jsaddleMsgBufArray32: Uint32Array) {
36+
private _jsaddleMsgBufArray32: Uint32Array,
37+
private _jsaddleMsgBufArrayInt32: Int32Array) {
3538
super();
3639
}
3740
public getPos(): number | undefined {
@@ -94,7 +97,7 @@ export class JSaddleDeviceFile extends BaseFile implements File {
9497
}
9598
public readSync(buffer: Buffer, offset: number, length: number, position: number | null): number {
9699
var bytes_read = 0;
97-
var isAlreadyLocked = Atomics.compareExchange(this._jsaddleMsgBufArray32, 0, 0, 1);
100+
var isAlreadyLocked = Atomics.compareExchange(this._jsaddleMsgBufArrayInt32, 0, 0, 1);
98101
if (isAlreadyLocked === 0) {
99102
var bytes_available = this._jsaddleMsgBufArray32[1];
100103
if (bytes_available > 0) {
@@ -118,7 +121,7 @@ export class JSaddleDeviceFile extends BaseFile implements File {
118121
}
119122
}
120123
// Release the lock
121-
this._jsaddleMsgBufArray32[0] = 0;
124+
this._jsaddleMsgBufArrayInt32[0] = 0;
122125
}
123126
return bytes_read;
124127
}

src/worker_runner.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ connectParent({ onMessage: async msg1 => {
99
const jsaddleDevice = new JSaddleDevice(
1010
msg.jsaddleVals.jsaddleListener,
1111
msg.jsaddleVals.jsaddleMsgBufArray,
12-
msg.jsaddleVals.jsaddleMsgBufArray32);
12+
msg.jsaddleVals.jsaddleMsgBufArray32,
13+
msg.jsaddleVals.jsaddleMsgBufArrayInt32);
1314
const fs = await configureFileSystem({ devices: { ["/jsaddle_inout"]: jsaddleDevice } });
1415
(await Process.instantiateProcess(fs, msg.url)).start([],[]);
1516
}});

www/jsaddle_sendMsgWorker.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../jsaddleJS/jsaddle_sendMsgWorker.js

0 commit comments

Comments
 (0)