xref: /netbsd-src/external/bsd/jemalloc/dist/test/unit/prof_accum.c (revision 7bdf38e5b7a28439665f2fdeff81e36913eef7dd)
1a0698ed9Schristos #include "test/jemalloc_test.h"
2a0698ed9Schristos 
3*7bdf38e5Schristos #include "jemalloc/internal/prof_data.h"
4*7bdf38e5Schristos #include "jemalloc/internal/prof_sys.h"
5*7bdf38e5Schristos 
6a0698ed9Schristos #define NTHREADS		4
7a0698ed9Schristos #define NALLOCS_PER_THREAD	50
8a0698ed9Schristos #define DUMP_INTERVAL		1
9a0698ed9Schristos #define BT_COUNT_CHECK_INTERVAL	5
10a0698ed9Schristos 
11a0698ed9Schristos static int
12*7bdf38e5Schristos prof_dump_open_file_intercept(const char *filename, int mode) {
13a0698ed9Schristos 	int fd;
14a0698ed9Schristos 
15a0698ed9Schristos 	fd = open("/dev/null", O_WRONLY);
16a0698ed9Schristos 	assert_d_ne(fd, -1, "Unexpected open() failure");
17a0698ed9Schristos 
18a0698ed9Schristos 	return fd;
19a0698ed9Schristos }
20a0698ed9Schristos 
21a0698ed9Schristos static void *
22a0698ed9Schristos alloc_from_permuted_backtrace(unsigned thd_ind, unsigned iteration) {
23a0698ed9Schristos 	return btalloc(1, thd_ind*NALLOCS_PER_THREAD + iteration);
24a0698ed9Schristos }
25a0698ed9Schristos 
26a0698ed9Schristos static void *
27a0698ed9Schristos thd_start(void *varg) {
28a0698ed9Schristos 	unsigned thd_ind = *(unsigned *)varg;
29a0698ed9Schristos 	size_t bt_count_prev, bt_count;
30a0698ed9Schristos 	unsigned i_prev, i;
31a0698ed9Schristos 
32a0698ed9Schristos 	i_prev = 0;
33a0698ed9Schristos 	bt_count_prev = 0;
34a0698ed9Schristos 	for (i = 0; i < NALLOCS_PER_THREAD; i++) {
35a0698ed9Schristos 		void *p = alloc_from_permuted_backtrace(thd_ind, i);
36a0698ed9Schristos 		dallocx(p, 0);
37a0698ed9Schristos 		if (i % DUMP_INTERVAL == 0) {
38*7bdf38e5Schristos 			expect_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0),
39a0698ed9Schristos 			    0, "Unexpected error while dumping heap profile");
40a0698ed9Schristos 		}
41a0698ed9Schristos 
42a0698ed9Schristos 		if (i % BT_COUNT_CHECK_INTERVAL == 0 ||
43a0698ed9Schristos 		    i+1 == NALLOCS_PER_THREAD) {
44a0698ed9Schristos 			bt_count = prof_bt_count();
45*7bdf38e5Schristos 			expect_zu_le(bt_count_prev+(i-i_prev), bt_count,
46a0698ed9Schristos 			    "Expected larger backtrace count increase");
47a0698ed9Schristos 			i_prev = i;
48a0698ed9Schristos 			bt_count_prev = bt_count;
49a0698ed9Schristos 		}
50a0698ed9Schristos 	}
51a0698ed9Schristos 
52a0698ed9Schristos 	return NULL;
53a0698ed9Schristos }
54a0698ed9Schristos 
55a0698ed9Schristos TEST_BEGIN(test_idump) {
56a0698ed9Schristos 	bool active;
57a0698ed9Schristos 	thd_t thds[NTHREADS];
58a0698ed9Schristos 	unsigned thd_args[NTHREADS];
59a0698ed9Schristos 	unsigned i;
60a0698ed9Schristos 
61a0698ed9Schristos 	test_skip_if(!config_prof);
62a0698ed9Schristos 
63a0698ed9Schristos 	active = true;
64*7bdf38e5Schristos 	expect_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active,
65a0698ed9Schristos 	    sizeof(active)), 0,
66a0698ed9Schristos 	    "Unexpected mallctl failure while activating profiling");
67a0698ed9Schristos 
68*7bdf38e5Schristos 	prof_dump_open_file = prof_dump_open_file_intercept;
69a0698ed9Schristos 
70a0698ed9Schristos 	for (i = 0; i < NTHREADS; i++) {
71a0698ed9Schristos 		thd_args[i] = i;
72a0698ed9Schristos 		thd_create(&thds[i], thd_start, (void *)&thd_args[i]);
73a0698ed9Schristos 	}
74a0698ed9Schristos 	for (i = 0; i < NTHREADS; i++) {
75a0698ed9Schristos 		thd_join(thds[i], NULL);
76a0698ed9Schristos 	}
77a0698ed9Schristos }
78a0698ed9Schristos TEST_END
79a0698ed9Schristos 
80a0698ed9Schristos int
81a0698ed9Schristos main(void) {
82a0698ed9Schristos 	return test_no_reentrancy(
83a0698ed9Schristos 	    test_idump);
84a0698ed9Schristos }
85