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 42 mallctl_bool_get("prof.active", prof_active_old_expected, func, line); 43} 44#define mallctl_prof_active_get(a) \ 45 mallctl_prof_active_get_impl(a, __func__, __LINE__) 46 47static void 48mallctl_prof_active_set_impl(bool prof_active_old_expected, 49 bool prof_active_new, const char *func, int line) 50{ 51 52 mallctl_bool_set("prof.active", prof_active_old_expected, 53 prof_active_new, func, line); 54} 55#define mallctl_prof_active_set(a, b) \ 56 mallctl_prof_active_set_impl(a, b, __func__, __LINE__) 57 58static void 59mallctl_thread_prof_active_get_impl(bool thread_prof_active_old_expected, 60 const char *func, int line) 61{ 62 63 mallctl_bool_get("thread.prof.active", thread_prof_active_old_expected, 64 func, line); 65} 66#define mallctl_thread_prof_active_get(a) \ 67 mallctl_thread_prof_active_get_impl(a, __func__, __LINE__) 68 69static void 70mallctl_thread_prof_active_set_impl(bool thread_prof_active_old_expected, 71 bool thread_prof_active_new, const char *func, int line) 72{ 73 74 mallctl_bool_set("thread.prof.active", thread_prof_active_old_expected, 75 thread_prof_active_new, func, line); 76} 77#define mallctl_thread_prof_active_set(a, b) \ 78 mallctl_thread_prof_active_set_impl(a, b, __func__, __LINE__) 79 80static void 81prof_sampling_probe_impl(bool expect_sample, const char *func, int line) 82{ 83 void *p; 84 size_t expected_backtraces = expect_sample ? 1 : 0; 85 86 assert_zu_eq(prof_bt_count(), 0, "%s():%d: Expected 0 backtraces", func, 87 line); 88 p = mallocx(1, 0); 89 assert_ptr_not_null(p, "Unexpected mallocx() failure"); 90 assert_zu_eq(prof_bt_count(), expected_backtraces, 91 "%s():%d: Unexpected backtrace count", func, line); 92 dallocx(p, 0); 93} 94#define prof_sampling_probe(a) \ 95 prof_sampling_probe_impl(a, __func__, __LINE__) 96 97TEST_BEGIN(test_prof_active) 98{ 99 100 test_skip_if(!config_prof); 101 102 mallctl_prof_active_get(true); 103 mallctl_thread_prof_active_get(false); 104 105 mallctl_prof_active_set(true, true); 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(true, false); 111 mallctl_thread_prof_active_set(false, false); 112 /* !prof.active, !thread.prof.active. */ 113 prof_sampling_probe(false); 114 115 mallctl_prof_active_set(false, false); 116 mallctl_thread_prof_active_set(false, true); 117 /* !prof.active, thread.prof.active. */ 118 prof_sampling_probe(false); 119 120 mallctl_prof_active_set(false, true); 121 mallctl_thread_prof_active_set(true, true); 122 /* prof.active, thread.prof.active. */ 123 prof_sampling_probe(true); 124 125 /* Restore settings. */ 126 mallctl_prof_active_set(true, true); 127 mallctl_thread_prof_active_set(true, false); 128} 129TEST_END 130 131int 132main(void) 133{ 134 135 return (test( 136 test_prof_active)); 137} 138