Add experiment for shared-memory usage

This commit is contained in:
Maximilian Ammann 2021-12-09 12:20:23 +01:00
parent f4bfff51d3
commit 264c2c2481
9 changed files with 111 additions and 38 deletions

9
.cargo/config.toml Normal file
View File

@ -0,0 +1,9 @@
[target.wasm32-unknown-unknown]
rustflags = [
# Enabled unstable APIs from web_sys
"--cfg=web_sys_unstable_apis",
# Enables features which are required for shared-memory
"-C", "target-feature=+atomics,+bulk-memory,+mutable-globals",
# Enables the possibility to import memory into wasm. shared-memory option is required.
"-C", "link-args=--shared-memory --import-memory",
]

View File

@ -12,7 +12,7 @@ web-webgl = ["wgpu/webgl"]
[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1"
winit = { version = "0.25", features = ["web-sys"] }
web-sys = { version = "0.3", features = ["Worker", "MessageEvent"]}
web-sys = { version = "0.3", features = ["Worker", "WorkerOptions", "WorkerType", "MessageEvent"] }
js-sys = "0.3"
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"

View File

@ -1,13 +0,0 @@
use log::info;
use wasm_bindgen::closure::Closure;
use wasm_bindgen::JsValue;
use web_sys::Window;
pub fn test_fetch(web_window: &Window) {
let cb: Closure<dyn FnMut(JsValue) + 'static> = Closure::wrap(Box::new(|value: JsValue| {
info!("interval elapsed!");
}) as Box<dyn FnMut(JsValue)>);
web_window.fetch_with_str("http://localhost:5555/web/mapr.html").then(&cb);
cb.forget();
}

View File

@ -15,32 +15,17 @@ use winit::platform::web::WindowBuilderExtWebSys;
use winit::window::{Window, WindowBuilder};
mod io;
mod wasm_experiment;
#[wasm_bindgen(start)]
pub fn start() {
console_log::init_with_level(Level::Info).expect("error initializing log");
//console_log::init_with_level(Level::Info).expect("error initializing log");
panic::set_hook(Box::new(console_error_panic_hook::hook));
//wasm_bindgen_futures::spawn_local(run());
}
#[wasm_bindgen]
pub async fn run() {
let worker = web_sys::Worker::new("./fetch-worker.js").unwrap();
let callback = Closure::wrap(Box::new(move |event: MessageEvent| {
info!("{}{:?}", "Received response: ", &event.data());
}) as Box<dyn FnMut(_)>);
let sab = js_sys::SharedArrayBuffer::new(10);
let u8sab = js_sys::Uint8Array::new(sab.as_ref());
u8sab.set_index(0, 13);
//worker_handle.set_onmessage(Some(callback.as_ref().unchecked_ref()));
//worker_handle.post_message(&JsValue::from("hello"));
worker.post_message(&u8sab.as_ref());
//callback.forget();
let event_loop = EventLoop::new();
let web_window: WebWindow = web_sys::window().unwrap();
let document = web_window.document().unwrap();
@ -62,5 +47,6 @@ pub async fn run() {
height: body.client_height(),
});
super::setup(window, event_loop, Some(u8sab)).await;
super::setup(window, event_loop, None).await;
}

View File

@ -0,0 +1,66 @@
use log::info;
use wasm_bindgen::closure::Closure;
use wasm_bindgen::JsValue;
use web_sys::MessageEvent;
use web_sys::Window;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn test_fetch(web_window: &Window) {
let cb: Closure<dyn FnMut(JsValue) + 'static> = Closure::wrap(Box::new(|value: JsValue| {
info!("interval elapsed!");
}) as Box<dyn FnMut(JsValue)>);
web_window.fetch_with_str("http://localhost:5555/web/mapr.html").then(&cb);
cb.forget();
}
#[wasm_bindgen]
pub fn test_shared_mem(memory: &JsValue) {
let worker = web_sys::Worker::new_with_options(
"./fetch-worker.js",
// Works only on chrome
&web_sys::WorkerOptions::new().type_(web_sys::WorkerType::Module),
)
.unwrap();
let callback = Closure::wrap(Box::new(move |event: MessageEvent| {
info!("{}{:?}", "Received response: ", &event.data());
}) as Box<dyn FnMut(_)>);
let sab = js_sys::SharedArrayBuffer::new(10);
let u8sab = js_sys::Uint8Array::new(sab.as_ref());
u8sab.set_index(0, 13);
//worker_handle.set_onmessage(Some(callback.as_ref().unchecked_ref()));
//worker_handle.post_message(&JsValue::from("hello"));
info!("test");
info!("{:?}", &memory);
/* let msg = js_sys::Array::new();
msg.push(memory.as_ref());
msg.push(&JsValue::from(test_alloc(100)));
msg.push(&u8sab);
worker.post_message(&msg.as_ref());
*/
//callback.forget();
}
#[wasm_bindgen]
pub fn test_alloc() -> *mut u8 {
let mut buf: Vec<u8> = Vec::with_capacity(100);
buf.push(54);
let ptr = buf.as_mut_ptr();
std::mem::forget(buf);
return ptr;
}
#[wasm_bindgen]
pub fn get54(ptr: *mut u8) -> u8 {
unsafe {
let data: Vec<u8> = Vec::from_raw_parts(ptr, 100, 100);
data[0]
}
}

View File

@ -8,7 +8,7 @@ eval set -- "$TEMP"
while true; do
case "$1" in
-g)
webgl_flag="--features web-webgl"
webgl_flag="web-webgl,"
shift 2
;;
*)
@ -18,8 +18,10 @@ while true; do
done
# shellcheck disable=SC2086
RUSTFLAGS=--cfg=web_sys_unstable_apis cargo build $webgl_flag --target wasm32-unknown-unknown --bin mapr
cargo +nightly build --features "$webgl_flag" --target wasm32-unknown-unknown -Z build-std=std,panic_abort
# TODO: Untested: --reference-types
wasm-bindgen --target web --out-dir web target/wasm32-unknown-unknown/debug/mapr.wasm
xdg-open "https://localhost:5555/web/mapr.html"
#xdg-open "https://localhost:5555/web/mapr.html"
python3 tools/tls-http-server.py

View File

@ -12,5 +12,5 @@ class Handler(SimpleHTTPRequestHandler):
if __name__ == '__main__':
socketserver.TCPServer.allow_reuse_address = True
with socketserver.TCPServer(('0.0.0.0', 5555), Handler) as httpd:
httpd.socket = ssl.wrap_socket(httpd.socket, certfile='tools/server.pem', server_side=True)
#httpd.socket = ssl.wrap_socket(httpd.socket, certfile='tools/server.pem', server_side=True)
httpd.serve_forever()

13
web/fetch-worker.js Normal file
View File

@ -0,0 +1,13 @@
import init from "./mapr.js";
var init_output;
onmessage = async m => {
let msg = m.data;
if (msg.type === "init") {
init_output = await init(undefined, msg.memory);
console.log(msg.address)
postMessage(init_output.get54(msg.address));
}
};

View File

@ -5,10 +5,20 @@
<body style="margin: 0; padding: 0;">
<script type="module">
import init from "./mapr.js";
const memory = new WebAssembly.Memory({initial: 1024, maximum: 10 * 1024, shared: true});
const init_output = await init(undefined, memory);
const init_output = await init();
const fetch_worker = new Worker("./fetch-worker.js", {
type: "module",
});
await init_output.run();
fetch_worker.postMessage({type: "init", memory, address: init_output.test_alloc()});
fetch_worker.onmessage = (e) => {
console.log(e)
}
//await init_output.run();
</script>
<canvas id="mapr"></canvas>
</body>