From 381075a36d07610e339364a39942bef9e2fe360f Mon Sep 17 00:00:00 2001 From: Greg Date: Tue, 25 Jul 2023 02:39:02 +0900 Subject: [PATCH] c-api: Expose async_stack_size configuration --- crates/c-api/Cargo.toml | 3 +- crates/c-api/include/wasmtime/config.h | 64 ++++++++++++++++++++++---- crates/c-api/src/config.rs | 6 +++ 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/crates/c-api/Cargo.toml b/crates/c-api/Cargo.toml index a464c0dbd506..3967559e6c85 100644 --- a/crates/c-api/Cargo.toml +++ b/crates/c-api/Cargo.toml @@ -33,8 +33,9 @@ cap-std = { workspace = true, optional = true } wasi-common = { workspace = true, optional = true } [features] -default = ['jitdump', 'wat', 'wasi', 'cache', 'parallel-compilation'] +default = ['jitdump', 'wat', 'wasi', 'cache', 'parallel-compilation', 'async'] jitdump = ["wasmtime/jitdump"] cache = ["wasmtime/cache"] parallel-compilation = ['wasmtime/parallel-compilation'] wasi = ['wasi-cap-std-sync', 'wasmtime-wasi', 'cap-std', 'wasi-common'] +async = ['wasmtime/async'] diff --git a/crates/c-api/include/wasmtime/config.h b/crates/c-api/include/wasmtime/config.h index 3518b8e45eeb..f0924070ab68 100644 --- a/crates/c-api/include/wasmtime/config.h +++ b/crates/c-api/include/wasmtime/config.h @@ -126,20 +126,66 @@ WASMTIME_CONFIG_PROP(void, consume_fuel, bool) WASMTIME_CONFIG_PROP(void, epoch_interruption, bool) /** - * \brief Configures the maximum stack size, in bytes, that JIT code can use. + * \brief Configures the maximum amount of stack space available, in bytes, + * for executing WebAssembly code. * - * This setting is 2MB by default. Configuring this setting will limit the - * amount of native stack space that JIT code can use while it is executing. If - * you're hitting stack overflow you can try making this setting larger, or if - * you'd like to limit wasm programs to less stack you can also configure this. + * WebAssembly has well-defined semantics on stack overflow. This is + * intended to be a knob which can help configure how much stack space + * wasm execution is allowed to consume. Note that the number here is not + * super-precise, but rather wasm will take at most "pretty close to this + * much" stack space. * - * Note that this setting is not interpreted with 100% precision. Additionally - * the amount of stack space that wasm takes is always relative to the first - * invocation of wasm on the stack, so recursive calls with host frames in the - * middle will all need to fit within this setting. + * If a wasm call (or series of nested wasm calls) take more stack space + * than the `size` specified then a stack overflow trap will be raised. + * + * Caveat: this knob only limits the stack space consumed by wasm code. + * More importantly, it does not ensure that this much stack space is + * available on the calling thread stack. Exhausting the thread stack + * typically leads to an **abort** of the process. + * + * Here are some examples of how that could happen: + * + * - Let's assume this option is set to 2 MiB and then a thread that has + * a stack with 512 KiB left. + * + * If wasm code consumes more than 512 KiB then the process will be aborted. + * + * - Assuming the same conditions, but this time wasm code does not consume + * any stack but calls into a host function. The host function consumes + * more than 512 KiB of stack space. The process will be aborted. + * + * There's another gotcha related to recursive calling into wasm: the stack + * space consumed by a host function is counted towards this limit. The + * host functions are not prevented from consuming more than this limit. + * However, if the host function that used more than this limit and called + * back into wasm, then the execution will trap immediatelly because of + * stack overflow. + * + * When the `async` feature is enabled, this value cannot exceed the + * `async_stack_size` option. Be careful not to set this value too close + * to `async_stack_size` as doing so may limit how much stack space + * is available for host functions. + * + * By default this option is 512 KiB. */ WASMTIME_CONFIG_PROP(void, max_wasm_stack, size_t) +/** + * \brief Configures the size of the stacks, in bytes, used for asynchronous + * execution. + * + * This setting configures the size of the stacks that are allocated for + * asynchronous execution. The value cannot be less than `max_wasm_stack`. + * + * The amount of stack space guaranteed for host functions is + * `async_stack_size - max_wasm_stack`, so take care not to set these two + * values close to one another; doing so may cause host functions to overflow + * the stack and abort the process. + * + * By default this option is 2 MiB. + */ +WASMTIME_CONFIG_PROP(void, async_stack_size, size_t) + /** * \brief Configures whether the WebAssembly threading proposal is enabled. * diff --git a/crates/c-api/src/config.rs b/crates/c-api/src/config.rs index 42032d0f6891..eba6998127bd 100644 --- a/crates/c-api/src/config.rs +++ b/crates/c-api/src/config.rs @@ -66,6 +66,12 @@ pub extern "C" fn wasmtime_config_max_wasm_stack_set(c: &mut wasm_config_t, size c.config.max_wasm_stack(size); } +#[no_mangle] +#[cfg(feature = "async")] +pub extern "C" fn wasmtime_config_async_stack_size_set(c: &mut wasm_config_t, size: usize) { + c.config.async_stack_size(size); +} + #[no_mangle] pub extern "C" fn wasmtime_config_wasm_threads_set(c: &mut wasm_config_t, enable: bool) { c.config.wasm_threads(enable);