| 550 | } |
| 551 | |
| 552 | static prof_gctx_t * |
| 553 | prof_gctx_create(tsdn_t *tsdn, prof_bt_t *bt) { |
| 554 | /* |
| 555 | * Create a single allocation that has space for vec of length bt->len. |
| 556 | */ |
| 557 | size_t size = offsetof(prof_gctx_t, vec) + (bt->len * sizeof(void *)); |
| 558 | prof_gctx_t *gctx = (prof_gctx_t *)iallocztm(tsdn, size, |
| 559 | sz_size2index(size), false, NULL, true, arena_get(TSDN_NULL, 0, true), |
| 560 | true); |
| 561 | if (gctx == NULL) { |
| 562 | return NULL; |
| 563 | } |
| 564 | gctx->lock = prof_gctx_mutex_choose(); |
| 565 | /* |
| 566 | * Set nlimbo to 1, in order to avoid a race condition with |
| 567 | * prof_tctx_destroy()/prof_gctx_try_destroy(). |
| 568 | */ |
| 569 | gctx->nlimbo = 1; |
| 570 | tctx_tree_new(&gctx->tctxs); |
| 571 | /* Duplicate bt. */ |
| 572 | memcpy(gctx->vec, bt->vec, bt->len * sizeof(void *)); |
| 573 | gctx->bt.vec = gctx->vec; |
| 574 | gctx->bt.len = bt->len; |
| 575 | return gctx; |
| 576 | } |
| 577 | |
| 578 | static void |
| 579 | prof_gctx_try_destroy(tsd_t *tsd, prof_tdata_t *tdata_self, prof_gctx_t *gctx, |
no test coverage detected