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, (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 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, (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 37 static void 38 mallctl_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 47 static void 48 mallctl_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 58 static void 59 mallctl_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 69 static void 70 mallctl_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 80 static void 81 prof_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 97 TEST_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 } 129 TEST_END 130 131 int 132 main(void) 133 { 134 135 return (test( 136 test_prof_active)); 137 } 138