| 1820 | } |
| 1821 | |
| 1822 | static void |
| 1823 | prof_dump_prep(tsd_t *tsd, prof_tdata_t *tdata, |
| 1824 | struct prof_tdata_merge_iter_arg_s *prof_tdata_merge_iter_arg, |
| 1825 | struct prof_gctx_merge_iter_arg_s *prof_gctx_merge_iter_arg, |
| 1826 | prof_gctx_tree_t *gctxs) { |
| 1827 | size_t tabind; |
| 1828 | union { |
| 1829 | prof_gctx_t *p; |
| 1830 | void *v; |
| 1831 | } gctx; |
| 1832 | |
| 1833 | prof_enter(tsd, tdata); |
| 1834 | |
| 1835 | /* |
| 1836 | * Put gctx's in limbo and clear their counters in preparation for |
| 1837 | * summing. |
| 1838 | */ |
| 1839 | gctx_tree_new(gctxs); |
| 1840 | for (tabind = 0; !ckh_iter(&bt2gctx, &tabind, NULL, &gctx.v);) { |
| 1841 | prof_dump_gctx_prep(tsd_tsdn(tsd), gctx.p, gctxs); |
| 1842 | } |
| 1843 | |
| 1844 | /* |
| 1845 | * Iterate over tdatas, and for the non-expired ones snapshot their tctx |
| 1846 | * stats and merge them into the associated gctx's. |
| 1847 | */ |
| 1848 | prof_tdata_merge_iter_arg->tsdn = tsd_tsdn(tsd); |
| 1849 | memset(&prof_tdata_merge_iter_arg->cnt_all, 0, sizeof(prof_cnt_t)); |
| 1850 | malloc_mutex_lock(tsd_tsdn(tsd), &tdatas_mtx); |
| 1851 | tdata_tree_iter(&tdatas, NULL, prof_tdata_merge_iter, |
| 1852 | (void *)prof_tdata_merge_iter_arg); |
| 1853 | malloc_mutex_unlock(tsd_tsdn(tsd), &tdatas_mtx); |
| 1854 | |
| 1855 | /* Merge tctx stats into gctx's. */ |
| 1856 | prof_gctx_merge_iter_arg->tsdn = tsd_tsdn(tsd); |
| 1857 | prof_gctx_merge_iter_arg->leak_ngctx = 0; |
| 1858 | gctx_tree_iter(gctxs, NULL, prof_gctx_merge_iter, |
| 1859 | (void *)prof_gctx_merge_iter_arg); |
| 1860 | |
| 1861 | prof_leave(tsd, tdata); |
| 1862 | } |
| 1863 | |
| 1864 | static bool |
| 1865 | prof_dump_file(tsd_t *tsd, bool propagate_err, const char *filename, |
no test coverage detected