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