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