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