Skip to content

Commit 50650e4

Browse files
authored
Modify poll_oneoff in libc-wasi to make it interruptible (bytecodealliance#1951)
1 parent 3cc132e commit 50650e4

File tree

2 files changed

+112
-8
lines changed

2 files changed

+112
-8
lines changed

core/iwasm/common/wasm_shared_memory.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,23 @@ notify_stale_threads_on_exception(WASMModuleInstanceCommon *module_inst)
111111
{
112112
AtomicWaitAddressArgs args = { 0 };
113113
uint32 i = 0, total_elem_count = 0;
114+
uint64 total_elem_count_size = 0;
114115

115116
os_mutex_lock(&shared_memory_list_lock);
116117

117118
/* count number of addresses in wait_map */
118119
bh_hash_map_traverse(wait_map, wait_map_address_count_callback,
119120
(void *)&total_elem_count);
120121

122+
if (!total_elem_count) {
123+
os_mutex_unlock(&shared_memory_list_lock);
124+
return;
125+
}
126+
121127
/* allocate memory */
122-
if (!(args.addr = wasm_runtime_malloc(sizeof(void *) * total_elem_count))) {
128+
total_elem_count_size = (uint64)sizeof(void *) * total_elem_count;
129+
if (total_elem_count_size >= UINT32_MAX
130+
|| !(args.addr = wasm_runtime_malloc((uint32)total_elem_count_size))) {
123131
LOG_ERROR(
124132
"failed to allocate memory for list of atomic wait addresses");
125133
os_mutex_unlock(&shared_memory_list_lock);

core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c

Lines changed: 103 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ typedef struct WASIContext {
6363
wasi_ctx_t
6464
wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst);
6565

66+
static inline size_t
67+
min(size_t a, size_t b)
68+
{
69+
return a > b ? b : a;
70+
}
71+
6672
static inline struct fd_table *
6773
wasi_ctx_get_curfds(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
6874
{
@@ -951,14 +957,105 @@ wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
951957
return wasmtime_ssp_path_remove_directory(curfds, fd, path, path_len);
952958
}
953959

960+
#if WASM_ENABLE_THREAD_MGR != 0
961+
static __wasi_timestamp_t
962+
get_timeout_for_poll_oneoff(const wasi_subscription_t *in,
963+
uint32 nsubscriptions)
964+
{
965+
__wasi_timestamp_t timeout = (__wasi_timestamp_t)-1;
966+
uint32 i = 0;
967+
968+
for (i = 0; i < nsubscriptions; ++i) {
969+
const __wasi_subscription_t *s = &in[i];
970+
if (s->u.type == __WASI_EVENTTYPE_CLOCK
971+
&& (s->u.u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME) == 0) {
972+
timeout = min(timeout, s->u.u.clock.timeout);
973+
}
974+
}
975+
return timeout;
976+
}
977+
978+
static void
979+
update_clock_subscription_data(wasi_subscription_t *in, uint32 nsubscriptions,
980+
const wasi_timestamp_t new_timeout)
981+
{
982+
uint32 i = 0;
983+
for (i = 0; i < nsubscriptions; ++i) {
984+
__wasi_subscription_t *s = &in[i];
985+
if (s->u.type == __WASI_EVENTTYPE_CLOCK) {
986+
s->u.u.clock.timeout = new_timeout;
987+
}
988+
}
989+
}
990+
991+
static wasi_errno_t
992+
execute_interruptible_poll_oneoff(wasm_module_inst_t module_inst,
993+
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
994+
struct fd_table *curfds,
995+
#endif
996+
const __wasi_subscription_t *in,
997+
__wasi_event_t *out, size_t nsubscriptions,
998+
size_t *nevents)
999+
{
1000+
if (nsubscriptions == 0) {
1001+
*nevents = 0;
1002+
return __WASI_ESUCCESS;
1003+
}
1004+
1005+
wasi_errno_t err;
1006+
__wasi_timestamp_t elapsed = 0;
1007+
1008+
const __wasi_timestamp_t timeout = get_timeout_for_poll_oneoff(
1009+
in, nsubscriptions),
1010+
time_quant = 1e9;
1011+
const uint64 size_to_copy =
1012+
nsubscriptions * (uint64)sizeof(wasi_subscription_t);
1013+
__wasi_subscription_t *in_copy = NULL;
1014+
1015+
if (size_to_copy >= UINT32_MAX
1016+
|| !(in_copy = (__wasi_subscription_t *)wasm_runtime_malloc(
1017+
(uint32)size_to_copy))) {
1018+
return __WASI_ENOMEM;
1019+
}
1020+
1021+
bh_memcpy_s(in_copy, size_to_copy, in, size_to_copy);
1022+
1023+
while (timeout == (__wasi_timestamp_t)-1 || elapsed <= timeout) {
1024+
elapsed += time_quant;
1025+
1026+
/* update timeout for clock subscription events */
1027+
update_clock_subscription_data(in_copy, nsubscriptions,
1028+
min(time_quant, timeout - elapsed));
1029+
err = wasmtime_ssp_poll_oneoff(curfds, in_copy, out, nsubscriptions,
1030+
nevents);
1031+
if (err) {
1032+
wasm_runtime_free(in_copy);
1033+
return err;
1034+
}
1035+
1036+
if (wasm_runtime_get_exception(module_inst) || *nevents > 0) {
1037+
wasm_runtime_free(in_copy);
1038+
1039+
if (*nevents) {
1040+
return __WASI_ESUCCESS;
1041+
}
1042+
return EINTR;
1043+
}
1044+
}
1045+
1046+
wasm_runtime_free(in_copy);
1047+
return __WASI_ESUCCESS;
1048+
}
1049+
#endif
1050+
9541051
static wasi_errno_t
9551052
wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
9561053
wasi_event_t *out, uint32 nsubscriptions, uint32 *nevents_app)
9571054
{
9581055
wasm_module_inst_t module_inst = get_module_inst(exec_env);
9591056
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
9601057
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
961-
size_t nevents;
1058+
size_t nevents = 0;
9621059
wasi_errno_t err;
9631060

9641061
if (!wasi_ctx)
@@ -969,7 +1066,12 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
9691066
|| !validate_native_addr(nevents_app, sizeof(uint32)))
9701067
return (wasi_errno_t)-1;
9711068

1069+
#if WASM_ENABLE_THREAD_MGR == 0
9721070
err = wasmtime_ssp_poll_oneoff(curfds, in, out, nsubscriptions, &nevents);
1071+
#else
1072+
err = execute_interruptible_poll_oneoff(module_inst, curfds, in, out,
1073+
nsubscriptions, &nevents);
1074+
#endif
9731075
if (err)
9741076
return err;
9751077

@@ -1861,12 +1963,6 @@ allocate_iovec_app_buffer(wasm_module_inst_t module_inst,
18611963
return __WASI_ESUCCESS;
18621964
}
18631965

1864-
static inline size_t
1865-
min(size_t a, size_t b)
1866-
{
1867-
return a > b ? b : a;
1868-
}
1869-
18701966
static wasi_errno_t
18711967
copy_buffer_to_iovec_app(wasm_module_inst_t module_inst, uint8 *buf_begin,
18721968
uint32 buf_size, iovec_app_t *data, uint32 data_len,

0 commit comments

Comments
 (0)