xref: /netbsd-src/external/bsd/jemalloc/dist/src/inspect.c (revision 32d1c65c71fbdb65a012e8392a62a757dd6853e9)
1 #include "jemalloc/internal/jemalloc_preamble.h"
2 #include "jemalloc/internal/jemalloc_internal_includes.h"
3 #include "jemalloc/internal/inspect.h"
4 
5 void
6 inspect_extent_util_stats_get(tsdn_t *tsdn, const void *ptr, size_t *nfree,
7     size_t *nregs, size_t *size) {
8 	assert(ptr != NULL && nfree != NULL && nregs != NULL && size != NULL);
9 
10 	const edata_t *edata = emap_edata_lookup(tsdn, &arena_emap_global, ptr);
11 	if (unlikely(edata == NULL)) {
12 		*nfree = *nregs = *size = 0;
13 		return;
14 	}
15 
16 	*size = edata_size_get(edata);
17 	if (!edata_slab_get(edata)) {
18 		*nfree = 0;
19 		*nregs = 1;
20 	} else {
21 		*nfree = edata_nfree_get(edata);
22 		*nregs = bin_infos[edata_szind_get(edata)].nregs;
23 		assert(*nfree <= *nregs);
24 		assert(*nfree * edata_usize_get(edata) <= *size);
25 	}
26 }
27 
28 void
29 inspect_extent_util_stats_verbose_get(tsdn_t *tsdn, const void *ptr,
30     size_t *nfree, size_t *nregs, size_t *size, size_t *bin_nfree,
31     size_t *bin_nregs, void **slabcur_addr) {
32 	assert(ptr != NULL && nfree != NULL && nregs != NULL && size != NULL
33 	    && bin_nfree != NULL && bin_nregs != NULL && slabcur_addr != NULL);
34 
35 	const edata_t *edata = emap_edata_lookup(tsdn, &arena_emap_global, ptr);
36 	if (unlikely(edata == NULL)) {
37 		*nfree = *nregs = *size = *bin_nfree = *bin_nregs = 0;
38 		*slabcur_addr = NULL;
39 		return;
40 	}
41 
42 	*size = edata_size_get(edata);
43 	if (!edata_slab_get(edata)) {
44 		*nfree = *bin_nfree = *bin_nregs = 0;
45 		*nregs = 1;
46 		*slabcur_addr = NULL;
47 		return;
48 	}
49 
50 	*nfree = edata_nfree_get(edata);
51 	const szind_t szind = edata_szind_get(edata);
52 	*nregs = bin_infos[szind].nregs;
53 	assert(*nfree <= *nregs);
54 	assert(*nfree * edata_usize_get(edata) <= *size);
55 
56 	arena_t *arena = (arena_t *)atomic_load_p(
57 	    &arenas[edata_arena_ind_get(edata)], ATOMIC_RELAXED);
58 	assert(arena != NULL);
59 	const unsigned binshard = edata_binshard_get(edata);
60 	bin_t *bin = arena_get_bin(arena, szind, binshard);
61 
62 	malloc_mutex_lock(tsdn, &bin->lock);
63 	if (config_stats) {
64 		*bin_nregs = *nregs * bin->stats.curslabs;
65 		assert(*bin_nregs >= bin->stats.curregs);
66 		*bin_nfree = *bin_nregs - bin->stats.curregs;
67 	} else {
68 		*bin_nfree = *bin_nregs = 0;
69 	}
70 	edata_t *slab;
71 	if (bin->slabcur != NULL) {
72 		slab = bin->slabcur;
73 	} else {
74 		slab = edata_heap_first(&bin->slabs_nonfull);
75 	}
76 	*slabcur_addr = slab != NULL ? edata_addr_get(slab) : NULL;
77 	malloc_mutex_unlock(tsdn, &bin->lock);
78 }
79