From 403f2d1664acfae920e8e6ce51e2695d826a0628 Mon Sep 17 00:00:00 2001 From: David Goldblatt Date: Wed, 4 Dec 2019 09:44:59 -0800 Subject: [PATCH] Extents: Split out introspection functionality. This isn't really part of the core extent allocation facilities. Especially as this module grows, having it in its own place may come in handy. --- Makefile.in | 3 +- include/jemalloc/internal/extent2.h | 28 ------- include/jemalloc/internal/inspect.h | 40 ++++++++++ .../projects/vc2015/jemalloc/jemalloc.vcxproj | 1 + .../projects/vc2017/jemalloc/jemalloc.vcxproj | 1 + src/ctl.c | 20 ++--- src/extent2.c | 75 ------------------ src/inspect.c | 77 +++++++++++++++++++ test/unit/{extent_util.c => inspect.c} | 0 9 files changed, 132 insertions(+), 113 deletions(-) create mode 100644 include/jemalloc/internal/inspect.h create mode 100644 src/inspect.c rename test/unit/{extent_util.c => inspect.c} (100%) diff --git a/Makefile.in b/Makefile.in index 29977bc0..cab4e1f1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -112,6 +112,7 @@ C_SRCS := $(srcroot)src/jemalloc.c \ $(srcroot)src/extent_mmap.c \ $(srcroot)src/hash.c \ $(srcroot)src/hook.c \ + $(srcroot)src/inspect.c \ $(srcroot)src/large.c \ $(srcroot)src/log.c \ $(srcroot)src/malloc_io.c \ @@ -189,11 +190,11 @@ TESTS_UNIT := \ $(srcroot)test/unit/div.c \ $(srcroot)test/unit/emitter.c \ $(srcroot)test/unit/extent_quantize.c \ - $(srcroot)test/unit/extent_util.c \ $(srcroot)test/unit/fork.c \ $(srcroot)test/unit/hash.c \ $(srcroot)test/unit/hook.c \ $(srcroot)test/unit/huge.c \ + $(srcroot)test/unit/inspect.c \ $(srcroot)test/unit/junk.c \ $(srcroot)test/unit/junk_alloc.c \ $(srcroot)test/unit/junk_free.c \ diff --git a/include/jemalloc/internal/extent2.h b/include/jemalloc/internal/extent2.h index 22035bba..7a18a613 100644 --- a/include/jemalloc/internal/extent2.h +++ b/include/jemalloc/internal/extent2.h @@ -17,28 +17,6 @@ * particular reason. This will also be changed, but much more immediately. */ -/* - * The following two structs are for experimental purposes. See - * experimental_utilization_query_ctl and - * experimental_utilization_batch_query_ctl in src/ctl.c. - */ -typedef struct extent_util_stats_s extent_util_stats_t; -struct extent_util_stats_s { - size_t nfree; - size_t nregs; - size_t size; -}; - -typedef struct extent_util_stats_verbose_s extent_util_stats_verbose_t; -struct extent_util_stats_verbose_s { - void *slabcur_addr; - size_t nfree; - size_t nregs; - size_t size; - size_t bin_nfree; - size_t bin_nregs; -}; - /* * When reuse (and split) an active extent, (1U << opt_lg_extent_max_active_fit) * is the max ratio between the size of the active extent and the new extent. @@ -83,10 +61,4 @@ bool extent_head_no_merge(extent_t *a, extent_t *b); bool extent_boot(void); -void extent_util_stats_get(tsdn_t *tsdn, const void *ptr, - size_t *nfree, size_t *nregs, size_t *size); -void extent_util_stats_verbose_get(tsdn_t *tsdn, const void *ptr, - size_t *nfree, size_t *nregs, size_t *size, - size_t *bin_nfree, size_t *bin_nregs, void **slabcur_addr); - #endif /* JEMALLOC_INTERNAL_EXTENT2_H */ diff --git a/include/jemalloc/internal/inspect.h b/include/jemalloc/internal/inspect.h new file mode 100644 index 00000000..65fef51d --- /dev/null +++ b/include/jemalloc/internal/inspect.h @@ -0,0 +1,40 @@ +#ifndef JEMALLOC_INTERNAL_INSPECT_H +#define JEMALLOC_INTERNAL_INSPECT_H + +/* + * This module contains the heap introspection capabilities. For now they are + * exposed purely through mallctl APIs in the experimental namespace, but this + * may change over time. + */ + +/* + * The following two structs are for experimental purposes. See + * experimental_utilization_query_ctl and + * experimental_utilization_batch_query_ctl in src/ctl.c. + */ +typedef struct inspect_extent_util_stats_s inspect_extent_util_stats_t; +struct inspect_extent_util_stats_s { + size_t nfree; + size_t nregs; + size_t size; +}; + +typedef struct inspect_extent_util_stats_verbose_s + inspect_extent_util_stats_verbose_t; + +struct inspect_extent_util_stats_verbose_s { + void *slabcur_addr; + size_t nfree; + size_t nregs; + size_t size; + size_t bin_nfree; + size_t bin_nregs; +}; + +void inspect_extent_util_stats_get(tsdn_t *tsdn, const void *ptr, + size_t *nfree, size_t *nregs, size_t *size); +void inspect_extent_util_stats_verbose_get(tsdn_t *tsdn, const void *ptr, + size_t *nfree, size_t *nregs, size_t *size, + size_t *bin_nfree, size_t *bin_nregs, void **slabcur_addr); + +#endif /* JEMALLOC_INTERNAL_INSPECT_H */ diff --git a/msvc/projects/vc2015/jemalloc/jemalloc.vcxproj b/msvc/projects/vc2015/jemalloc/jemalloc.vcxproj index 4118b911..f5069d38 100644 --- a/msvc/projects/vc2015/jemalloc/jemalloc.vcxproj +++ b/msvc/projects/vc2015/jemalloc/jemalloc.vcxproj @@ -52,6 +52,7 @@ + diff --git a/msvc/projects/vc2017/jemalloc/jemalloc.vcxproj b/msvc/projects/vc2017/jemalloc/jemalloc.vcxproj index ed3b5248..19e72d4f 100644 --- a/msvc/projects/vc2017/jemalloc/jemalloc.vcxproj +++ b/msvc/projects/vc2017/jemalloc/jemalloc.vcxproj @@ -52,6 +52,7 @@ + diff --git a/src/ctl.c b/src/ctl.c index a9982ca3..4aa4af8f 100644 --- a/src/ctl.c +++ b/src/ctl.c @@ -6,6 +6,7 @@ #include "jemalloc/internal/ctl.h" #include "jemalloc/internal/extent_dss.h" #include "jemalloc/internal/extent_mmap.h" +#include "jemalloc/internal/inspect.h" #include "jemalloc/internal/mutex.h" #include "jemalloc/internal/nstime.h" #include "jemalloc/internal/sc.h" @@ -3258,11 +3259,11 @@ experimental_utilization_query_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { int ret; - assert(sizeof(extent_util_stats_verbose_t) + assert(sizeof(inspect_extent_util_stats_verbose_t) == sizeof(void *) + sizeof(size_t) * 5); if (oldp == NULL || oldlenp == NULL - || *oldlenp != sizeof(extent_util_stats_verbose_t) + || *oldlenp != sizeof(inspect_extent_util_stats_verbose_t) || newp == NULL) { ret = EINVAL; goto label_return; @@ -3270,9 +3271,9 @@ experimental_utilization_query_ctl(tsd_t *tsd, const size_t *mib, void *ptr = NULL; WRITE(ptr, void *); - extent_util_stats_verbose_t *util_stats - = (extent_util_stats_verbose_t *)oldp; - extent_util_stats_verbose_get(tsd_tsdn(tsd), ptr, + inspect_extent_util_stats_verbose_t *util_stats + = (inspect_extent_util_stats_verbose_t *)oldp; + inspect_extent_util_stats_verbose_get(tsd_tsdn(tsd), ptr, &util_stats->nfree, &util_stats->nregs, &util_stats->size, &util_stats->bin_nfree, &util_stats->bin_nregs, &util_stats->slabcur_addr); @@ -3383,21 +3384,22 @@ experimental_utilization_batch_query_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { int ret; - assert(sizeof(extent_util_stats_t) == sizeof(size_t) * 3); + assert(sizeof(inspect_extent_util_stats_t) == sizeof(size_t) * 3); const size_t len = newlen / sizeof(const void *); if (oldp == NULL || oldlenp == NULL || newp == NULL || newlen == 0 || newlen != len * sizeof(const void *) - || *oldlenp != len * sizeof(extent_util_stats_t)) { + || *oldlenp != len * sizeof(inspect_extent_util_stats_t)) { ret = EINVAL; goto label_return; } void **ptrs = (void **)newp; - extent_util_stats_t *util_stats = (extent_util_stats_t *)oldp; + inspect_extent_util_stats_t *util_stats = + (inspect_extent_util_stats_t *)oldp; size_t i; for (i = 0; i < len; ++i) { - extent_util_stats_get(tsd_tsdn(tsd), ptrs[i], + inspect_extent_util_stats_get(tsd_tsdn(tsd), ptrs[i], &util_stats[i].nfree, &util_stats[i].nregs, &util_stats[i].size); } diff --git a/src/extent2.c b/src/extent2.c index 4865beb1..0b097160 100644 --- a/src/extent2.c +++ b/src/extent2.c @@ -1661,78 +1661,3 @@ extent_boot(void) { return false; } - -void -extent_util_stats_get(tsdn_t *tsdn, const void *ptr, - size_t *nfree, size_t *nregs, size_t *size) { - assert(ptr != NULL && nfree != NULL && nregs != NULL && size != NULL); - - const extent_t *extent = iealloc(tsdn, ptr); - if (unlikely(extent == NULL)) { - *nfree = *nregs = *size = 0; - return; - } - - *size = extent_size_get(extent); - if (!extent_slab_get(extent)) { - *nfree = 0; - *nregs = 1; - } else { - *nfree = extent_nfree_get(extent); - *nregs = bin_infos[extent_szind_get(extent)].nregs; - assert(*nfree <= *nregs); - assert(*nfree * extent_usize_get(extent) <= *size); - } -} - -void -extent_util_stats_verbose_get(tsdn_t *tsdn, const void *ptr, - size_t *nfree, size_t *nregs, size_t *size, - size_t *bin_nfree, size_t *bin_nregs, void **slabcur_addr) { - assert(ptr != NULL && nfree != NULL && nregs != NULL && size != NULL - && bin_nfree != NULL && bin_nregs != NULL && slabcur_addr != NULL); - - const extent_t *extent = iealloc(tsdn, ptr); - if (unlikely(extent == NULL)) { - *nfree = *nregs = *size = *bin_nfree = *bin_nregs = 0; - *slabcur_addr = NULL; - return; - } - - *size = extent_size_get(extent); - if (!extent_slab_get(extent)) { - *nfree = *bin_nfree = *bin_nregs = 0; - *nregs = 1; - *slabcur_addr = NULL; - return; - } - - *nfree = extent_nfree_get(extent); - const szind_t szind = extent_szind_get(extent); - *nregs = bin_infos[szind].nregs; - assert(*nfree <= *nregs); - assert(*nfree * extent_usize_get(extent) <= *size); - - const arena_t *arena = (arena_t *)atomic_load_p( - &arenas[extent_arena_ind_get(extent)], ATOMIC_RELAXED); - assert(arena != NULL); - const unsigned binshard = extent_binshard_get(extent); - bin_t *bin = &arena->bins[szind].bin_shards[binshard]; - - malloc_mutex_lock(tsdn, &bin->lock); - if (config_stats) { - *bin_nregs = *nregs * bin->stats.curslabs; - assert(*bin_nregs >= bin->stats.curregs); - *bin_nfree = *bin_nregs - bin->stats.curregs; - } else { - *bin_nfree = *bin_nregs = 0; - } - extent_t *slab; - if (bin->slabcur != NULL) { - slab = bin->slabcur; - } else { - slab = extent_heap_first(&bin->slabs_nonfull); - } - *slabcur_addr = slab != NULL ? extent_addr_get(slab) : NULL; - malloc_mutex_unlock(tsdn, &bin->lock); -} diff --git a/src/inspect.c b/src/inspect.c new file mode 100644 index 00000000..435016e6 --- /dev/null +++ b/src/inspect.c @@ -0,0 +1,77 @@ +#include "jemalloc/internal/jemalloc_preamble.h" +#include "jemalloc/internal/jemalloc_internal_includes.h" + +void +inspect_extent_util_stats_get(tsdn_t *tsdn, const void *ptr, size_t *nfree, + size_t *nregs, size_t *size) { + assert(ptr != NULL && nfree != NULL && nregs != NULL && size != NULL); + + const extent_t *extent = iealloc(tsdn, ptr); + if (unlikely(extent == NULL)) { + *nfree = *nregs = *size = 0; + return; + } + + *size = extent_size_get(extent); + if (!extent_slab_get(extent)) { + *nfree = 0; + *nregs = 1; + } else { + *nfree = extent_nfree_get(extent); + *nregs = bin_infos[extent_szind_get(extent)].nregs; + assert(*nfree <= *nregs); + assert(*nfree * extent_usize_get(extent) <= *size); + } +} + +void +inspect_extent_util_stats_verbose_get(tsdn_t *tsdn, const void *ptr, + size_t *nfree, size_t *nregs, size_t *size, size_t *bin_nfree, + size_t *bin_nregs, void **slabcur_addr) { + assert(ptr != NULL && nfree != NULL && nregs != NULL && size != NULL + && bin_nfree != NULL && bin_nregs != NULL && slabcur_addr != NULL); + + const extent_t *extent = iealloc(tsdn, ptr); + if (unlikely(extent == NULL)) { + *nfree = *nregs = *size = *bin_nfree = *bin_nregs = 0; + *slabcur_addr = NULL; + return; + } + + *size = extent_size_get(extent); + if (!extent_slab_get(extent)) { + *nfree = *bin_nfree = *bin_nregs = 0; + *nregs = 1; + *slabcur_addr = NULL; + return; + } + + *nfree = extent_nfree_get(extent); + const szind_t szind = extent_szind_get(extent); + *nregs = bin_infos[szind].nregs; + assert(*nfree <= *nregs); + assert(*nfree * extent_usize_get(extent) <= *size); + + const arena_t *arena = (arena_t *)atomic_load_p( + &arenas[extent_arena_ind_get(extent)], ATOMIC_RELAXED); + assert(arena != NULL); + const unsigned binshard = extent_binshard_get(extent); + bin_t *bin = &arena->bins[szind].bin_shards[binshard]; + + malloc_mutex_lock(tsdn, &bin->lock); + if (config_stats) { + *bin_nregs = *nregs * bin->stats.curslabs; + assert(*bin_nregs >= bin->stats.curregs); + *bin_nfree = *bin_nregs - bin->stats.curregs; + } else { + *bin_nfree = *bin_nregs = 0; + } + extent_t *slab; + if (bin->slabcur != NULL) { + slab = bin->slabcur; + } else { + slab = extent_heap_first(&bin->slabs_nonfull); + } + *slabcur_addr = slab != NULL ? extent_addr_get(slab) : NULL; + malloc_mutex_unlock(tsdn, &bin->lock); +} diff --git a/test/unit/extent_util.c b/test/unit/inspect.c similarity index 100% rename from test/unit/extent_util.c rename to test/unit/inspect.c