Skip to content

Commit

Permalink
cli: add --timeout option
Browse files Browse the repository at this point in the history
todo: add it to repl too?
  • Loading branch information
yamt committed Jun 18, 2023
1 parent 005284a commit f563a4a
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 11 deletions.
20 changes: 16 additions & 4 deletions cli/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ enum longopt {
opt_repl,
opt_repl_prompt,
opt_print_stats,
opt_timeout,
opt_trace,
opt_version,
opt_wasi,
Expand Down Expand Up @@ -95,6 +96,12 @@ static const struct option longopts[] = {
NULL,
opt_print_stats,
},
{
"timeout",
required_argument,
NULL,
opt_timeout,
},
{
"trace",
required_argument,
Expand Down Expand Up @@ -147,6 +154,7 @@ static const char *opt_metavars[] = {
[opt_wasi_env] = "NAME=VAR",
[opt_wasi_dir] = "DIR",
[opt_wasi_mapdir] = "GUEST_DIR::HOST_DIR",
[opt_timeout] = "TIMEOUT_MS",
[opt_trace] = "LEVEL",
[opt_repl_prompt] = "STRING",
[opt_max_frames] = "NUMBER_OF_FRAMES",
Expand Down Expand Up @@ -208,6 +216,7 @@ main(int argc, char *const *argv)
bool might_need_help = true;

int exit_status = 1;
int timeout_ms = -1;

#if defined(__NuttX__)
xlog_tracing = 0;
Expand All @@ -231,8 +240,8 @@ main(int argc, char *const *argv)
opts->load_options.generate_resulttype_cellidx = false;
break;
case opt_invoke:
ret = toywasm_repl_invoke(state, NULL, optarg, NULL,
true);
ret = toywasm_repl_invoke(state, NULL, optarg,
timeout_ms, NULL, true);
if (ret != 0) {
goto fail;
}
Expand Down Expand Up @@ -265,6 +274,9 @@ main(int argc, char *const *argv)
case opt_print_stats:
opts->print_stats = true;
break;
case opt_timeout:
timeout_ms = atoi(optarg);
break;
case opt_trace:
xlog_tracing = atoi(optarg);
break;
Expand Down Expand Up @@ -354,8 +366,8 @@ main(int argc, char *const *argv)
}
#endif
uint32_t wasi_exit_code = 0;
ret = toywasm_repl_invoke(state, NULL, "_start", &wasi_exit_code,
false);
ret = toywasm_repl_invoke(state, NULL, "_start", timeout_ms,
&wasi_exit_code, false);
if (ret != 0) {
xlog_error("invoke failed with %d", ret);
/*
Expand Down
43 changes: 37 additions & 6 deletions cli/repl.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "repl.h"
#include "report.h"
#include "suspend.h"
#include "timeutil.h"
#include "toywasm_version.h"
#include "type.h"
#include "usched.h"
Expand Down Expand Up @@ -809,18 +810,46 @@ unescape(char *p0, size_t *lenp)
static int
exec_func(struct exec_context *ctx, uint32_t funcidx,
const struct resulttype *ptype, const struct resulttype *rtype,
const struct val *param, struct val *result,
const struct val *param, struct val *result, int timeout_ms,
const struct trap_info **trapp)
{
struct timespec abstimeout;
int ret;
ret = instance_execute_func(ctx, funcidx, ptype, rtype, param, result);
ret = instance_execute_handle_restart(ctx, ret);
*trapp = NULL;
if (timeout_ms > 0) {
const static atomic_uint one = 1;
ret = abstime_from_reltime_ms(CLOCK_MONOTONIC, &abstimeout,
timeout_ms);
if (ret != 0) {
goto fail;
}
ctx->intrp = &one;
}
ret = instance_execute_func(ctx, funcidx, ptype, rtype, param, result);
do {
if (ret == ETOYWASMUSERINTERRUPT) {
struct timespec now;
int ret1;
assert(timeout_ms > 0);
ret1 = timespec_now(CLOCK_MONOTONIC, &now);
if (ret1 != 0) {
ret = ret1;
goto fail;
}
if (timespec_cmp(&now, &abstimeout) > 0) {
xlog_error("execution timed out");
ret = ETIMEDOUT;
goto fail;
}
}
ret = instance_execute_handle_restart_once(ctx, ret);
} while (IS_RESTARTABLE(ret));
if (ret == ETOYWASMTRAP) {
assert(ctx->trapped);
const struct trap_info *trap = &ctx->trap;
*trapp = trap;
}
fail:
return ret;
}

Expand All @@ -829,7 +858,8 @@ exec_func(struct exec_context *ctx, uint32_t funcidx,
*/
int
toywasm_repl_invoke(struct repl_state *state, const char *modname,
const char *cmd, uint32_t *exitcodep, bool print_result)
const char *cmd, int timeout_ms, uint32_t *exitcodep,
bool print_result)
{
char *cmd1 = strdup(cmd);
if (cmd1 == NULL) {
Expand Down Expand Up @@ -910,7 +940,8 @@ toywasm_repl_invoke(struct repl_state *state, const char *modname,
struct wasi_threads_instance *wasi_threads = state->wasi_threads;
wasi_threads_setup_exec_context(wasi_threads, ctx);
#endif
ret = exec_func(ctx, funcidx, ptype, rtype, param, result, &trap);
ret = exec_func(ctx, funcidx, ptype, rtype, param, result, timeout_ms,
&trap);
#if defined(TOYWASM_ENABLE_WASI_THREADS)
wasi_threads_complete_exec(wasi_threads, &trap);
#endif
Expand Down Expand Up @@ -1097,7 +1128,7 @@ repl_module_subcmd(struct repl_state *state, const char *cmd,
goto fail;
}
} else if (!strcmp(cmd, "invoke") && opt != NULL) {
ret = toywasm_repl_invoke(state, modname, opt, NULL, true);
ret = toywasm_repl_invoke(state, modname, opt, -1, NULL, true);
if (ret != 0) {
goto fail;
}
Expand Down
2 changes: 1 addition & 1 deletion cli/repl.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ int toywasm_repl_load(struct repl_state *state, const char *modname,
int toywasm_repl_register(struct repl_state *state, const char *modname,
const char *register_name);
int toywasm_repl_invoke(struct repl_state *state, const char *modname,
const char *cmd, uint32_t *exitcodep,
const char *cmd, int timeout_ms, uint32_t *exitcodep,
bool print_result);
void toywasm_repl_print_version(void);

Expand Down

0 comments on commit f563a4a

Please sign in to comment.