1#include "test/jemalloc_test.h" 2 3#ifdef JEMALLOC_PROF 4const char *malloc_conf = 5 "prof:true,prof_thread_active_init:false,lg_prof_sample:0"; 6#endif 7 8static void 9mallctl_bool_get(const char *name, bool expected, const char *func, int line) 10{ 11 bool old; 12 size_t sz; 13 14 sz = sizeof(old); 15 assert_d_eq(mallctl(name, (void *)&old, &sz, NULL, 0), 0, 16 "%s():%d: Unexpected mallctl failure reading %s", func, line, name); 17 assert_b_eq(old, expected, "%s():%d: Unexpected %s value", func, line, 18 name); 19} 20 21static void 22mallctl_bool_set(const char *name, bool old_expected, bool val_new, 23 const char *func, int line) 24{ 25 bool old; 26 size_t sz; 27 28 sz = sizeof(old); 29 assert_d_eq(mallctl(name, (void *)&old, &sz, (void *)&val_new, 30 sizeof(val_new)), 0, 31 "%s():%d: Unexpected mallctl failure reading/writing %s", func, 32 line, name); 33 assert_b_eq(old, old_expected, "%s():%d: Unexpected %s value", func, 34 line, name); 35} 36 37static void 38mallctl_prof_active_get_impl(bool prof_active_old_expected, const char *func, 39 int line) 40{ 41 mallctl_bool_get("prof.active", prof_active_old_expected, func, line); 42} 43#define mallctl_prof_active_get(a) \ 44 mallctl_prof_active_get_impl(a, __func__, __LINE__) 45 46static void 47mallctl_prof_active_set_impl(bool prof_active_old_expected, 48 bool prof_active_new, const char *func, int line) 49{ 50 mallctl_bool_set("prof.active", prof_active_old_expected, 51 prof_active_new, func, line); 52} 53#define mallctl_prof_active_set(a, b) \ 54 mallctl_prof_active_set_impl(a, b, __func__, __LINE__) 55 56static void 57mallctl_thread_prof_active_get_impl(bool thread_prof_active_old_expected, 58 const char *func, int line) 59{ 60 mallctl_bool_get("thread.prof.active", thread_prof_active_old_expected, 61 func, line); 62} 63#define mallctl_thread_prof_active_get(a) \ 64 mallctl_thread_prof_active_get_impl(a, __func__, __LINE__) 65 66static void 67mallctl_thread_prof_active_set_impl(bool thread_prof_active_old_expected, 68 bool thread_prof_active_new, const char *func, int line) 69{ 70 mallctl_bool_set("thread.prof.active", thread_prof_active_old_expected, 71 thread_prof_active_new, func, line); 72} 73#define mallctl_thread_prof_active_set(a, b) \ 74 mallctl_thread_prof_active_set_impl(a, b, __func__, __LINE__) 75 76static void 77prof_sampling_probe_impl(bool expect_sample, const char *func, int line) 78{ 79 void *p; 80 size_t expected_backtraces = expect_sample ? 1 : 0; 81 82 assert_zu_eq(prof_bt_count(), 0, "%s():%d: Expected 0 backtraces", func, 83 line); 84 p = mallocx(1, 0); 85 assert_ptr_not_null(p, "Unexpected mallocx() failure"); 86 assert_zu_eq(prof_bt_count(), expected_backtraces, 87 "%s():%d: Unexpected backtrace count", func, line); 88 dallocx(p, 0); 89} 90#define prof_sampling_probe(a) \ 91 prof_sampling_probe_impl(a, __func__, __LINE__) 92 93TEST_BEGIN(test_prof_active) 94{ 95 test_skip_if(!config_prof); 96 97 mallctl_prof_active_get(true); 98 mallctl_thread_prof_active_get(false); 99 100 mallctl_prof_active_set(true, true); 101 mallctl_thread_prof_active_set(false, false); 102 /* prof.active, !thread.prof.active. */ 103 prof_sampling_probe(false); 104 105 mallctl_prof_active_set(true, false); 106 mallctl_thread_prof_active_set(false, false); 107 /* !prof.active, !thread.prof.active. */ 108 prof_sampling_probe(false); 109 110 mallctl_prof_active_set(false, false); 111 mallctl_thread_prof_active_set(false, true); 112 /* !prof.active, thread.prof.active. */ 113 prof_sampling_probe(false); 114 115 mallctl_prof_active_set(false, true); 116 mallctl_thread_prof_active_set(true, true); 117 /* prof.active, thread.prof.active. */ 118 prof_sampling_probe(true); 119 120 /* Restore settings. */ 121 mallctl_prof_active_set(true, true); 122 mallctl_thread_prof_active_set(true, false); 123} 124TEST_END 125 126int 127main(void) 128{ 129 return (test( 130 test_prof_active)); 131} 132