Add mallctl for prof stats fetching

This commit is contained in:
Yinan Zhang 2020-08-21 14:37:34 -07:00
parent 40fa4d29d3
commit 54f3351f1f
2 changed files with 215 additions and 24 deletions

170
src/ctl.c
View File

@ -12,6 +12,7 @@
#include "jemalloc/internal/prof_data.h" #include "jemalloc/internal/prof_data.h"
#include "jemalloc/internal/prof_log.h" #include "jemalloc/internal/prof_log.h"
#include "jemalloc/internal/prof_recent.h" #include "jemalloc/internal/prof_recent.h"
#include "jemalloc/internal/prof_stats.h"
#include "jemalloc/internal/prof_sys.h" #include "jemalloc/internal/prof_sys.h"
#include "jemalloc/internal/sc.h" #include "jemalloc/internal/sc.h"
#include "jemalloc/internal/util.h" #include "jemalloc/internal/util.h"
@ -183,6 +184,12 @@ CTL_PROTO(prof_interval)
CTL_PROTO(lg_prof_sample) CTL_PROTO(lg_prof_sample)
CTL_PROTO(prof_log_start) CTL_PROTO(prof_log_start)
CTL_PROTO(prof_log_stop) CTL_PROTO(prof_log_stop)
CTL_PROTO(prof_stats_bins_i_live)
CTL_PROTO(prof_stats_bins_i_accum)
INDEX_PROTO(prof_stats_bins_i)
CTL_PROTO(prof_stats_lextents_i_live)
CTL_PROTO(prof_stats_lextents_i_accum)
INDEX_PROTO(prof_stats_lextents_i)
CTL_PROTO(stats_arenas_i_small_allocated) CTL_PROTO(stats_arenas_i_small_allocated)
CTL_PROTO(stats_arenas_i_small_nmalloc) CTL_PROTO(stats_arenas_i_small_nmalloc)
CTL_PROTO(stats_arenas_i_small_ndalloc) CTL_PROTO(stats_arenas_i_small_ndalloc)
@ -494,6 +501,37 @@ static const ctl_named_node_t arenas_node[] = {
{NAME("lookup"), CTL(arenas_lookup)} {NAME("lookup"), CTL(arenas_lookup)}
}; };
static const ctl_named_node_t prof_stats_bins_i_node[] = {
{NAME("live"), CTL(prof_stats_bins_i_live)},
{NAME("accum"), CTL(prof_stats_bins_i_accum)}
};
static const ctl_named_node_t super_prof_stats_bins_i_node[] = {
{NAME(""), CHILD(named, prof_stats_bins_i)}
};
static const ctl_indexed_node_t prof_stats_bins_node[] = {
{INDEX(prof_stats_bins_i)}
};
static const ctl_named_node_t prof_stats_lextents_i_node[] = {
{NAME("live"), CTL(prof_stats_lextents_i_live)},
{NAME("accum"), CTL(prof_stats_lextents_i_accum)}
};
static const ctl_named_node_t super_prof_stats_lextents_i_node[] = {
{NAME(""), CHILD(named, prof_stats_lextents_i)}
};
static const ctl_indexed_node_t prof_stats_lextents_node[] = {
{INDEX(prof_stats_lextents_i)}
};
static const ctl_named_node_t prof_stats_node[] = {
{NAME("bins"), CHILD(indexed, prof_stats_bins)},
{NAME("lextents"), CHILD(indexed, prof_stats_lextents)},
};
static const ctl_named_node_t prof_node[] = { static const ctl_named_node_t prof_node[] = {
{NAME("thread_active_init"), CTL(prof_thread_active_init)}, {NAME("thread_active_init"), CTL(prof_thread_active_init)},
{NAME("active"), CTL(prof_active)}, {NAME("active"), CTL(prof_active)},
@ -504,8 +542,10 @@ static const ctl_named_node_t prof_node[] = {
{NAME("interval"), CTL(prof_interval)}, {NAME("interval"), CTL(prof_interval)},
{NAME("lg_sample"), CTL(lg_prof_sample)}, {NAME("lg_sample"), CTL(lg_prof_sample)},
{NAME("log_start"), CTL(prof_log_start)}, {NAME("log_start"), CTL(prof_log_start)},
{NAME("log_stop"), CTL(prof_log_stop)} {NAME("log_stop"), CTL(prof_log_stop)},
{NAME("stats"), CHILD(named, prof_stats)}
}; };
static const ctl_named_node_t stats_arenas_i_small_node[] = { static const ctl_named_node_t stats_arenas_i_small_node[] = {
{NAME("allocated"), CTL(stats_arenas_i_small_allocated)}, {NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
{NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)}, {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
@ -3975,3 +4015,131 @@ experimental_batch_alloc_ctl(tsd_t *tsd, const size_t *mib,
label_return: label_return:
return ret; return ret;
} }
static int
prof_stats_bins_i_live_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
int ret;
unsigned binind;
prof_stats_t stats;
if (!(config_prof && opt_prof && opt_prof_stats)) {
ret = ENOENT;
goto label_return;
}
READONLY();
MIB_UNSIGNED(binind, 3);
if (binind >= SC_NBINS) {
ret = EINVAL;
goto label_return;
}
prof_stats_get_live(tsd, (szind_t)binind, &stats);
READ(stats, prof_stats_t);
ret = 0;
label_return:
return ret;
}
static int
prof_stats_bins_i_accum_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
int ret;
unsigned binind;
prof_stats_t stats;
if (!(config_prof && opt_prof && opt_prof_stats)) {
ret = ENOENT;
goto label_return;
}
READONLY();
MIB_UNSIGNED(binind, 3);
if (binind >= SC_NBINS) {
ret = EINVAL;
goto label_return;
}
prof_stats_get_accum(tsd, (szind_t)binind, &stats);
READ(stats, prof_stats_t);
ret = 0;
label_return:
return ret;
}
static const ctl_named_node_t *
prof_stats_bins_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
size_t i) {
if (!(config_prof && opt_prof && opt_prof_stats)) {
return NULL;
}
if (i >= SC_NBINS) {
return NULL;
}
return super_prof_stats_bins_i_node;
}
static int
prof_stats_lextents_i_live_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
int ret;
unsigned lextent_ind;
prof_stats_t stats;
if (!(config_prof && opt_prof && opt_prof_stats)) {
ret = ENOENT;
goto label_return;
}
READONLY();
MIB_UNSIGNED(lextent_ind, 3);
if (lextent_ind >= SC_NSIZES - SC_NBINS) {
ret = EINVAL;
goto label_return;
}
prof_stats_get_live(tsd, (szind_t)(lextent_ind + SC_NBINS), &stats);
READ(stats, prof_stats_t);
ret = 0;
label_return:
return ret;
}
static int
prof_stats_lextents_i_accum_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
int ret;
unsigned lextent_ind;
prof_stats_t stats;
if (!(config_prof && opt_prof && opt_prof_stats)) {
ret = ENOENT;
goto label_return;
}
READONLY();
MIB_UNSIGNED(lextent_ind, 3);
if (lextent_ind >= SC_NSIZES - SC_NBINS) {
ret = EINVAL;
goto label_return;
}
prof_stats_get_accum(tsd, (szind_t)(lextent_ind + SC_NBINS), &stats);
READ(stats, prof_stats_t);
ret = 0;
label_return:
return ret;
}
static const ctl_named_node_t *
prof_stats_lextents_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
size_t i) {
if (!(config_prof && opt_prof && opt_prof_stats)) {
return NULL;
}
if (i >= SC_NSIZES - SC_NBINS) {
return NULL;
}
return super_prof_stats_lextents_i_node;
}

View File

@ -1,18 +1,33 @@
#include "test/jemalloc_test.h" #include "test/jemalloc_test.h"
#include "jemalloc/internal/prof_stats.h"
static void static void
test_wrapper(szind_t ind) { test_wrapper(szind_t ind) {
#define N_PTRS 3 #define N_PTRS 3
#define MALLCTL_STR_LEN 64
assert(opt_prof && opt_prof_stats); assert(opt_prof && opt_prof_stats);
tsd_t *tsd = tsd_fetch(); char mallctl_live_str[MALLCTL_STR_LEN];
char mallctl_accum_str[MALLCTL_STR_LEN];
if (ind < SC_NBINS) {
malloc_snprintf(mallctl_live_str, MALLCTL_STR_LEN,
"prof.stats.bins.%u.live", (unsigned)ind);
malloc_snprintf(mallctl_accum_str, MALLCTL_STR_LEN,
"prof.stats.bins.%u.accum", (unsigned)ind);
} else {
malloc_snprintf(mallctl_live_str, MALLCTL_STR_LEN,
"prof.stats.lextents.%u.live", (unsigned)(ind - SC_NBINS));
malloc_snprintf(mallctl_accum_str, MALLCTL_STR_LEN,
"prof.stats.lextents.%u.accum", (unsigned)(ind - SC_NBINS));
}
prof_stats_t live_stats_orig; size_t stats_len = 2 * sizeof(uint64_t);
prof_stats_get_live(tsd, ind, &live_stats_orig);
prof_stats_t accum_stats_orig; uint64_t live_stats_orig[2];
prof_stats_get_accum(tsd, ind, &accum_stats_orig); assert_d_eq(mallctl(mallctl_live_str, &live_stats_orig, &stats_len,
NULL, 0), 0, "");
uint64_t accum_stats_orig[2];
assert_d_eq(mallctl(mallctl_accum_str, &accum_stats_orig, &stats_len,
NULL, 0), 0, "");
void *ptrs[N_PTRS]; void *ptrs[N_PTRS];
@ -30,17 +45,19 @@ test_wrapper(szind_t ind) {
live_count++; live_count++;
accum_req_sum += sz; accum_req_sum += sz;
accum_count++; accum_count++;
prof_stats_t live_stats; uint64_t live_stats[2];
prof_stats_get_live(tsd, ind, &live_stats); assert_d_eq(mallctl(mallctl_live_str, &live_stats, &stats_len,
expect_u64_eq(live_stats.req_sum - live_stats_orig.req_sum, NULL, 0), 0, "");
expect_u64_eq(live_stats[0] - live_stats_orig[0],
live_req_sum, ""); live_req_sum, "");
expect_u64_eq(live_stats.count - live_stats_orig.count, expect_u64_eq(live_stats[1] - live_stats_orig[1],
live_count, ""); live_count, "");
prof_stats_t accum_stats; uint64_t accum_stats[2];
prof_stats_get_accum(tsd, ind, &accum_stats); assert_d_eq(mallctl(mallctl_accum_str, &accum_stats, &stats_len,
expect_u64_eq(accum_stats.req_sum - accum_stats_orig.req_sum, NULL, 0), 0, "");
expect_u64_eq(accum_stats[0] - accum_stats_orig[0],
accum_req_sum, ""); accum_req_sum, "");
expect_u64_eq(accum_stats.count - accum_stats_orig.count, expect_u64_eq(accum_stats[1] - accum_stats_orig[1],
accum_count, ""); accum_count, "");
} }
@ -49,19 +66,22 @@ test_wrapper(szind_t ind) {
free(ptrs[i]); free(ptrs[i]);
live_req_sum -= sz; live_req_sum -= sz;
live_count--; live_count--;
prof_stats_t live_stats; uint64_t live_stats[2];
prof_stats_get_live(tsd, ind, &live_stats); assert_d_eq(mallctl(mallctl_live_str, &live_stats, &stats_len,
expect_u64_eq(live_stats.req_sum - live_stats_orig.req_sum, NULL, 0), 0, "");
expect_u64_eq(live_stats[0] - live_stats_orig[0],
live_req_sum, ""); live_req_sum, "");
expect_u64_eq(live_stats.count - live_stats_orig.count, expect_u64_eq(live_stats[1] - live_stats_orig[1],
live_count, ""); live_count, "");
prof_stats_t accum_stats; uint64_t accum_stats[2];
prof_stats_get_accum(tsd, ind, &accum_stats); assert_d_eq(mallctl(mallctl_accum_str, &accum_stats, &stats_len,
expect_u64_eq(accum_stats.req_sum - accum_stats_orig.req_sum, NULL, 0), 0, "");
expect_u64_eq(accum_stats[0] - accum_stats_orig[0],
accum_req_sum, ""); accum_req_sum, "");
expect_u64_eq(accum_stats.count - accum_stats_orig.count, expect_u64_eq(accum_stats[1] - accum_stats_orig[1],
accum_count, ""); accum_count, "");
} }
#undef MALLCTL_STR_LEN
#undef N_PTRS #undef N_PTRS
} }
@ -70,6 +90,9 @@ TEST_BEGIN(test_prof_stats) {
test_wrapper(0); test_wrapper(0);
test_wrapper(1); test_wrapper(1);
test_wrapper(2); test_wrapper(2);
test_wrapper(SC_NBINS);
test_wrapper(SC_NBINS + 1);
test_wrapper(SC_NBINS + 2);
} }
TEST_END TEST_END