Unlike prof_sample which is supported only with profiling mode active, prof_threshold is intended to be an always-supported allocation callback with much less overhead. The usage of the threshold allows performance critical callers to change program execution based on the callback: e.g. drop caches when memory becomes high or to predict the program is about to OOM ahead of time using peak memory watermarks.

This commit is contained in:
Shai Duvdevani 2025-01-29 15:25:10 -08:00 committed by Qi Wang
parent ef8e512e29
commit 257e64b968
22 changed files with 246 additions and 0 deletions

View file

@ -11,6 +11,7 @@ extern bool opt_prof_active;
extern bool opt_prof_thread_active_init;
extern unsigned opt_prof_bt_max;
extern size_t opt_lg_prof_sample; /* Mean bytes between samples. */
extern size_t opt_experimental_lg_prof_threshold; /* Mean bytes between thresholds. */
extern ssize_t opt_lg_prof_interval; /* lg(prof_interval). */
extern bool opt_prof_gdump; /* High-water memory dumping. */
extern bool opt_prof_final; /* Final profile dumping. */
@ -67,6 +68,9 @@ prof_sample_hook_t prof_sample_hook_get(void);
void prof_sample_free_hook_set(prof_sample_free_hook_t hook);
prof_sample_free_hook_t prof_sample_free_hook_get(void);
void prof_threshold_hook_set(prof_threshold_hook_t hook);
prof_threshold_hook_t prof_threshold_hook_get(void);
/* Functions only accessed in prof_inlines.h */
prof_tdata_t *prof_tdata_init(tsd_t *tsd);
prof_tdata_t *prof_tdata_reinit(tsd_t *tsd, prof_tdata_t *tdata);

View file

@ -26,4 +26,9 @@ typedef void (*prof_sample_hook_t)(const void *ptr, size_t size, void **backtrac
/* ptr, size */
typedef void (*prof_sample_free_hook_t)(const void *, size_t);
/*
* A callback hook that notifies when an allocation threshold has been crossed.
*/
typedef void (*prof_threshold_hook_t)(uint64_t alloc, uint64_t dealloc, uint64_t peak);
#endif /* JEMALLOC_INTERNAL_PROF_HOOK_H */

View file

@ -0,0 +1,11 @@
#ifndef JEMALLOC_INTERNAL_THRESHOLD_EVENT_H
#define JEMALLOC_INTERNAL_THRESHOLD_EVENT_H
#include "jemalloc/internal/tsd_types.h"
/* The activity-triggered hooks. */
uint64_t prof_threshold_new_event_wait(tsd_t *tsd);
uint64_t prof_threshold_postponed_event_wait(tsd_t *tsd);
void prof_threshold_event_handler(tsd_t *tsd, uint64_t elapsed);
#endif /* JEMALLOC_INTERNAL_THRESHOLD_EVENT_H */

View file

@ -56,6 +56,7 @@ void tsd_te_init(tsd_t *tsd);
#define ITERATE_OVER_ALL_EVENTS \
E(tcache_gc, (opt_tcache_gc_incr_bytes > 0), true) \
E(prof_sample, (config_prof && opt_prof), true) \
E(prof_threshold, config_stats, true) \
E(stats_interval, (opt_stats_interval >= 0), true) \
E(tcache_gc_dalloc, (opt_tcache_gc_incr_bytes > 0), false) \
E(peak_alloc, config_stats, true) \

View file

@ -72,6 +72,7 @@ typedef ql_elm(tsd_t) tsd_link_t;
O(tcache_gc_dalloc_event_wait, uint64_t, uint64_t) \
O(prof_sample_event_wait, uint64_t, uint64_t) \
O(prof_sample_last_event, uint64_t, uint64_t) \
O(prof_threshold_event_wait, uint64_t, uint64_t) \
O(stats_interval_event_wait, uint64_t, uint64_t) \
O(stats_interval_last_event, uint64_t, uint64_t) \
O(peak_alloc_event_wait, uint64_t, uint64_t) \
@ -105,6 +106,7 @@ typedef ql_elm(tsd_t) tsd_link_t;
/* tcache_gc_dalloc_event_wait */ 0, \
/* prof_sample_event_wait */ 0, \
/* prof_sample_last_event */ 0, \
/* prof_threshold_event_wait */ 0, \
/* stats_interval_event_wait */ 0, \
/* stats_interval_last_event */ 0, \
/* peak_alloc_event_wait */ 0, \