Commit 54e035a3 authored by Linshizhi's avatar Linshizhi

Test with module worker.

parent 50ffd1cc
import { WW } from './WW.js';
import { assert } from './utils.js'; import { assert } from './utils.js';
class CpySchedule { class CpySchedule {
...@@ -36,7 +35,6 @@ export class Channel { ...@@ -36,7 +35,6 @@ export class Channel {
#size = 0; #size = 0;
#totalSize = 0; #totalSize = 0;
#WW = undefined;
#shMem = undefined; #shMem = undefined;
#view = undefined; #view = undefined;
#buffer = undefined; #buffer = undefined;
...@@ -47,28 +45,37 @@ export class Channel { ...@@ -47,28 +45,37 @@ export class Channel {
// size's unit is byte // size's unit is byte
// bufferType parameter is mainly for testability. // 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.`) assert(size >= 2, `Channel require its data area has at least 2 Bytes.`)
this.#WW = WW;
this.#size = size; this.#size = size;
// Init shared memory // Init shared memory
this.#metaSize = this.#rFieldPosLen + this.#wFieldPosLen + this.#priFieldLen; 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.#view = new DataView(this.#shMem);
this.#buffer = new Uint8Array(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.#size = size;
this.#totalSize = this.#metaSize + this.#size; this.#totalSize = this.#metaSize + this.#size;
this.#endPos = 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() { #getReadPointer() {
......
...@@ -131,7 +131,7 @@ describe("Channel Spec", () => { ...@@ -131,7 +131,7 @@ describe("Channel Spec", () => {
it("Transfer 64 MB to WebWorker", async () => { it("Transfer 64 MB to WebWorker", async () => {
let url = new URL('./workers/channelWW.js', import.meta.url), let url = new URL('./workers/channelWW.js', import.meta.url),
ret = true; 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 worker = new Worker(url, { type: 'module' });
let sended = 0; let sended = 0;
...@@ -139,9 +139,9 @@ describe("Channel Spec", () => { ...@@ -139,9 +139,9 @@ describe("Channel Spec", () => {
[...Array(getRandomInt(Math.pow(2,10))).keys()]); [...Array(getRandomInt(Math.pow(2,10))).keys()]);
let cur = 0; let cur = 0;
let size = Math.pow(2, 15); let size = Math.pow(2, 26);
let rBuffer = new Uint8Array(Math.pow(2, 16)); let rBuffer = new Uint8Array(Math.pow(2, 27));
let sBuffer = new Uint8Array(Math.pow(2, 16)); let sBuffer = new Uint8Array(Math.pow(2, 27));
worker.postMessage(channel.getShMem()); worker.postMessage(channel.getShMem());
...@@ -174,17 +174,16 @@ describe("Channel Spec", () => { ...@@ -174,17 +174,16 @@ describe("Channel Spec", () => {
// Wait for Web Worker // Wait for Web Worker
await new Promise(r => { await new Promise(r => {
setInterval(() => { setInterval(() => {
console.log(cur, sended);
if (cur == sended) { if (cur == sended) {
r(); r();
} }
}, 10); }, 100);
}, 100000); }, 100000);
worker.terminate(); worker.terminate();
expect(areEqual(rBuffer, sBuffer)).toBe(true); expect(areEqual(rBuffer, sBuffer)).toBe(true);
}, 100000); }, 10000);
}); });
......
import { Channel } from '../src/channel.js';
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;
async function sleep(ms) { async function sleep(ms) {
await new Promise(r => setTimeout(() => r(), ms)); await new Promise(r => setTimeout(() => r(), ms));
} }
// Init async function main(mem) {
onmessage = async e => { let chnlReader = new Channel(Math.pow(2, 10), SharedArrayBuffer, mem);
if (!init) {
chnlReader = new ChannelReader(e.data);
}
let ret = true; let ret = true;
let rSize = Math.pow(2, 10); let rSize = Math.pow(2, 10);
...@@ -125,4 +25,10 @@ onmessage = async e => { ...@@ -125,4 +25,10 @@ onmessage = async e => {
postMessage(data); 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