Deduplicate prof hook ctl handlers

This commit is contained in:
Slobodan Predolac 2026-05-21 17:15:14 -07:00
parent 366a2cd9c0
commit bbe86b591f
2 changed files with 54 additions and 93 deletions

131
src/ctl.c
View file

@ -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) {

View file

@ -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);
}