diff --git a/doc/jemalloc.xml.in b/doc/jemalloc.xml.in
index 36aae37c..f213a2c8 100644
--- a/doc/jemalloc.xml.in
+++ b/doc/jemalloc.xml.in
@@ -1253,7 +1253,7 @@ malloc_conf = "xmalloc:true";]]>
Get or set the arena associated with the calling
thread. If the specified arena was not initialized beforehand (see the
arenas.initialized
+ linkend="arena.i.initialized">arena.i.initialized
mallctl), it will be automatically initialized as a side effect of
calling this interface.
@@ -1425,6 +1425,19 @@ malloc_conf = "xmalloc:true";]]>
+
+
+ arena.<i>.initialized
+ (bool)
+ r-
+
+ Get whether the specified arena's statistics are
+ initialized (i.e. the arena was initialized prior to the current epoch).
+ This interface can also be nominally used to query whether the merged
+ statistics corresponding to MALLCTL_ARENAS_ALL are
+ initialized (always true).
+
+
arena.<i>.purge
@@ -1715,18 +1728,6 @@ struct extent_hooks_s {
Current limit on number of arenas.
-
-
- arenas.initialized
- (bool *)
- r-
-
- An array of arenas.narenas
- booleans. Each boolean indicates whether the corresponding arena is
- initialized.
-
-
arenas.decay_time
diff --git a/src/ctl.c b/src/ctl.c
index 0e7a09da..45e397b8 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -109,7 +109,7 @@ CTL_PROTO(opt_prof_accum)
CTL_PROTO(tcache_create)
CTL_PROTO(tcache_flush)
CTL_PROTO(tcache_destroy)
-static void arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all);
+CTL_PROTO(arena_i_initialized)
CTL_PROTO(arena_i_purge)
CTL_PROTO(arena_i_decay)
CTL_PROTO(arena_i_reset)
@@ -124,7 +124,6 @@ INDEX_PROTO(arenas_bin_i)
CTL_PROTO(arenas_lextent_i_size)
INDEX_PROTO(arenas_lextent_i)
CTL_PROTO(arenas_narenas)
-CTL_PROTO(arenas_initialized)
CTL_PROTO(arenas_decay_time)
CTL_PROTO(arenas_quantum)
CTL_PROTO(arenas_page)
@@ -271,6 +270,7 @@ static const ctl_named_node_t tcache_node[] = {
};
static const ctl_named_node_t arena_i_node[] = {
+ {NAME("initialized"), CTL(arena_i_initialized)},
{NAME("purge"), CTL(arena_i_purge)},
{NAME("decay"), CTL(arena_i_decay)},
{NAME("reset"), CTL(arena_i_reset)},
@@ -312,7 +312,6 @@ static const ctl_indexed_node_t arenas_lextent_node[] = {
static const ctl_named_node_t arenas_node[] = {
{NAME("narenas"), CTL(arenas_narenas)},
- {NAME("initialized"), CTL(arenas_initialized)},
{NAME("decay_time"), CTL(arenas_decay_time)},
{NAME("quantum"), CTL(arenas_quantum)},
{NAME("page"), CTL(arenas_page)},
@@ -1461,6 +1460,29 @@ label_return:
/******************************************************************************/
+static int
+arena_i_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
+ void *oldp, size_t *oldlenp, void *newp, size_t newlen)
+{
+ int ret;
+ tsdn_t *tsdn = tsd_tsdn(tsd);
+ unsigned arena_ind;
+ bool initialized;
+
+ READONLY();
+ MIB_UNSIGNED(arena_ind, 1);
+
+ malloc_mutex_lock(tsdn, &ctl_mtx);
+ initialized = stats_arenas_i(arena_ind)->initialized;
+ malloc_mutex_unlock(tsdn, &ctl_mtx);
+
+ READ(initialized, bool);
+
+ ret = 0;
+label_return:
+ return (ret);
+}
+
static void
arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all)
{
@@ -1746,32 +1768,6 @@ label_return:
return (ret);
}
-static int
-arenas_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
- size_t *oldlenp, void *newp, size_t newlen)
-{
- int ret;
- unsigned nread, i;
-
- malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
- READONLY();
- if (*oldlenp != ctl_stats->narenas * sizeof(bool)) {
- ret = EINVAL;
- nread = (*oldlenp < ctl_stats->narenas * sizeof(bool))
- ? (unsigned)(*oldlenp / sizeof(bool)) : ctl_stats->narenas;
- } else {
- ret = 0;
- nread = ctl_stats->narenas;
- }
-
- for (i = 0; i < nread; i++)
- ((bool *)oldp)[i] = stats_arenas_i(i)->initialized;
-
-label_return:
- malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
- return (ret);
-}
-
static int
arenas_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
size_t *oldlenp, void *newp, size_t newlen)
diff --git a/src/stats.c b/src/stats.c
index ad7d7ba4..4e09eb45 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -818,14 +818,18 @@ stats_print_helper(void (*write_cb)(void *, const char *), void *cbopaque,
CTL_GET("arenas.narenas", &narenas, unsigned);
{
+ size_t mib[3];
+ size_t miblen = sizeof(mib) / sizeof(size_t);
+ size_t sz;
VARIABLE_ARRAY(bool, initialized, narenas);
- size_t isz;
unsigned i, j, ninitialized;
- isz = sizeof(bool) * narenas;
- xmallctl("arenas.initialized", (void *)initialized,
- &isz, NULL, 0);
+ xmallctlnametomib("arena.0.initialized", mib, &miblen);
for (i = ninitialized = 0; i < narenas; i++) {
+ mib[1] = i;
+ sz = sizeof(bool);
+ xmallctlbymib(mib, miblen, &initialized[i], &sz,
+ NULL, 0);
if (initialized[i])
ninitialized++;
}
diff --git a/test/unit/mallctl.c b/test/unit/mallctl.c
index 95c27753..b3320788 100644
--- a/test/unit/mallctl.c
+++ b/test/unit/mallctl.c
@@ -354,6 +354,36 @@ TEST_BEGIN(test_thread_arena)
}
TEST_END
+TEST_BEGIN(test_arena_i_initialized)
+{
+ unsigned narenas, i;
+ size_t sz;
+ size_t mib[3];
+ size_t miblen = sizeof(mib) / sizeof(size_t);
+ bool initialized;
+
+ sz = sizeof(narenas);
+ assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0),
+ 0, "Unexpected mallctl() failure");
+
+ assert_d_eq(mallctlnametomib("arena.0.initialized", mib, &miblen), 0,
+ "Unexpected mallctlnametomib() failure");
+ for (i = 0; i < narenas; i++) {
+ mib[1] = i;
+ sz = sizeof(initialized);
+ assert_d_eq(mallctlbymib(mib, miblen, &initialized, &sz, NULL,
+ 0), 0, "Unexpected mallctl() failure");
+ }
+
+ mib[1] = MALLCTL_ARENAS_ALL;
+ sz = sizeof(initialized);
+ assert_d_eq(mallctlbymib(mib, miblen, &initialized, &sz, NULL, 0), 0,
+ "Unexpected mallctl() failure");
+ assert_true(initialized,
+ "Merged arena statistics should always be initialized");
+}
+TEST_END
+
TEST_BEGIN(test_arena_i_decay_time)
{
ssize_t decay_time, orig_decay_time, prev_decay_time;
@@ -479,23 +509,6 @@ TEST_BEGIN(test_arena_i_dss)
}
TEST_END
-TEST_BEGIN(test_arenas_initialized)
-{
- unsigned narenas;
- size_t sz = sizeof(narenas);
-
- assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0),
- 0, "Unexpected mallctl() failure");
- {
- VARIABLE_ARRAY(bool, initialized, narenas);
-
- sz = narenas * sizeof(bool);
- assert_d_eq(mallctl("arenas.initialized", (void *)initialized,
- &sz, NULL, 0), 0, "Unexpected mallctl() failure");
- }
-}
-TEST_END
-
TEST_BEGIN(test_arenas_decay_time)
{
ssize_t decay_time, orig_decay_time, prev_decay_time;
@@ -638,11 +651,11 @@ main(void)
test_tcache_none,
test_tcache,
test_thread_arena,
+ test_arena_i_initialized,
test_arena_i_decay_time,
test_arena_i_purge,
test_arena_i_decay,
test_arena_i_dss,
- test_arenas_initialized,
test_arenas_decay_time,
test_arenas_constants,
test_arenas_bin_constants,