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