Commit 54e035a3 authored by Linshizhi's avatar Linshizhi

Test with module worker.

parent 50ffd1cc
import { WW } from './WW.js';
import { assert } from './utils.js';
class CpySchedule {
......@@ -36,7 +35,6 @@ export class Channel {
#size = 0;
#totalSize = 0;
#WW = undefined;
#shMem = undefined;
#view = undefined;
#buffer = undefined;
......@@ -47,28 +45,37 @@ export class Channel {
// size's unit is byte
// bufferType parameter is mainly for testability.
constructor(size, bufferType = SharedArrayBuffer) {
constructor(size, bufferType = SharedArrayBuffer, shMem = null) {
assert(size >= 2, `Channel require its data area has at least 2 Bytes.`)
this.#WW = WW;
this.#size = size;
// Init shared memory
this.#metaSize = this.#rFieldPosLen + this.#wFieldPosLen + this.#priFieldLen;
this.#shMem = new bufferType(size + this.#metaSize);
this.#shMem = shMem == null ? new bufferType(size + this.#metaSize) : shMem;
this.#view = new DataView(this.#shMem);
this.#buffer = new Uint8Array(this.#shMem);
this.#writePointerCache = this.#metaSize;
this.#readPointerCache = this.#metaSize;
if (shMem == null) {
this.#writePointerCache = this.#metaSize;
this.#readPointerCache = this.#metaSize;
// Init readPointer and writePointer to
// the first bytes of data area.
this.#view.setUint32(0, this.#writePointerCache);
this.#view.setUint32(4, this.#readPointerCache);
} else {
this.#writePointerCache = this.#getWritePointer();
this.#readPointerCache = this.#getReadPointer();
}
this.#size = size;
this.#totalSize = this.#metaSize + this.#size;
this.#endPos = this.#metaSize + this.#size;
// Init readPointer and writePointer to
// the first bytes of data area.
this.#view.setUint32(0, this.#writePointerCache);
this.#view.setUint32(4, this.#readPointerCache);
}
#getReadPointer() {
......
......@@ -131,7 +131,7 @@ describe("Channel Spec", () => {
it("Transfer 64 MB to WebWorker", async () => {
let url = new URL('./workers/channelWW.js', import.meta.url),
ret = true;
let channel = new Channel(Math.pow(2,10));
let channel = new Channel(Math.pow(2,20));
let worker = new Worker(url, { type: 'module' });
let sended = 0;
......@@ -139,9 +139,9 @@ describe("Channel Spec", () => {
[...Array(getRandomInt(Math.pow(2,10))).keys()]);
let cur = 0;
let size = Math.pow(2, 15);
let rBuffer = new Uint8Array(Math.pow(2, 16));
let sBuffer = new Uint8Array(Math.pow(2, 16));
let size = Math.pow(2, 26);
let rBuffer = new Uint8Array(Math.pow(2, 27));
let sBuffer = new Uint8Array(Math.pow(2, 27));
worker.postMessage(channel.getShMem());
......@@ -174,17 +174,16 @@ describe("Channel Spec", () => {
// Wait for Web Worker
await new Promise(r => {
setInterval(() => {
console.log(cur, sended);
if (cur == sended) {
r();
}
}, 10);
}, 100);
}, 100000);
worker.terminate();
expect(areEqual(rBuffer, sBuffer)).toBe(true);
}, 100000);
}, 10000);
});
......
class ChannelReader {
#rFieldPosLen = 4;
#wFieldPosLen = 4;
#privFieldLen = 4;
#metaSize = this.#rFieldPosLen +
this.#wFieldPosLen +
this.#privFieldLen;
#readPos = 0;
#buffer = null;
#view = null;
#shMem = null;
/* Buffer should follow the specification
* of Channel in src/encGroup.js */
constructor(shMem) {
this.#shMem = shMem;
this.#buffer = new Uint8Array(this.#shMem);
this.#view = new DataView(this.#shMem);
this.#readPos = this.#view.getUint32(0);
}
readPriv() {
return [
this.#view.getUint8(8),
this.#view.getUint8(9),
this.#view.getUint8(10),
this.#view.getUint8(11),
];
}
writePriv(privData) {
if (!(privData instanceof Array) ||
privData.length > this.#privFieldLen) {
throw new Error("Invalid Private datas");
}
for (let i = 8; i < 12; ++i) {
this.#view.setUint8(i);
}
}
readData(size) {
let writePos = this.#writePos();
let readTo = 0, readBuffer = null;
if (this.#readPos == writePos) {
return new Uint8Array(0);
} else if (this.#readPos < writePos) {
readTo = this.#readPos + Math.min(size, writePos - this.#readPos);
readBuffer = this.#buffer.slice(this.#readPos, readTo);
this.#readPosUpdate(readTo);
} else {
// Read two times
let firstRSize = Math.min(size, this.#buffer.byteLength-this.#readPos);
let secondRSize = firstRSize < size ? size - firstRSize : 0;
secondRSize = Math.min(secondRSize, writePos-this.#metaSize);
readBuffer = new Uint8Array(firstRSize+secondRSize);
// First read
readBuffer.set(this.#buffer.slice(
this.#readPos, this.#readPos+firstRSize), 0);
// Second Read
if (secondRSize > 0) {
readBuffer.set(
this.#buffer.slice(this.#metaSize, this.#metaSize+secondRSize),
firstRSize);
this.#readPosUpdate(this.#metaSize+secondRSize);
} else {
let newPos = this.#readPos+firstRSize;
newPos = newPos == this.#buffer.byteLength ? this.#metaSize : newPos;
this.#readPosUpdate(newPos);
}
}
return readBuffer;
}
#writePos() {
return this.#view.getUint32(4);
}
#readPosUpdate(pos) {
this.#readPos = pos;
this.#view.setUint32(0, pos);
}
};
let chnlReader = null;
let init = false;
import { Channel } from '../src/channel.js';
async function sleep(ms) {
await new Promise(r => setTimeout(() => r(), ms));
}
// Init
onmessage = async e => {
if (!init) {
chnlReader = new ChannelReader(e.data);
}
async function main(mem) {
let chnlReader = new Channel(Math.pow(2, 10), SharedArrayBuffer, mem);
let ret = true;
let rSize = Math.pow(2, 10);
......@@ -125,4 +25,10 @@ onmessage = async e => {
postMessage(data);
}
}
// Init
onmessage = async e => {
await main(e.data);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment