Skip to content
Permalink
Browse files

core: Behavior shouldn't be generic

We always pass around Box<[u8]>, and adding this generic is an
unnecessary complication.

Add deno_core_http_bench_test to test.py

sharedQueue works on deno_core_http_bench
  • Loading branch information...
ry committed Mar 14, 2019
1 parent 630ead1 commit c0549879aa63f36df21c8a878cc565a270e89b8e
Showing with 774 additions and 344 deletions.
  1. +1 −2 BUILD.gn
  2. +27 −8 core/BUILD.gn
  3. +65 −71 core/http_bench.js
  4. +67 −66 core/http_bench.rs
  5. +138 −148 core/isolate.rs
  6. +3 −0 core/lib.rs
  7. +0 −49 core/shared.rs
  8. +127 −0 core/shared_queue.js
  9. +225 −0 core/shared_queue.rs
  10. +65 −0 core/shared_queue_test.js
  11. +51 −0 core/test_util.rs
  12. +5 −0 tools/test.py
@@ -13,8 +13,7 @@ group("default") {
":deno",
":hyper_hello",
":test_rs",
"core:deno_core_http_bench",
"core:deno_core_test",
"core:default",
"libdeno:test_cc",
]
}
@@ -1,5 +1,14 @@
import("//build_extra/rust/rust.gni")

group("default") {
testonly = true
deps = [
":deno_core_http_bench",
":deno_core_http_bench_test",
":deno_core_test",
]
}

# deno_core does not depend on flatbuffers nor tokio.
main_extern = [
"$rust_build:futures",
@@ -24,14 +33,24 @@ rust_test("deno_core_test") {
]
}

http_bench_extern = [
"$rust_build:futures",
"$rust_build:lazy_static",
"$rust_build:libc",
"$rust_build:log",
"$rust_build:tokio",
":deno_core"
]
if (is_win) {
http_bench_extern += [ "$rust_build:winapi" ]
}

rust_executable("deno_core_http_bench") {
source_root = "http_bench.rs"
extern = [
"$rust_build:futures",
"$rust_build:lazy_static",
"$rust_build:libc",
"$rust_build:log",
"$rust_build:tokio",
":deno_core"
]
extern = http_bench_extern
}

rust_test("deno_core_http_bench_test") {
source_root = "http_bench.rs"
extern = http_bench_extern
}
@@ -6,64 +6,21 @@ const OP_ACCEPT = 2;
const OP_READ = 3;
const OP_WRITE = 4;
const OP_CLOSE = 5;
const INDEX_START = 0;
const INDEX_END = 1;
const NUM_RECORDS = 128;
const RECORD_SIZE = 4;

const shared32 = new Int32Array(libdeno.shared);

function idx(i, off) {
return 2 + i * RECORD_SIZE + off;
}

function recordsPush(promiseId, opId, arg, result) {
let i = shared32[INDEX_END];
if (i >= NUM_RECORDS) {
return false;
}
shared32[idx(i, 0)] = promiseId;
shared32[idx(i, 1)] = opId;
shared32[idx(i, 2)] = arg;
shared32[idx(i, 3)] = result;
shared32[INDEX_END]++;
return true;
}

function recordsShift() {
if (shared32[INDEX_START] == shared32[INDEX_END]) {
return null;
}
const i = shared32[INDEX_START];
const record = {
promiseId: shared32[idx(i, 0)],
opId: shared32[idx(i, 1)],
arg: shared32[idx(i, 2)],
result: shared32[idx(i, 3)]
};
shared32[INDEX_START]++;
return record;
}

function recordsReset() {
shared32[INDEX_START] = 0;
shared32[INDEX_END] = 0;
}

function recordsSize() {
return shared32[INDEX_END] - shared32[INDEX_START];
}

const requestBuf = new Uint8Array(64 * 1024);
const responseBuf = new Uint8Array(
"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World\n"
.split("")
.map(c => c.charCodeAt(0))
);

const promiseMap = new Map();
let nextPromiseId = 1;

function assert(cond) {
if (!cond) {
throw Error("assert");
}
}

function createResolvable() {
let methods;
const promise = new Promise((resolve, reject) => {
@@ -72,36 +29,73 @@ function createResolvable() {
return Object.assign(promise, methods);
}

const scratch32 = new Int32Array(4);
const scratchBytes = new Uint8Array(
scratch32.buffer,
scratch32.byteOffset,
scratch32.byteLength
);
assert(scratchBytes.byteLength === 4 * 4);

// Toggle what method we send with. false = legacy.
// AFAICT This has no effect on performance.
const sendWithShared = true;

function send(promiseId, opId, arg, zeroCopy = null) {
scratch32[0] = promiseId;
scratch32[1] = opId;
scratch32[2] = arg;
scratch32[3] = -1;
if (sendWithShared) {
Deno._sharedQueue.push(scratchBytes);
libdeno.send(null, zeroCopy);
} else {
libdeno.send(scratchBytes, zeroCopy);
}
}

/** Returns Promise<number> */
function sendAsync(opId, arg, zeroCopyData) {
function sendAsync(opId, arg, zeroCopy = null) {
const promiseId = nextPromiseId++;
const p = createResolvable();
recordsReset();
recordsPush(promiseId, opId, arg, -1);
promiseMap.set(promiseId, p);
libdeno.send(null, zeroCopyData);
send(promiseId, opId, arg, zeroCopy);
return p;
}

/** Returns u32 number */
function sendSync(opId, arg) {
recordsReset();
recordsPush(0, opId, arg, -1);
libdeno.send();
if (recordsSize() != 1) {
throw Error("Expected sharedSimple to have size 1");
}
let { result } = recordsShift();
return result;
function recordFromBuf(buf) {
assert(buf.byteLength === 16);
const buf32 = new Int32Array(buf.buffer, buf.byteOffset, buf.byteLength / 4);
return {
promiseId: buf32[0],
opId: buf32[1],
arg: buf32[2],
result: buf32[3]
};
}

function handleAsyncMsgFromRust() {
while (recordsSize() > 0) {
const { promiseId, result } = recordsShift();
const p = promiseMap.get(promiseId);
promiseMap.delete(promiseId);
p.resolve(result);
function recv() {
const buf = Deno._sharedQueue.shift();
if (!buf) {
return null;
}
return recordFromBuf(buf);
}

/** Returns i32 number */
function sendSync(opId, arg) {
send(0, opId, arg);
const record = recv();
assert(recv() == null);
return record.result;
}

function handleAsyncMsgFromRust(buf) {
const record = recordFromBuf(buf);
const { promiseId, result } = record;
const p = promiseMap.get(promiseId);
promiseMap.delete(promiseId);
p.resolve(result);
}

/** Listens on 0.0.0.0:4500, returns rid. */
@@ -147,12 +141,12 @@ async function serve(rid) {
}

async function main() {
libdeno.recv(handleAsyncMsgFromRust);
Deno._setAsyncHandler(handleAsyncMsgFromRust);

libdeno.print("http_bench.js start\n");

const listenerRid = listen();
libdeno.print(`listening http://127.0.0.1:4544/ rid = ${listenerRid}`);
libdeno.print(`listening http://127.0.0.1:4544/ rid = ${listenerRid}\n`);
while (true) {
const rid = await accept(listenerRid);
// libdeno.print(`accepted ${rid}`);
Oops, something went wrong.

0 comments on commit c054987

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.