| 630 | } |
| 631 | |
| 632 | static void |
| 633 | stats_print_atexit(void) { |
| 634 | if (config_stats) { |
| 635 | tsdn_t *tsdn; |
| 636 | unsigned narenas, i; |
| 637 | |
| 638 | tsdn = tsdn_fetch(); |
| 639 | |
| 640 | /* |
| 641 | * Merge stats from extant threads. This is racy, since |
| 642 | * individual threads do not lock when recording tcache stats |
| 643 | * events. As a consequence, the final stats may be slightly |
| 644 | * out of date by the time they are reported, if other threads |
| 645 | * continue to allocate. |
| 646 | */ |
| 647 | for (i = 0, narenas = narenas_total_get(); i < narenas; i++) { |
| 648 | arena_t *arena = arena_get(tsdn, i, false); |
| 649 | if (arena != NULL) { |
| 650 | tcache_t *tcache; |
| 651 | |
| 652 | malloc_mutex_lock(tsdn, &arena->tcache_ql_mtx); |
| 653 | ql_foreach(tcache, &arena->tcache_ql, link) { |
| 654 | tcache_stats_merge(tsdn, tcache, arena); |
| 655 | } |
| 656 | malloc_mutex_unlock(tsdn, |
| 657 | &arena->tcache_ql_mtx); |
| 658 | } |
| 659 | } |
| 660 | } |
| 661 | je_malloc_stats_print(NULL, NULL, opt_stats_print_opts); |
| 662 | } |
| 663 | |
| 664 | /* |
| 665 | * Ensure that we don't hold any locks upon entry to or exit from allocator |
nothing calls this directly
no test coverage detected