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