diff --git a/banned-die.h b/banned-die.h index 4d1800353d..cff1072397 100644 --- a/banned-die.h +++ b/banned-die.h @@ -23,4 +23,7 @@ #undef ALLOC_ARRAY #define ALLOC_ARRAY(x, alloc) BANNED(ALLOC_ARRAY) +#undef ALLOC_GROW +#define ALLOC_GROW(x, nr, alloc) BANNED(ALLOC_GROW) + #endif /* BANNED_DIE_H */ diff --git a/trace2/tr2_tls.c b/trace2/tr2_tls.c index 49bd505d62..5e4624d0b3 100644 --- a/trace2/tr2_tls.c +++ b/trace2/tr2_tls.c @@ -109,8 +109,33 @@ void tr2tls_unset_self(void) void tr2tls_push_self(uint64_t us_now) { struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + uint64_t *new_array; + size_t new_alloc; + + if (ctx->nr_skipped_regions) { + ctx->nr_skipped_regions++; + return; + } + + if (ctx->nr_open_regions >= ctx->alloc) { + if (ctx->alloc > + SIZE_MAX / (2 * sizeof(*ctx->array_us_start))) { + ctx->nr_skipped_regions++; + return; + } + new_alloc = ctx->alloc * 2; + + new_array = realloc(ctx->array_us_start, + new_alloc * sizeof(*ctx->array_us_start)); + if (!new_array) { + ctx->nr_skipped_regions++; + return; + } + + ctx->array_us_start = new_array; + ctx->alloc = new_alloc; + } - ALLOC_GROW(ctx->array_us_start, ctx->nr_open_regions + 1, ctx->alloc); ctx->array_us_start[ctx->nr_open_regions++] = us_now; } @@ -118,6 +143,11 @@ void tr2tls_pop_self(void) { struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + if (ctx->nr_skipped_regions) { + ctx->nr_skipped_regions--; + return; + } + if (!ctx->nr_open_regions) BUG("no open regions in thread '%s'", ctx->thread_name); @@ -138,6 +168,8 @@ uint64_t tr2tls_region_elasped_self(uint64_t us) uint64_t us_start; ctx = tr2tls_get_self(); + if (ctx->nr_skipped_regions) + return 0; if (!ctx->nr_open_regions) return 0; diff --git a/trace2/tr2_tls.h b/trace2/tr2_tls.h index 3bdbf4d275..c365017923 100644 --- a/trace2/tr2_tls.h +++ b/trace2/tr2_tls.h @@ -20,6 +20,7 @@ struct tr2tls_thread_ctx { uint64_t *array_us_start; size_t alloc; size_t nr_open_regions; /* plays role of "nr" in ALLOC_GROW */ + size_t nr_skipped_regions; int thread_id; struct tr2_timer_block timer_block; struct tr2_counter_block counter_block;