decay.c revision 9bad07903962962de9f656d281b9b1e7e9501c87
1243f7a0508bb014c2a7bf592c466a923911db234Jason Evans#include "test/jemalloc_test.h"
2243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
3243f7a0508bb014c2a7bf592c466a923911db234Jason Evansconst char *malloc_conf = "purge:decay,decay_time:1";
4243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
59bad07903962962de9f656d281b9b1e7e9501c87Jason Evansstatic nstime_update_t *nstime_update_orig;
6243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
7243f7a0508bb014c2a7bf592c466a923911db234Jason Evansstatic unsigned nupdates_mock;
89bad07903962962de9f656d281b9b1e7e9501c87Jason Evansstatic nstime_t time_mock;
9243f7a0508bb014c2a7bf592c466a923911db234Jason Evansstatic bool nonmonotonic_mock;
10243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
11243f7a0508bb014c2a7bf592c466a923911db234Jason Evansstatic bool
129bad07903962962de9f656d281b9b1e7e9501c87Jason Evansnstime_update_mock(nstime_t *time)
13243f7a0508bb014c2a7bf592c466a923911db234Jason Evans{
14243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
15243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	nupdates_mock++;
16243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	if (!nonmonotonic_mock)
179bad07903962962de9f656d281b9b1e7e9501c87Jason Evans		nstime_copy(time, &time_mock);
18243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	return (nonmonotonic_mock);
19243f7a0508bb014c2a7bf592c466a923911db234Jason Evans}
20243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
21243f7a0508bb014c2a7bf592c466a923911db234Jason EvansTEST_BEGIN(test_decay_ticks)
22243f7a0508bb014c2a7bf592c466a923911db234Jason Evans{
23243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	ticker_t *decay_ticker;
24243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	unsigned tick0, tick1;
25243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	size_t sz, huge0, large0;
26243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	void *p;
27243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
28243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	test_skip_if(opt_purge != purge_mode_decay);
29243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
30243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	decay_ticker = decay_ticker_get(tsd_fetch(), 0);
31243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_ptr_not_null(decay_ticker,
32243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected failure getting decay ticker");
33243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
34243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	sz = sizeof(size_t);
35243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(mallctl("arenas.hchunk.0.size", &huge0, &sz, NULL, 0), 0,
36243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected mallctl failure");
37243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(mallctl("arenas.lrun.0.size", &large0, &sz, NULL, 0), 0,
38243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected mallctl failure");
39243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
409f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	/*
419f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	 * Test the standard APIs using a huge size class, since we can't
429f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	 * control tcache interactions (except by completely disabling tcache
439f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	 * for the entire test program).
449f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	 */
459f24c944744e91d0cfe1864287ca7a52c16598faJason Evans
46243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	/* malloc(). */
47243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick0 = ticker_read(decay_ticker);
48243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	p = malloc(huge0);
49243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_ptr_not_null(p, "Unexpected malloc() failure");
50243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick1 = ticker_read(decay_ticker);
51243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_u32_ne(tick1, tick0, "Expected ticker to tick during malloc()");
52243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	/* free(). */
53243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick0 = ticker_read(decay_ticker);
54243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	free(p);
55243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick1 = ticker_read(decay_ticker);
56243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_u32_ne(tick1, tick0, "Expected ticker to tick during free()");
57243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
58243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	/* calloc(). */
59243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick0 = ticker_read(decay_ticker);
60243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	p = calloc(1, huge0);
61243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_ptr_not_null(p, "Unexpected calloc() failure");
62243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick1 = ticker_read(decay_ticker);
63243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_u32_ne(tick1, tick0, "Expected ticker to tick during calloc()");
64243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	free(p);
65243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
66243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	/* posix_memalign(). */
67243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick0 = ticker_read(decay_ticker);
68243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(posix_memalign(&p, sizeof(size_t), huge0), 0,
69243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected posix_memalign() failure");
70243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick1 = ticker_read(decay_ticker);
71243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_u32_ne(tick1, tick0,
72243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Expected ticker to tick during posix_memalign()");
73243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	free(p);
74243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
75243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	/* aligned_alloc(). */
76243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick0 = ticker_read(decay_ticker);
77243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	p = aligned_alloc(sizeof(size_t), huge0);
78243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_ptr_not_null(p, "Unexpected aligned_alloc() failure");
79243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick1 = ticker_read(decay_ticker);
80243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_u32_ne(tick1, tick0,
81243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Expected ticker to tick during aligned_alloc()");
82243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	free(p);
83243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
84243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	/* realloc(). */
85243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	/* Allocate. */
86243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick0 = ticker_read(decay_ticker);
87243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	p = realloc(NULL, huge0);
88243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_ptr_not_null(p, "Unexpected realloc() failure");
89243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick1 = ticker_read(decay_ticker);
90243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_u32_ne(tick1, tick0, "Expected ticker to tick during realloc()");
91243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	/* Reallocate. */
92243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick0 = ticker_read(decay_ticker);
93243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	p = realloc(p, huge0);
94243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_ptr_not_null(p, "Unexpected realloc() failure");
95243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick1 = ticker_read(decay_ticker);
96243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_u32_ne(tick1, tick0, "Expected ticker to tick during realloc()");
97243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	/* Deallocate. */
98243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick0 = ticker_read(decay_ticker);
99243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	realloc(p, 0);
100243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	tick1 = ticker_read(decay_ticker);
101243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_u32_ne(tick1, tick0, "Expected ticker to tick during realloc()");
102243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
1039f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	/*
1049f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	 * Test the *allocx() APIs using huge, large, and small size classes,
1059f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	 * with tcache explicitly disabled.
1069f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	 */
1079f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	{
1089f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		unsigned i;
1099f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		size_t allocx_sizes[3];
1109f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		allocx_sizes[0] = huge0;
1119f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		allocx_sizes[1] = large0;
1129f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		allocx_sizes[2] = 1;
1139f24c944744e91d0cfe1864287ca7a52c16598faJason Evans
1149f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		for (i = 0; i < sizeof(allocx_sizes) / sizeof(size_t); i++) {
1159f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			sz = allocx_sizes[i];
1169f24c944744e91d0cfe1864287ca7a52c16598faJason Evans
1179f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			/* mallocx(). */
1189f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick0 = ticker_read(decay_ticker);
1199f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			p = mallocx(sz, MALLOCX_TCACHE_NONE);
1209f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			assert_ptr_not_null(p, "Unexpected mallocx() failure");
1219f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick1 = ticker_read(decay_ticker);
1229f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			assert_u32_ne(tick1, tick0,
1239f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    "Expected ticker to tick during mallocx() (sz=%zu)",
1249f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    sz);
1259f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			/* rallocx(). */
1269f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick0 = ticker_read(decay_ticker);
1279f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			p = rallocx(p, sz, MALLOCX_TCACHE_NONE);
1289f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			assert_ptr_not_null(p, "Unexpected rallocx() failure");
1299f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick1 = ticker_read(decay_ticker);
1309f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			assert_u32_ne(tick1, tick0,
1319f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    "Expected ticker to tick during rallocx() (sz=%zu)",
1329f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    sz);
1339f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			/* xallocx(). */
1349f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick0 = ticker_read(decay_ticker);
1359f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			xallocx(p, sz, 0, MALLOCX_TCACHE_NONE);
1369f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick1 = ticker_read(decay_ticker);
1379f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			assert_u32_ne(tick1, tick0,
1389f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    "Expected ticker to tick during xallocx() (sz=%zu)",
1399f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    sz);
1409f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			/* dallocx(). */
1419f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick0 = ticker_read(decay_ticker);
1429f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			dallocx(p, MALLOCX_TCACHE_NONE);
1439f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick1 = ticker_read(decay_ticker);
1449f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			assert_u32_ne(tick1, tick0,
1459f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    "Expected ticker to tick during dallocx() (sz=%zu)",
1469f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    sz);
1479f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			/* sdallocx(). */
1489f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			p = mallocx(sz, MALLOCX_TCACHE_NONE);
1499f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			assert_ptr_not_null(p, "Unexpected mallocx() failure");
1509f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick0 = ticker_read(decay_ticker);
1519f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			sdallocx(p, sz, MALLOCX_TCACHE_NONE);
1529f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick1 = ticker_read(decay_ticker);
1539f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			assert_u32_ne(tick1, tick0,
1549f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    "Expected ticker to tick during sdallocx() "
1559f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    "(sz=%zu)", sz);
1569f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		}
1579f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	}
1589f24c944744e91d0cfe1864287ca7a52c16598faJason Evans
1599f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	/*
1609f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	 * Test tcache fill/flush interactions for large and small size classes,
1619f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	 * using an explicit tcache.
1629f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	 */
1639f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	{
1649f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		unsigned tcache_ind, i;
1659f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		size_t tcache_sizes[2];
1669f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		tcache_sizes[0] = large0;
1679f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		tcache_sizes[1] = 1;
1689f24c944744e91d0cfe1864287ca7a52c16598faJason Evans
1699f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		sz = sizeof(unsigned);
1709f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		assert_d_eq(mallctl("tcache.create", &tcache_ind, &sz, NULL, 0),
1719f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		    0, "Unexpected mallctl failure");
1729f24c944744e91d0cfe1864287ca7a52c16598faJason Evans
1739f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		for (i = 0; i < sizeof(tcache_sizes) / sizeof(size_t); i++) {
1749f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			sz = tcache_sizes[i];
1759f24c944744e91d0cfe1864287ca7a52c16598faJason Evans
1769f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			/* tcache fill. */
1779f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick0 = ticker_read(decay_ticker);
1789f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			p = mallocx(sz, MALLOCX_TCACHE(tcache_ind));
1799f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			assert_ptr_not_null(p, "Unexpected mallocx() failure");
1809f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick1 = ticker_read(decay_ticker);
1819f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			assert_u32_ne(tick1, tick0,
1829f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    "Expected ticker to tick during tcache fill "
1839f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    "(sz=%zu)", sz);
1849f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			/* tcache flush. */
1859f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			dallocx(p, MALLOCX_TCACHE(tcache_ind));
1869f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick0 = ticker_read(decay_ticker);
1879f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			assert_d_eq(mallctl("tcache.flush", NULL, NULL,
1889f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    &tcache_ind, sizeof(unsigned)), 0,
1899f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    "Unexpected mallctl failure");
1909f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			tick1 = ticker_read(decay_ticker);
1919f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			assert_u32_ne(tick1, tick0,
1929f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    "Expected ticker to tick during tcache flush "
1939f24c944744e91d0cfe1864287ca7a52c16598faJason Evans			    "(sz=%zu)", sz);
1949f24c944744e91d0cfe1864287ca7a52c16598faJason Evans		}
1959f24c944744e91d0cfe1864287ca7a52c16598faJason Evans	}
196243f7a0508bb014c2a7bf592c466a923911db234Jason Evans}
197243f7a0508bb014c2a7bf592c466a923911db234Jason EvansTEST_END
198243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
199243f7a0508bb014c2a7bf592c466a923911db234Jason EvansTEST_BEGIN(test_decay_ticker)
200243f7a0508bb014c2a7bf592c466a923911db234Jason Evans{
201243f7a0508bb014c2a7bf592c466a923911db234Jason Evans#define	NPS 1024
202243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	int flags = (MALLOCX_ARENA(0) | MALLOCX_TCACHE_NONE);
203243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	void *ps[NPS];
204243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	uint64_t epoch, npurge0, npurge1;
205243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	size_t sz, tcache_max, large;
206243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	unsigned i, nupdates0;
2079bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_t time, decay_time, deadline;
208243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
209243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	test_skip_if(opt_purge != purge_mode_decay);
210243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
211243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	/*
212243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	 * Allocate a bunch of large objects, pause the clock, deallocate the
213243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	 * objects, restore the clock, then [md]allocx() in a tight loop to
214243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	 * verify the ticker triggers purging.
215243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	 */
216243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
217243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	sz = sizeof(size_t);
218243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(mallctl("arenas.tcache_max", &tcache_max, &sz, NULL, 0), 0,
219243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected mallctl failure");
220243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	large = nallocx(tcache_max + 1, flags);
221243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
222243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
223243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected mallctl failure");
224243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(uint64_t)), 0,
225243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected mallctl failure");
226243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	sz = sizeof(uint64_t);
227243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge0, &sz, NULL, 0), 0,
228243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected mallctl failure");
229243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
230243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	for (i = 0; i < NPS; i++) {
231243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		ps[i] = mallocx(large, flags);
232243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		assert_ptr_not_null(ps[i], "Unexpected mallocx() failure");
233243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	}
234243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
235243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	nupdates_mock = 0;
2369bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_init(&time_mock, 0);
2379bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_update(&time_mock);
238243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	nonmonotonic_mock = false;
239243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
2409bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_update_orig = nstime_update;
2419bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_update = nstime_update_mock;
242243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
243243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	for (i = 0; i < NPS; i++) {
244243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		dallocx(ps[i], flags);
245243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		nupdates0 = nupdates_mock;
246243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		assert_d_eq(mallctl("arena.0.decay", NULL, NULL, NULL, 0), 0,
247243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		    "Unexpected arena.0.decay failure");
248243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		assert_u_gt(nupdates_mock, nupdates0,
2499bad07903962962de9f656d281b9b1e7e9501c87Jason Evans		    "Expected nstime_update() to be called");
250243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	}
251243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
2529bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_update = nstime_update_orig;
253243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
2549bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_init(&time, 0);
2559bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_update(&time);
2569bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_init2(&decay_time, opt_decay_time, 0);
2579bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_copy(&deadline, &time);
2589bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_add(&deadline, &decay_time);
259243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	do {
260243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		for (i = 0; i < DECAY_NTICKS_PER_UPDATE / 2; i++) {
261243f7a0508bb014c2a7bf592c466a923911db234Jason Evans			void *p = mallocx(1, flags);
262243f7a0508bb014c2a7bf592c466a923911db234Jason Evans			assert_ptr_not_null(p, "Unexpected mallocx() failure");
263243f7a0508bb014c2a7bf592c466a923911db234Jason Evans			dallocx(p, flags);
264243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		}
265243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		assert_d_eq(mallctl("epoch", NULL, NULL, &epoch,
266243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		    sizeof(uint64_t)), 0, "Unexpected mallctl failure");
267243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		sz = sizeof(uint64_t);
268243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge1, &sz,
269243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		    NULL, 0), 0, "Unexpected mallctl failure");
270243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
2719bad07903962962de9f656d281b9b1e7e9501c87Jason Evans		nstime_update(&time);
2729bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	} while (nstime_compare(&time, &deadline) <= 0 && npurge1 == npurge0);
273243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
274243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_u64_gt(npurge1, npurge0, "Expected purging to occur");
275243f7a0508bb014c2a7bf592c466a923911db234Jason Evans#undef NPS
276243f7a0508bb014c2a7bf592c466a923911db234Jason Evans}
277243f7a0508bb014c2a7bf592c466a923911db234Jason EvansTEST_END
278243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
279243f7a0508bb014c2a7bf592c466a923911db234Jason EvansTEST_BEGIN(test_decay_nonmonotonic)
280243f7a0508bb014c2a7bf592c466a923911db234Jason Evans{
281243f7a0508bb014c2a7bf592c466a923911db234Jason Evans#define	NPS (SMOOTHSTEP_NSTEPS + 1)
282243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	int flags = (MALLOCX_ARENA(0) | MALLOCX_TCACHE_NONE);
283243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	void *ps[NPS];
284243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	uint64_t epoch, npurge0, npurge1;
285243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	size_t sz, large0;
286243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	unsigned i, nupdates0;
287243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
288243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	test_skip_if(opt_purge != purge_mode_decay);
289243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
290243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	sz = sizeof(size_t);
291243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(mallctl("arenas.lrun.0.size", &large0, &sz, NULL, 0), 0,
292243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected mallctl failure");
293243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
294243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
295243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected mallctl failure");
296243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(uint64_t)), 0,
297243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected mallctl failure");
298243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	sz = sizeof(uint64_t);
299243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge0, &sz, NULL, 0), 0,
300243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected mallctl failure");
301243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
302243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	nupdates_mock = 0;
3039bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_init(&time_mock, 0);
3049bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_update(&time_mock);
305243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	nonmonotonic_mock = true;
306243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
3079bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_update_orig = nstime_update;
3089bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_update = nstime_update_mock;
309243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
310243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	for (i = 0; i < NPS; i++) {
311243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		ps[i] = mallocx(large0, flags);
312243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		assert_ptr_not_null(ps[i], "Unexpected mallocx() failure");
313243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	}
314243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
315243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	for (i = 0; i < NPS; i++) {
316243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		dallocx(ps[i], flags);
317243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		nupdates0 = nupdates_mock;
318243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		assert_d_eq(mallctl("arena.0.decay", NULL, NULL, NULL, 0), 0,
319243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		    "Unexpected arena.0.decay failure");
320243f7a0508bb014c2a7bf592c466a923911db234Jason Evans		assert_u_gt(nupdates_mock, nupdates0,
3219bad07903962962de9f656d281b9b1e7e9501c87Jason Evans		    "Expected nstime_update() to be called");
322243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	}
323243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
324243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(uint64_t)), 0,
325243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected mallctl failure");
326243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	sz = sizeof(uint64_t);
327243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge1, &sz, NULL, 0), 0,
328243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    "Unexpected mallctl failure");
329243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
330243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	assert_u64_gt(npurge1, npurge0, "Expected purging to occur");
331243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
3329bad07903962962de9f656d281b9b1e7e9501c87Jason Evans	nstime_update = nstime_update_orig;
333243f7a0508bb014c2a7bf592c466a923911db234Jason Evans#undef NPS
334243f7a0508bb014c2a7bf592c466a923911db234Jason Evans}
335243f7a0508bb014c2a7bf592c466a923911db234Jason EvansTEST_END
336243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
337243f7a0508bb014c2a7bf592c466a923911db234Jason Evansint
338243f7a0508bb014c2a7bf592c466a923911db234Jason Evansmain(void)
339243f7a0508bb014c2a7bf592c466a923911db234Jason Evans{
340243f7a0508bb014c2a7bf592c466a923911db234Jason Evans
341243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	return (test(
342243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    test_decay_ticks,
343243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    test_decay_ticker,
344243f7a0508bb014c2a7bf592c466a923911db234Jason Evans	    test_decay_nonmonotonic));
345243f7a0508bb014c2a7bf592c466a923911db234Jason Evans}
346