From bbe86b591f64493b3ed197c779c1f79bab8b1617 Mon Sep 17 00:00:00 2001 From: Slobodan Predolac Date: Thu, 21 May 2026 17:15:14 -0700 Subject: [PATCH] Deduplicate prof hook ctl handlers --- src/ctl.c | 131 +++++++++++++----------------------------- test/unit/prof_hook.c | 16 +++++- 2 files changed, 54 insertions(+), 93 deletions(-) diff --git a/src/ctl.c b/src/ctl.c index 2112c26e..132d0503 100644 --- a/src/ctl.c +++ b/src/ctl.c @@ -3599,118 +3599,65 @@ prof_log_stop_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, return 0; } +#define PROF_HOOK_CTL_BODY(hook_type, hook_get, hook_set, allow_null) \ + do { \ + int ret; \ + if (oldp == NULL && newp == NULL) { \ + ret = EINVAL; \ + goto label_return; \ + } \ + if (oldp != NULL) { \ + hook_type old_hook = hook_get(); \ + READ(old_hook, hook_type); \ + } \ + if (newp != NULL) { \ + if (!opt_prof) { \ + ret = ENOENT; \ + goto label_return; \ + } \ + hook_type new_hook JEMALLOC_CC_SILENCE_INIT(NULL); \ + WRITE(new_hook, hook_type); \ + if (!(allow_null) && new_hook == NULL) { \ + ret = EINVAL; \ + goto label_return; \ + } \ + hook_set(new_hook); \ + } \ + ret = 0; \ + label_return: \ + return ret; \ + } while (0) + static int experimental_hooks_prof_backtrace_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { - int ret; - - if (oldp == NULL && newp == NULL) { - ret = EINVAL; - goto label_return; - } - if (oldp != NULL) { - prof_backtrace_hook_t old_hook = prof_backtrace_hook_get(); - READ(old_hook, prof_backtrace_hook_t); - } - if (newp != NULL) { - if (!opt_prof) { - ret = ENOENT; - goto label_return; - } - prof_backtrace_hook_t new_hook JEMALLOC_CC_SILENCE_INIT(NULL); - WRITE(new_hook, prof_backtrace_hook_t); - if (new_hook == NULL) { - ret = EINVAL; - goto label_return; - } - prof_backtrace_hook_set(new_hook); - } - ret = 0; -label_return: - return ret; + PROF_HOOK_CTL_BODY(prof_backtrace_hook_t, prof_backtrace_hook_get, + prof_backtrace_hook_set, false); } static int experimental_hooks_prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { - int ret; - - if (oldp == NULL && newp == NULL) { - ret = EINVAL; - goto label_return; - } - if (oldp != NULL) { - prof_dump_hook_t old_hook = prof_dump_hook_get(); - READ(old_hook, prof_dump_hook_t); - } - if (newp != NULL) { - if (!opt_prof) { - ret = ENOENT; - goto label_return; - } - prof_dump_hook_t new_hook JEMALLOC_CC_SILENCE_INIT(NULL); - WRITE(new_hook, prof_dump_hook_t); - prof_dump_hook_set(new_hook); - } - ret = 0; -label_return: - return ret; + PROF_HOOK_CTL_BODY(prof_dump_hook_t, prof_dump_hook_get, + prof_dump_hook_set, true); } static int experimental_hooks_prof_sample_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { - int ret; - - if (oldp == NULL && newp == NULL) { - ret = EINVAL; - goto label_return; - } - if (oldp != NULL) { - prof_sample_hook_t old_hook = prof_sample_hook_get(); - READ(old_hook, prof_sample_hook_t); - } - if (newp != NULL) { - if (!opt_prof) { - ret = ENOENT; - goto label_return; - } - prof_sample_hook_t new_hook JEMALLOC_CC_SILENCE_INIT(NULL); - WRITE(new_hook, prof_sample_hook_t); - prof_sample_hook_set(new_hook); - } - ret = 0; -label_return: - return ret; + PROF_HOOK_CTL_BODY(prof_sample_hook_t, prof_sample_hook_get, + prof_sample_hook_set, true); } static int experimental_hooks_prof_sample_free_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { - int ret; - - if (oldp == NULL && newp == NULL) { - ret = EINVAL; - goto label_return; - } - if (oldp != NULL) { - prof_sample_free_hook_t old_hook = prof_sample_free_hook_get(); - READ(old_hook, prof_sample_free_hook_t); - } - if (newp != NULL) { - if (!opt_prof) { - ret = ENOENT; - goto label_return; - } - prof_sample_free_hook_t new_hook JEMALLOC_CC_SILENCE_INIT(NULL); - WRITE(new_hook, prof_sample_free_hook_t); - prof_sample_free_hook_set(new_hook); - } - ret = 0; -label_return: - return ret; + PROF_HOOK_CTL_BODY(prof_sample_free_hook_t, prof_sample_free_hook_get, + prof_sample_free_hook_set, true); } +#undef PROF_HOOK_CTL_BODY + static int experimental_hooks_thread_event_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { diff --git a/test/unit/prof_hook.c b/test/unit/prof_hook.c index 1d58469c..72c0c43e 100644 --- a/test/unit/prof_hook.c +++ b/test/unit/prof_hook.c @@ -334,9 +334,23 @@ TEST_BEGIN(test_prof_sample_hooks) { } TEST_END +TEST_BEGIN(test_prof_hook_noop) { + test_skip_if(!config_prof); + + const char *hooks[] = {"experimental.hooks.prof_backtrace", + "experimental.hooks.prof_dump", "experimental.hooks.prof_sample", + "experimental.hooks.prof_sample_free"}; + + for (unsigned i = 0; i < sizeof(hooks) / sizeof(hooks[0]); i++) { + expect_d_eq(mallctl(hooks[i], NULL, NULL, NULL, 0), EINVAL, + "Unexpected noop hook mallctl result"); + } +} +TEST_END + int main(void) { return test(test_prof_backtrace_hook_replace, test_prof_backtrace_hook_augment, test_prof_dump_hook, - test_prof_sample_hooks); + test_prof_sample_hooks, test_prof_hook_noop); }