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