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, &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, &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 36static void 37mallctl_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 46static void 47mallctl_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 57static void 58mallctl_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 68static void 69mallctl_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 79static void 80prof_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 96TEST_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} 128TEST_END 129 130int 131main(void) 132{ 133 134 return (test( 135 test_prof_active)); 136} 137