xref: /netbsd-src/external/bsd/jemalloc/dist/test/unit/prof_log.c (revision 7bdf38e5b7a28439665f2fdeff81e36913eef7dd)
1 #include "test/jemalloc_test.h"
2 #include "jemalloc/internal/prof_log.h"
3 
4 #define N_PARAM 100
5 #define N_THREADS 10
6 
7 static void expect_rep() {
8 	expect_b_eq(prof_log_rep_check(), false, "Rep check failed");
9 }
10 
11 static void expect_log_empty() {
12 	expect_zu_eq(prof_log_bt_count(), 0,
13 	    "The log has backtraces; it isn't empty");
14 	expect_zu_eq(prof_log_thr_count(), 0,
15 	    "The log has threads; it isn't empty");
16 	expect_zu_eq(prof_log_alloc_count(), 0,
17 	    "The log has allocations; it isn't empty");
18 }
19 
20 void *buf[N_PARAM];
21 
22 static void f() {
23 	int i;
24 	for (i = 0; i < N_PARAM; i++) {
25 		buf[i] = malloc(100);
26 	}
27 	for (i = 0; i < N_PARAM; i++) {
28 		free(buf[i]);
29 	}
30 }
31 
32 TEST_BEGIN(test_prof_log_many_logs) {
33 	int i;
34 
35 	test_skip_if(!config_prof);
36 
37 	for (i = 0; i < N_PARAM; i++) {
38 		expect_b_eq(prof_log_is_logging(), false,
39 		    "Logging shouldn't have started yet");
40 		expect_d_eq(mallctl("prof.log_start", NULL, NULL, NULL, 0), 0,
41 		    "Unexpected mallctl failure when starting logging");
42 		expect_b_eq(prof_log_is_logging(), true,
43 		    "Logging should be started by now");
44 		expect_log_empty();
45 		expect_rep();
46 		f();
47 		expect_zu_eq(prof_log_thr_count(), 1, "Wrong thread count");
48 		expect_rep();
49 		expect_b_eq(prof_log_is_logging(), true,
50 		    "Logging should still be on");
51 		expect_d_eq(mallctl("prof.log_stop", NULL, NULL, NULL, 0), 0,
52 		    "Unexpected mallctl failure when stopping logging");
53 		expect_b_eq(prof_log_is_logging(), false,
54 		    "Logging should have turned off");
55 	}
56 }
57 TEST_END
58 
59 thd_t thr_buf[N_THREADS];
60 
61 static void *f_thread(void *unused) {
62 	int i;
63 	for (i = 0; i < N_PARAM; i++) {
64 		void *p = malloc(100);
65 		memset(p, 100, 1);
66 		free(p);
67 	}
68 
69 	return NULL;
70 }
71 
72 TEST_BEGIN(test_prof_log_many_threads) {
73 
74 	test_skip_if(!config_prof);
75 
76 	int i;
77 	expect_d_eq(mallctl("prof.log_start", NULL, NULL, NULL, 0), 0,
78 	    "Unexpected mallctl failure when starting logging");
79 	for (i = 0; i < N_THREADS; i++) {
80 		thd_create(&thr_buf[i], &f_thread, NULL);
81 	}
82 
83 	for (i = 0; i < N_THREADS; i++) {
84 		thd_join(thr_buf[i], NULL);
85 	}
86 	expect_zu_eq(prof_log_thr_count(), N_THREADS,
87 	    "Wrong number of thread entries");
88 	expect_rep();
89 	expect_d_eq(mallctl("prof.log_stop", NULL, NULL, NULL, 0), 0,
90 	    "Unexpected mallctl failure when stopping logging");
91 }
92 TEST_END
93 
94 static void f3() {
95 	void *p = malloc(100);
96 	free(p);
97 }
98 
99 static void f1() {
100 	void *p = malloc(100);
101 	f3();
102 	free(p);
103 }
104 
105 static void f2() {
106 	void *p = malloc(100);
107 	free(p);
108 }
109 
110 TEST_BEGIN(test_prof_log_many_traces) {
111 
112 	test_skip_if(!config_prof);
113 
114 	expect_d_eq(mallctl("prof.log_start", NULL, NULL, NULL, 0), 0,
115 	    "Unexpected mallctl failure when starting logging");
116 	int i;
117 	expect_rep();
118 	expect_log_empty();
119 	for (i = 0; i < N_PARAM; i++) {
120 		expect_rep();
121 		f1();
122 		expect_rep();
123 		f2();
124 		expect_rep();
125 		f3();
126 		expect_rep();
127 	}
128 	/*
129 	 * There should be 8 total backtraces: two for malloc/free in f1(), two
130 	 * for malloc/free in f2(), two for malloc/free in f3(), and then two
131 	 * for malloc/free in f1()'s call to f3().  However compiler
132 	 * optimizations such as loop unrolling might generate more call sites.
133 	 * So >= 8 traces are expected.
134 	 */
135 	expect_zu_ge(prof_log_bt_count(), 8,
136 	    "Expect at least 8 backtraces given sample workload");
137 	expect_d_eq(mallctl("prof.log_stop", NULL, NULL, NULL, 0), 0,
138 	    "Unexpected mallctl failure when stopping logging");
139 }
140 TEST_END
141 
142 int
143 main(void) {
144 	if (config_prof) {
145 		prof_log_dummy_set(true);
146 	}
147 	return test_no_reentrancy(
148 	    test_prof_log_many_logs,
149 	    test_prof_log_many_traces,
150 	    test_prof_log_many_threads);
151 }
152