| 1540 | } |
| 1541 | |
| 1542 | static void |
| 1543 | prof_dump_prep(tsd_t *tsd, prof_tdata_t *tdata, |
| 1544 | struct prof_tdata_merge_iter_arg_s *prof_tdata_merge_iter_arg, |
| 1545 | struct prof_gctx_merge_iter_arg_s *prof_gctx_merge_iter_arg, |
| 1546 | prof_gctx_tree_t *gctxs) { |
| 1547 | size_t tabind; |
| 1548 | union { |
| 1549 | prof_gctx_t *p; |
| 1550 | void *v; |
| 1551 | } gctx; |
| 1552 | |
| 1553 | prof_enter(tsd, tdata); |
| 1554 | |
| 1555 | /* |
| 1556 | * Put gctx's in limbo and clear their counters in preparation for |
| 1557 | * summing. |
| 1558 | */ |
| 1559 | gctx_tree_new(gctxs); |
| 1560 | for (tabind = 0; !ckh_iter(&bt2gctx, &tabind, NULL, &gctx.v);) { |
| 1561 | prof_dump_gctx_prep(tsd_tsdn(tsd), gctx.p, gctxs); |
| 1562 | } |
| 1563 | |
| 1564 | /* |
| 1565 | * Iterate over tdatas, and for the non-expired ones snapshot their tctx |
| 1566 | * stats and merge them into the associated gctx's. |
| 1567 | */ |
| 1568 | prof_tdata_merge_iter_arg->tsdn = tsd_tsdn(tsd); |
| 1569 | memset(&prof_tdata_merge_iter_arg->cnt_all, 0, sizeof(prof_cnt_t)); |
| 1570 | malloc_mutex_lock(tsd_tsdn(tsd), &tdatas_mtx); |
| 1571 | tdata_tree_iter(&tdatas, NULL, prof_tdata_merge_iter, |
| 1572 | (void *)prof_tdata_merge_iter_arg); |
| 1573 | malloc_mutex_unlock(tsd_tsdn(tsd), &tdatas_mtx); |
| 1574 | |
| 1575 | /* Merge tctx stats into gctx's. */ |
| 1576 | prof_gctx_merge_iter_arg->tsdn = tsd_tsdn(tsd); |
| 1577 | prof_gctx_merge_iter_arg->leak_ngctx = 0; |
| 1578 | gctx_tree_iter(gctxs, NULL, prof_gctx_merge_iter, |
| 1579 | (void *)prof_gctx_merge_iter_arg); |
| 1580 | |
| 1581 | prof_leave(tsd, tdata); |
| 1582 | } |
| 1583 | |
| 1584 | static bool |
| 1585 | prof_dump_file(tsd_t *tsd, bool propagate_err, const char *filename, |
no test coverage detected