xref: /netbsd-src/external/bsd/jemalloc.old/dist/test/unit/background_thread.c (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
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