1#include "test/jemalloc_test.h" 2 3#include "jemalloc/internal/util.h" 4 5static void 6test_switch_background_thread_ctl(bool new_val) { 7 bool e0, e1; 8 size_t sz = sizeof(bool); 9 10 e1 = new_val; 11 assert_d_eq(mallctl("background_thread", (void *)&e0, &sz, 12 &e1, sz), 0, "Unexpected mallctl() failure"); 13 assert_b_eq(e0, !e1, 14 "background_thread should be %d before.\n", !e1); 15 if (e1) { 16 assert_zu_gt(n_background_threads, 0, 17 "Number of background threads should be non zero.\n"); 18 } else { 19 assert_zu_eq(n_background_threads, 0, 20 "Number of background threads should be zero.\n"); 21 } 22} 23 24static void 25test_repeat_background_thread_ctl(bool before) { 26 bool e0, e1; 27 size_t sz = sizeof(bool); 28 29 e1 = before; 30 assert_d_eq(mallctl("background_thread", (void *)&e0, &sz, 31 &e1, sz), 0, "Unexpected mallctl() failure"); 32 assert_b_eq(e0, before, 33 "background_thread should be %d.\n", before); 34 if (e1) { 35 assert_zu_gt(n_background_threads, 0, 36 "Number of background threads should be non zero.\n"); 37 } else { 38 assert_zu_eq(n_background_threads, 0, 39 "Number of background threads should be zero.\n"); 40 } 41} 42 43TEST_BEGIN(test_background_thread_ctl) { 44 test_skip_if(!have_background_thread); 45 46 bool e0, e1; 47 size_t sz = sizeof(bool); 48 49 assert_d_eq(mallctl("opt.background_thread", (void *)&e0, &sz, 50 NULL, 0), 0, "Unexpected mallctl() failure"); 51 assert_d_eq(mallctl("background_thread", (void *)&e1, &sz, 52 NULL, 0), 0, "Unexpected mallctl() failure"); 53 assert_b_eq(e0, e1, 54 "Default and opt.background_thread does not match.\n"); 55 if (e0) { 56 test_switch_background_thread_ctl(false); 57 } 58 assert_zu_eq(n_background_threads, 0, 59 "Number of background threads should be 0.\n"); 60 61 for (unsigned i = 0; i < 4; i++) { 62 test_switch_background_thread_ctl(true); 63 test_repeat_background_thread_ctl(true); 64 test_repeat_background_thread_ctl(true); 65 66 test_switch_background_thread_ctl(false); 67 test_repeat_background_thread_ctl(false); 68 test_repeat_background_thread_ctl(false); 69 } 70} 71TEST_END 72 73TEST_BEGIN(test_background_thread_running) { 74 test_skip_if(!have_background_thread); 75 test_skip_if(!config_stats); 76 77#if defined(JEMALLOC_BACKGROUND_THREAD) 78 tsd_t *tsd = tsd_fetch(); 79 background_thread_info_t *info = &background_thread_info[0]; 80 81 test_repeat_background_thread_ctl(false); 82 test_switch_background_thread_ctl(true); 83 assert_b_eq(info->state, background_thread_started, 84 "Background_thread did not start.\n"); 85 86 nstime_t start, now; 87 nstime_init(&start, 0); 88 nstime_update(&start); 89 90 bool ran = false; 91 while (true) { 92 malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx); 93 if (info->tot_n_runs > 0) { 94 ran = true; 95 } 96 malloc_mutex_unlock(tsd_tsdn(tsd), &info->mtx); 97 if (ran) { 98 break; 99 } 100 101 nstime_init(&now, 0); 102 nstime_update(&now); 103 nstime_subtract(&now, &start); 104 assert_u64_lt(nstime_sec(&now), 1000, 105 "Background threads did not run for 1000 seconds."); 106 sleep(1); 107 } 108 test_switch_background_thread_ctl(false); 109#endif 110} 111TEST_END 112 113int 114main(void) { 115 /* Background_thread creation tests reentrancy naturally. */ 116 return test_no_reentrancy( 117 test_background_thread_ctl, 118 test_background_thread_running); 119} 120