Skip to content

Commit

Permalink
introduce IS_RESTARTABLE macro
Browse files Browse the repository at this point in the history
no functional changes are intended for now.

in future, i might add other restartable errors.
  • Loading branch information
yamt committed Jun 15, 2023
1 parent 1f01aeb commit 191c339
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 31 deletions.
18 changes: 9 additions & 9 deletions lib/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,15 +540,15 @@ do_host_call(struct exec_context *ctx, const struct funcinst *finst)
ret = finst->u.host.func(ctx, finst->u.host.instance, ft,
&VEC_NEXTELEM(ctx->stack),
&VEC_NEXTELEM(ctx->stack));
assert(ret == ETOYWASMRESTART || ctx->restart_type == RESTART_NONE);
assert(IS_RESTARTABLE(ret) || ctx->restart_type == RESTART_NONE);
if (ret != 0) {
if (ret == ETOYWASMRESTART) {
if (IS_RESTARTABLE(ret)) {
/*
* Restore the stack pointer for restarting.
*
* Note: it's a responsibility of host functions
* to keep function arguments on the stack intact
* when returning ETOYWASMRESTART.
* when returning a restartable error.
*/
ctx->stack.lsize += nparams;
STAT_INC(ctx->stats.call_restart);
Expand Down Expand Up @@ -984,7 +984,7 @@ exec_expr_continue(struct exec_context *ctx)
assert(ctx->frames.lsize > 0);
ret = do_return_call(ctx, ctx->event_u.call.func);
if (ret != 0) {
if (ret == ETOYWASMRESTART) {
if (IS_RESTARTABLE(ret)) {
ctx->event = EXEC_EVENT_CALL;
/*
* Note: because we have changed
Expand Down Expand Up @@ -1028,7 +1028,7 @@ exec_expr_continue(struct exec_context *ctx)
*
* Instead, this implementation relies on the
* opcode functions set up an explicit execution
* event when returning ETOYWASMRESTART.
* event when returning a restartable error.
*/
ret = restart_insn(ctx);
goto after_insn;
Expand All @@ -1044,7 +1044,7 @@ exec_expr_continue(struct exec_context *ctx)
n = 0;
ret = check_interrupt(ctx);
if (ret != 0) {
if (ret == ETOYWASMRESTART) {
if (IS_RESTARTABLE(ret)) {
STAT_INC(ctx->stats.exec_loop_restart);
}
return ret;
Expand All @@ -1053,7 +1053,7 @@ exec_expr_continue(struct exec_context *ctx)
struct cell *stack = &VEC_NEXTELEM(ctx->stack);
ret = fetch_exec_next_insn(ctx->p, stack, ctx);
after_insn:
assert((ret == ETOYWASMRESTART) ==
assert(IS_RESTARTABLE(ret) ==
(ctx->event == EXEC_EVENT_RESTART_INSN));
if (ret != 0) {
if (ctx->trapped) {
Expand Down Expand Up @@ -1149,7 +1149,7 @@ exec_const_expr(const struct expr *expr, enum valtype type, struct val *result,
* it's very unlikely for a const expr to use a restart.
* but just in case.
*/
while (ret == ETOYWASMRESTART) {
while (IS_RESTARTABLE(ret)) {
xlog_trace("%s: restarting execution of a const expr\n",
__func__);
ret = exec_expr_continue(ctx);
Expand Down Expand Up @@ -1605,7 +1605,7 @@ retry:;
}
ret = 0;
fail:
if (ret == ETOYWASMRESTART) {
if (IS_RESTARTABLE(ret)) {
if (abstimeout != NULL) {
assert(abstimeout == &ctx->restart_u.timer.abstimeout);
ctx->restart_type = RESTART_TIMER;
Expand Down
2 changes: 2 additions & 0 deletions lib/exec_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ struct funcframe {
#define ETOYWASMTRAP -1
#define ETOYWASMRESTART -2

#define IS_RESTARTABLE(error) ((error) == ETOYWASMRESTART)

enum trapid {
TRAP_MISC,
TRAP_DIV_BY_ZERO,
Expand Down
8 changes: 4 additions & 4 deletions lib/insn.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ read_memarg_nocheck(const uint8_t **pp, struct memarg *arg)
#define INSN_FAIL_RESTARTABLE(NAME) \
assert(ret != 0); \
if (EXECUTING) { \
if (ret == ETOYWASMRESTART) { \
if (IS_RESTARTABLE(ret)) { \
struct exec_context *ectx = ECTX; \
ectx->stack.lsize = saved_stack_ptr; \
ectx->event = EXEC_EVENT_RESTART_INSN; \
Expand All @@ -501,7 +501,7 @@ read_memarg_nocheck(const uint8_t **pp, struct memarg *arg)
#endif
#define INSN_FAIL \
assert(ret != 0); \
assert(ret != ETOYWASMRESTART); \
assert(!IS_RESTARTABLE(ret)); \
return ret
#define STACK &VEC_NEXTELEM(ECTX->stack)
#define STACK_ADJ(n) ECTX->stack.lsize += (n)
Expand Down Expand Up @@ -553,7 +553,7 @@ read_memarg_nocheck(const uint8_t **pp, struct memarg *arg)
#define PREPARE_FOR_POSSIBLE_RESTART struct cell *saved_stack_ptr = stack
#define INSN_FAIL_RESTARTABLE(NAME) \
assert(ret != 0); \
if (ret == ETOYWASMRESTART) { \
if (IS_RESTARTABLE(ret)) { \
ctx->p = ORIG_PC; \
stack = saved_stack_ptr; \
SAVE_STACK_PTR; \
Expand All @@ -563,7 +563,7 @@ read_memarg_nocheck(const uint8_t **pp, struct memarg *arg)
return ret
#define INSN_FAIL \
assert(ret != 0); \
assert(ret != ETOYWASMRESTART); \
assert(!IS_RESTARTABLE(ret)); \
return ret
#define ep NULL
#define STACK stack
Expand Down
6 changes: 3 additions & 3 deletions lib/instance.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ instance_create_execute_init(struct instance *inst, struct exec_context *ctx)
assert(m->start < m->nimportedfuncs + m->nfuncs);
struct funcinst *finst = VEC_ELEM(inst->funcs, m->start);
ret = invoke(finst, NULL, NULL, NULL, NULL, ctx);
while (ret == ETOYWASMRESTART) {
while (IS_RESTARTABLE(ret)) {
xlog_trace("%s: restarting execution of the start "
"function\n",
__func__);
Expand Down Expand Up @@ -581,7 +581,7 @@ instance_execute_func(struct exec_context *ctx, uint32_t funcidx,
ctx);
if (ret == 0) {
vals_from_cells(results, result_cells, resulttype);
} else if (ret == ETOYWASMRESTART) {
} else if (IS_RESTARTABLE(ret)) {
/*
* ctx->nresults is set by invoke().
* while it's redundant, it can be used by
Expand Down Expand Up @@ -640,7 +640,7 @@ int
instance_execute_handle_restart(struct exec_context *ctx, int exec_ret)
{
int ret = exec_ret;
while (ret == ETOYWASMRESTART) {
while (IS_RESTARTABLE(ret)) {
#if defined(TOYWASM_ENABLE_WASM_THREADS)
suspend_parked(ctx->cluster);
#endif
Expand Down
15 changes: 9 additions & 6 deletions lib/instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,12 @@ void instance_destroy(struct instance *inst);
* execute the function.
*
* in addition to usual <errno.h> error numbers, this function can
* return following toywasm-specific errors:
* return following toywasm-specific errors.
* Some of them are restartable, which can be checked using
* the IS_RESTARTABLE macro.
*
* ETOYWASMRESTART: the execution has been suspended for some reasons.
* ETOYWASMRESTART (or other restartable error):
* the execution has been suspended for some reasons.
* possible reasons include:
*
* - suspend_threads mechanism, which is used for
Expand Down Expand Up @@ -83,7 +86,7 @@ int instance_execute_func_nocheck(struct exec_context *ctx, uint32_t funcidx,
* instance_execute_continue:
*
* when one of instance_execute_xxx functions including the following ones
* returned ETOYWASMRESTART, the app can resume the execution by calling
* returned a restartable error, the app can resume the execution by calling
* this function.
*
* - instance_execute_func
Expand All @@ -97,9 +100,9 @@ int instance_execute_continue(struct exec_context *ctx);
/*
* instance_execute_handle_restart:
*
* perform the default ETOYWASMRESTART handling.
* this function never returns ETOYWASMRESTART.
* if the given exec_ret is not ETOYWASMRESTART, this function just
* perform the default handling of a restartable error.
* this function never returns a restartable error.
* if the given exec_ret is not a restartable error, this function just
* returns it as it is.
*/
int instance_execute_handle_restart(struct exec_context *ctx, int exec_ret);
Expand Down
2 changes: 1 addition & 1 deletion lib/usched.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ sched_run(struct sched *sched, struct exec_context *caller)
* calling sched_enqueue.
*/
ret = instance_execute_continue(ctx);
if (ret == ETOYWASMRESTART) {
if (IS_RESTARTABLE(ret)) {
xlog_trace("%s: re-enqueueing ctx %p", __func__,
(void *)ctx);
LIST_INSERT_TAIL(q, ctx, rq);
Expand Down
11 changes: 5 additions & 6 deletions libwasi/wasi.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ wasi_poll(struct exec_context *ctx, struct pollfd *fds, nfds_t nfds,

host_ret = check_interrupt(ctx);
if (host_ret != 0) {
if (host_ret == ETOYWASMRESTART) {
if (IS_RESTARTABLE(host_ret)) {
if (abstimeout != NULL) {
assert(abstimeout ==
&ctx->restart_u.timer
Expand Down Expand Up @@ -656,8 +656,7 @@ wasi_poll(struct exec_context *ctx, struct pollfd *fds, nfds_t nfds,
fail:
assert(host_ret != 0 || ret >= 0);
assert(host_ret != 0 || ret != 0 || *neventsp > 0);
assert(host_ret == ETOYWASMRESTART ||
ctx->restart_type == RESTART_NONE);
assert(IS_RESTARTABLE(host_ret) || ctx->restart_type == RESTART_NONE);
if (host_ret == 0) {
*retp = ret;
}
Expand All @@ -672,7 +671,7 @@ wait_fd_ready(struct exec_context *ctx, int hostfd, short event, int *retp)
pfd.events = event;
int nev;
int ret = wasi_poll(ctx, &pfd, 1, -1, retp, &nev);
if (ret == ETOYWASMRESTART) {
if (IS_RESTARTABLE(ret)) {
xlog_trace("%s: restarting", __func__);
}
return ret;
Expand Down Expand Up @@ -2026,12 +2025,12 @@ wasi_poll_oneoff(struct exec_context *ctx, struct host_instance *hi,
wasi_convert_errno(ret));
}
free(pollfds);
if (host_ret != ETOYWASMRESTART) {
if (!IS_RESTARTABLE(host_ret)) {
/*
* avoid leaving a stale restart state.
*
* consider:
* 1. poll_oneoff returns ETOYWASMRESTART with
* 1. poll_oneoff returns a restartable error with
* restart_abstimeout saved.
* 2. exec_expr_continue restarts the poll_oneoff.
* 3. however, for some reasons, poll_oneoff doesn't
Expand Down
4 changes: 2 additions & 2 deletions libwasi/wasi_threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ user_runner_exec_start(struct thread_arg *arg)
ctx->exec_done = user_runner_exec_done;
ctx->exec_done_arg = arg;
ret = exec_thread_start_func(ctx, arg);
if (ret == ETOYWASMRESTART) {
if (IS_RESTARTABLE(ret)) {
struct sched *sched = wasi_threads_sched(arg->wasi);
sched_enqueue(sched, ctx);
} else {
Expand All @@ -381,7 +381,7 @@ runner(void *vp)
exec_context_init(ctx, arg->inst);

ret = exec_thread_start_func(ctx, arg);
while (ret == ETOYWASMRESTART) {
while (IS_RESTARTABLE(ret)) {
suspend_parked(ctx->cluster);
xlog_trace("%s: restarting execution\n", __func__);
ret = instance_execute_continue(ctx);
Expand Down

0 comments on commit 191c339

Please sign in to comment.