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