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