trace2: remove use of ALLOC_GROW()
The ALLOC_GROW() helper can call die() on a failed memory allocation. We need to remove this from the trace2 API code to prevent a recursive die() handler. This helper is used to track the nested region stack. Use a new skipped_regions member to track how many times a region was entered without being added to the stack, and decrease that amount as we leave each region. This allows us to avoid a failure and instead stop deepening the stack, giving as much nesting behavior as possible without failing the entire process. Helped-by: Elijah Newren <newren@gmail.com> Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>seen
parent
8c7b68a8bf
commit
4adf78e107
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue