mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-14 13:41:31 +00:00
Modify poll_oneoff in libc-wasi to make it interruptible (#1951)
This commit is contained in:
parent
3cc132e8fc
commit
50650e4634
|
@ -111,6 +111,7 @@ notify_stale_threads_on_exception(WASMModuleInstanceCommon *module_inst)
|
||||||
{
|
{
|
||||||
AtomicWaitAddressArgs args = { 0 };
|
AtomicWaitAddressArgs args = { 0 };
|
||||||
uint32 i = 0, total_elem_count = 0;
|
uint32 i = 0, total_elem_count = 0;
|
||||||
|
uint64 total_elem_count_size = 0;
|
||||||
|
|
||||||
os_mutex_lock(&shared_memory_list_lock);
|
os_mutex_lock(&shared_memory_list_lock);
|
||||||
|
|
||||||
|
@ -118,8 +119,15 @@ notify_stale_threads_on_exception(WASMModuleInstanceCommon *module_inst)
|
||||||
bh_hash_map_traverse(wait_map, wait_map_address_count_callback,
|
bh_hash_map_traverse(wait_map, wait_map_address_count_callback,
|
||||||
(void *)&total_elem_count);
|
(void *)&total_elem_count);
|
||||||
|
|
||||||
|
if (!total_elem_count) {
|
||||||
|
os_mutex_unlock(&shared_memory_list_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* allocate memory */
|
/* allocate memory */
|
||||||
if (!(args.addr = wasm_runtime_malloc(sizeof(void *) * total_elem_count))) {
|
total_elem_count_size = (uint64)sizeof(void *) * total_elem_count;
|
||||||
|
if (total_elem_count_size >= UINT32_MAX
|
||||||
|
|| !(args.addr = wasm_runtime_malloc((uint32)total_elem_count_size))) {
|
||||||
LOG_ERROR(
|
LOG_ERROR(
|
||||||
"failed to allocate memory for list of atomic wait addresses");
|
"failed to allocate memory for list of atomic wait addresses");
|
||||||
os_mutex_unlock(&shared_memory_list_lock);
|
os_mutex_unlock(&shared_memory_list_lock);
|
||||||
|
|
|
@ -63,6 +63,12 @@ typedef struct WASIContext {
|
||||||
wasi_ctx_t
|
wasi_ctx_t
|
||||||
wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst);
|
wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst);
|
||||||
|
|
||||||
|
static inline size_t
|
||||||
|
min(size_t a, size_t b)
|
||||||
|
{
|
||||||
|
return a > b ? b : a;
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct fd_table *
|
static inline struct fd_table *
|
||||||
wasi_ctx_get_curfds(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
|
wasi_ctx_get_curfds(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
|
||||||
{
|
{
|
||||||
|
@ -951,6 +957,97 @@ wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||||
return wasmtime_ssp_path_remove_directory(curfds, fd, path, path_len);
|
return wasmtime_ssp_path_remove_directory(curfds, fd, path, path_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
static __wasi_timestamp_t
|
||||||
|
get_timeout_for_poll_oneoff(const wasi_subscription_t *in,
|
||||||
|
uint32 nsubscriptions)
|
||||||
|
{
|
||||||
|
__wasi_timestamp_t timeout = (__wasi_timestamp_t)-1;
|
||||||
|
uint32 i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < nsubscriptions; ++i) {
|
||||||
|
const __wasi_subscription_t *s = &in[i];
|
||||||
|
if (s->u.type == __WASI_EVENTTYPE_CLOCK
|
||||||
|
&& (s->u.u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME) == 0) {
|
||||||
|
timeout = min(timeout, s->u.u.clock.timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_clock_subscription_data(wasi_subscription_t *in, uint32 nsubscriptions,
|
||||||
|
const wasi_timestamp_t new_timeout)
|
||||||
|
{
|
||||||
|
uint32 i = 0;
|
||||||
|
for (i = 0; i < nsubscriptions; ++i) {
|
||||||
|
__wasi_subscription_t *s = &in[i];
|
||||||
|
if (s->u.type == __WASI_EVENTTYPE_CLOCK) {
|
||||||
|
s->u.u.clock.timeout = new_timeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static wasi_errno_t
|
||||||
|
execute_interruptible_poll_oneoff(wasm_module_inst_t module_inst,
|
||||||
|
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||||
|
struct fd_table *curfds,
|
||||||
|
#endif
|
||||||
|
const __wasi_subscription_t *in,
|
||||||
|
__wasi_event_t *out, size_t nsubscriptions,
|
||||||
|
size_t *nevents)
|
||||||
|
{
|
||||||
|
if (nsubscriptions == 0) {
|
||||||
|
*nevents = 0;
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasi_errno_t err;
|
||||||
|
__wasi_timestamp_t elapsed = 0;
|
||||||
|
|
||||||
|
const __wasi_timestamp_t timeout = get_timeout_for_poll_oneoff(
|
||||||
|
in, nsubscriptions),
|
||||||
|
time_quant = 1e9;
|
||||||
|
const uint64 size_to_copy =
|
||||||
|
nsubscriptions * (uint64)sizeof(wasi_subscription_t);
|
||||||
|
__wasi_subscription_t *in_copy = NULL;
|
||||||
|
|
||||||
|
if (size_to_copy >= UINT32_MAX
|
||||||
|
|| !(in_copy = (__wasi_subscription_t *)wasm_runtime_malloc(
|
||||||
|
(uint32)size_to_copy))) {
|
||||||
|
return __WASI_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
bh_memcpy_s(in_copy, size_to_copy, in, size_to_copy);
|
||||||
|
|
||||||
|
while (timeout == (__wasi_timestamp_t)-1 || elapsed <= timeout) {
|
||||||
|
elapsed += time_quant;
|
||||||
|
|
||||||
|
/* update timeout for clock subscription events */
|
||||||
|
update_clock_subscription_data(in_copy, nsubscriptions,
|
||||||
|
min(time_quant, timeout - elapsed));
|
||||||
|
err = wasmtime_ssp_poll_oneoff(curfds, in_copy, out, nsubscriptions,
|
||||||
|
nevents);
|
||||||
|
if (err) {
|
||||||
|
wasm_runtime_free(in_copy);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wasm_runtime_get_exception(module_inst) || *nevents > 0) {
|
||||||
|
wasm_runtime_free(in_copy);
|
||||||
|
|
||||||
|
if (*nevents) {
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
}
|
||||||
|
return EINTR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_runtime_free(in_copy);
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static wasi_errno_t
|
static wasi_errno_t
|
||||||
wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
|
wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
|
||||||
wasi_event_t *out, uint32 nsubscriptions, uint32 *nevents_app)
|
wasi_event_t *out, uint32 nsubscriptions, uint32 *nevents_app)
|
||||||
|
@ -958,7 +1055,7 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
|
||||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||||
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
|
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
|
||||||
size_t nevents;
|
size_t nevents = 0;
|
||||||
wasi_errno_t err;
|
wasi_errno_t err;
|
||||||
|
|
||||||
if (!wasi_ctx)
|
if (!wasi_ctx)
|
||||||
|
@ -969,7 +1066,12 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
|
||||||
|| !validate_native_addr(nevents_app, sizeof(uint32)))
|
|| !validate_native_addr(nevents_app, sizeof(uint32)))
|
||||||
return (wasi_errno_t)-1;
|
return (wasi_errno_t)-1;
|
||||||
|
|
||||||
|
#if WASM_ENABLE_THREAD_MGR == 0
|
||||||
err = wasmtime_ssp_poll_oneoff(curfds, in, out, nsubscriptions, &nevents);
|
err = wasmtime_ssp_poll_oneoff(curfds, in, out, nsubscriptions, &nevents);
|
||||||
|
#else
|
||||||
|
err = execute_interruptible_poll_oneoff(module_inst, curfds, in, out,
|
||||||
|
nsubscriptions, &nevents);
|
||||||
|
#endif
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -1861,12 +1963,6 @@ allocate_iovec_app_buffer(wasm_module_inst_t module_inst,
|
||||||
return __WASI_ESUCCESS;
|
return __WASI_ESUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t
|
|
||||||
min(size_t a, size_t b)
|
|
||||||
{
|
|
||||||
return a > b ? b : a;
|
|
||||||
}
|
|
||||||
|
|
||||||
static wasi_errno_t
|
static wasi_errno_t
|
||||||
copy_buffer_to_iovec_app(wasm_module_inst_t module_inst, uint8 *buf_begin,
|
copy_buffer_to_iovec_app(wasm_module_inst_t module_inst, uint8 *buf_begin,
|
||||||
uint32 buf_size, iovec_app_t *data, uint32 data_len,
|
uint32 buf_size, iovec_app_t *data, uint32 data_len,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user