Add thread.peak.[read|reset] mallctls.
These can be used to track net allocator activity on a per-thread basis.
This commit is contained in:
committed by
David Goldblatt
parent
fe7108305a
commit
d82a164d0d
41
src/ctl.c
41
src/ctl.c
@@ -9,6 +9,7 @@
|
||||
#include "jemalloc/internal/inspect.h"
|
||||
#include "jemalloc/internal/mutex.h"
|
||||
#include "jemalloc/internal/nstime.h"
|
||||
#include "jemalloc/internal/peak_event.h"
|
||||
#include "jemalloc/internal/sc.h"
|
||||
#include "jemalloc/internal/util.h"
|
||||
|
||||
@@ -61,6 +62,8 @@ CTL_PROTO(background_thread)
|
||||
CTL_PROTO(max_background_threads)
|
||||
CTL_PROTO(thread_tcache_enabled)
|
||||
CTL_PROTO(thread_tcache_flush)
|
||||
CTL_PROTO(thread_peak_read)
|
||||
CTL_PROTO(thread_peak_reset)
|
||||
CTL_PROTO(thread_prof_name)
|
||||
CTL_PROTO(thread_prof_active)
|
||||
CTL_PROTO(thread_arena)
|
||||
@@ -294,6 +297,11 @@ static const ctl_named_node_t thread_tcache_node[] = {
|
||||
{NAME("flush"), CTL(thread_tcache_flush)}
|
||||
};
|
||||
|
||||
static const ctl_named_node_t thread_peak_node[] = {
|
||||
{NAME("read"), CTL(thread_peak_read)},
|
||||
{NAME("reset"), CTL(thread_peak_reset)},
|
||||
};
|
||||
|
||||
static const ctl_named_node_t thread_prof_node[] = {
|
||||
{NAME("name"), CTL(thread_prof_name)},
|
||||
{NAME("active"), CTL(thread_prof_active)}
|
||||
@@ -306,6 +314,7 @@ static const ctl_named_node_t thread_node[] = {
|
||||
{NAME("deallocated"), CTL(thread_deallocated)},
|
||||
{NAME("deallocatedp"), CTL(thread_deallocatedp)},
|
||||
{NAME("tcache"), CHILD(named, thread_tcache)},
|
||||
{NAME("peak"), CHILD(named, thread_peak)},
|
||||
{NAME("prof"), CHILD(named, thread_prof)},
|
||||
{NAME("idle"), CTL(thread_idle)}
|
||||
};
|
||||
@@ -1953,6 +1962,38 @@ label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
thread_peak_read_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp,
|
||||
size_t newlen) {
|
||||
int ret;
|
||||
if (!config_stats) {
|
||||
return ENOENT;
|
||||
}
|
||||
READONLY();
|
||||
peak_event_update(tsd);
|
||||
uint64_t result = peak_event_max(tsd);
|
||||
READ(result, uint64_t);
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
thread_peak_reset_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp,
|
||||
size_t newlen) {
|
||||
int ret;
|
||||
if (!config_stats) {
|
||||
return ENOENT;
|
||||
}
|
||||
NEITHER_READ_NOR_WRITE();
|
||||
peak_event_zero(tsd);
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
thread_prof_name_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp,
|
||||
|
67
src/peak_event.c
Normal file
67
src/peak_event.c
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
||||
|
||||
#include "jemalloc/internal/peak.h"
|
||||
#include "jemalloc/internal/peak_event.h"
|
||||
|
||||
/*
|
||||
* Update every 100k by default. We're not exposing this as a configuration
|
||||
* option for now; we don't want to bind ourselves too tightly to any particular
|
||||
* performance requirements for small values, or guarantee that we'll even be
|
||||
* able to provide fine-grained accuracy.
|
||||
*/
|
||||
#define PEAK_EVENT_WAIT (100 * 1024)
|
||||
|
||||
/* Update the peak with current tsd state. */
|
||||
void
|
||||
peak_event_update(tsd_t *tsd) {
|
||||
uint64_t alloc = tsd_thread_allocated_get(tsd);
|
||||
uint64_t dalloc = tsd_thread_deallocated_get(tsd);
|
||||
peak_t *peak = tsd_peakp_get(tsd);
|
||||
peak_update(peak, alloc, dalloc);
|
||||
}
|
||||
|
||||
/* Set current state to zero. */
|
||||
void
|
||||
peak_event_zero(tsd_t *tsd) {
|
||||
uint64_t alloc = tsd_thread_allocated_get(tsd);
|
||||
uint64_t dalloc = tsd_thread_deallocated_get(tsd);
|
||||
peak_t *peak = tsd_peakp_get(tsd);
|
||||
peak_set_zero(peak, alloc, dalloc);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
peak_event_max(tsd_t *tsd) {
|
||||
peak_t *peak = tsd_peakp_get(tsd);
|
||||
return peak_max(peak);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
peak_alloc_new_event_wait(tsd_t *tsd) {
|
||||
return PEAK_EVENT_WAIT;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
peak_alloc_postponed_event_wait(tsd_t *tsd) {
|
||||
return TE_MIN_START_WAIT;
|
||||
}
|
||||
|
||||
void
|
||||
peak_alloc_event_handler(tsd_t *tsd, uint64_t elapsed) {
|
||||
peak_event_update(tsd);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
peak_dalloc_new_event_wait(tsd_t *tsd) {
|
||||
return PEAK_EVENT_WAIT;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
peak_dalloc_postponed_event_wait(tsd_t *tsd) {
|
||||
return TE_MIN_START_WAIT;
|
||||
}
|
||||
|
||||
void
|
||||
peak_dalloc_event_handler(tsd_t *tsd, uint64_t elapsed) {
|
||||
peak_event_update(tsd);
|
||||
}
|
@@ -60,6 +60,16 @@ stats_interval_fetch_elapsed(tsd_t *tsd) {
|
||||
return last_event - last_stats_event;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
peak_alloc_fetch_elapsed(tsd_t *tsd) {
|
||||
return TE_INVALID_ELAPSED;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
peak_dalloc_fetch_elapsed(tsd_t *tsd) {
|
||||
return TE_INVALID_ELAPSED;
|
||||
}
|
||||
|
||||
/* Per event facilities done. */
|
||||
|
||||
static bool
|
||||
|
Reference in New Issue
Block a user