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