Skip to content

Commit

Permalink
make check_interval adaptive
Browse files Browse the repository at this point in the history
  • Loading branch information
yamt committed May 15, 2023
1 parent 3502af3 commit 38c4fd0
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 5 deletions.
1 change: 1 addition & 0 deletions lib/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ struct exec_context {
/* check_interrupt() */
const atomic_uint *intrp;
struct cluster *cluster;
uint32_t check_interval;

/* scheduler */
struct sched *sched;
Expand Down
52 changes: 47 additions & 5 deletions lib/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -886,8 +886,6 @@ restart_insn(struct exec_context *ctx)
#endif
}

#define CHECK_INTERVAL 1000

int
check_interrupt(struct exec_context *ctx)
{
Expand Down Expand Up @@ -938,6 +936,34 @@ check_interrupt(struct exec_context *ctx)
return 0;
}

#define CHECK_INTERVAL_MAX UINT32_MAX
#define CHECK_INTERVAL_DEFAULT 1000
#define CHECK_INTERVAL_MIN 1

static void
adjust_check_interval(struct exec_context *ctx, const struct timespec *now,
const struct timespec *last)
{
struct timespec diff;
timespec_sub(now, last, &diff);
uint64_t diff_ms = timespec_to_ms(&diff);
uint32_t check_interval = ctx->check_interval;
if (diff_ms < CHECK_INTERRUPT_INTERVAL_MS / 2) {
if (check_interval <= CHECK_INTERVAL_MAX / 2) {
check_interval *= 2;
} else {
check_interval = CHECK_INTERVAL_MAX;
}
} else if (diff_ms / 2 > CHECK_INTERRUPT_INTERVAL_MS) {
check_interval /= 2;
if (check_interval < CHECK_INTERVAL_MIN) {
check_interval = CHECK_INTERVAL_MIN;
}
}
xlog_trace("check_interval %" PRIu32, check_interval);
ctx->check_interval = check_interval;
}

int
exec_expr(uint32_t funcidx, const struct expr *expr,
const struct localtype *localtype,
Expand Down Expand Up @@ -965,7 +991,10 @@ exec_expr(uint32_t funcidx, const struct expr *expr,
int
exec_expr_continue(struct exec_context *ctx)
{
uint32_t n = 0;
struct timespec last;
bool has_last = false;
uint32_t n = ctx->check_interval;
assert(n > 0);
while (true) {
int ret;
switch (ctx->event) {
Expand Down Expand Up @@ -1029,8 +1058,8 @@ exec_expr_continue(struct exec_context *ctx)
if (ctx->frames.lsize == 0) {
break;
}
n++;
if (__predict_false(n > CHECK_INTERVAL)) {
n--;
if (__predict_false(n == 0)) {
n = 0;
ret = check_interrupt(ctx);
if (ret != 0) {
Expand All @@ -1039,6 +1068,18 @@ exec_expr_continue(struct exec_context *ctx)
}
return ret;
}
struct timespec now;
ret = timespec_now(CLOCK_MONOTONIC, &now);
if (ret != 0) {
return ret;
}
if (has_last) {
adjust_check_interval(ctx, &now, &last);
}
last = now;
has_last = true;
n = ctx->check_interval;
assert(n > 0);
}
struct cell *stack = &VEC_NEXTELEM(ctx->stack);
ret = fetch_exec_next_insn(ctx->p, stack, ctx);
Expand Down Expand Up @@ -1261,6 +1302,7 @@ exec_context_init(struct exec_context *ctx, struct instance *inst)
report_init(&ctx->report0);
ctx->report = &ctx->report0;
ctx->restart_type = RESTART_NONE;
ctx->check_interval = CHECK_INTERVAL_DEFAULT;
exec_options_set_defaults(&ctx->options);
}

Expand Down
14 changes: 14 additions & 0 deletions lib/timeutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,17 @@ convert_timespec(clockid_t from_id, clockid_t to_id,
fail:
return ret;
}

uint64_t
timespec_to_ms(const struct timespec *tv)
{
if (UINT64_MAX / 1000 < tv->tv_sec) {
return UINT64_MAX;
}
uint64_t ms1 = tv->tv_sec * 1000;
uint64_t ms2 = tv->tv_nsec / 1000000;
if (UINT64_MAX - ms1 < ms2) {
return UINT64_MAX;
}
return ms1 + ms2;
}
2 changes: 2 additions & 0 deletions lib/timeutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ int abstime_to_reltime_ms_roundup(clockid_t id, const struct timespec *abstime,
int *reltime_ms);
int convert_timespec(clockid_t from_id, clockid_t to_id,
const struct timespec *from_ts, struct timespec *result);

uint64_t timespec_to_ms(const struct timespec *tv);

0 comments on commit 38c4fd0

Please sign in to comment.