1dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans#include "test/jemalloc_test.h"
2dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
3dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evansstatic size_t
4dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evansget_max_size_class(void)
5dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans{
6dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	unsigned nhchunks;
7dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	size_t mib[4];
8dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	size_t sz, miblen, max_size_class;
9dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
10dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	sz = sizeof(unsigned);
118f61fdedb908c29905103b22dda32ceb29cd8edeJason Evans	assert_d_eq(mallctl("arenas.nhchunks", (void *)&nhchunks, &sz, NULL, 0),
128f61fdedb908c29905103b22dda32ceb29cd8edeJason Evans	    0, "Unexpected mallctl() error");
13dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
14dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	miblen = sizeof(mib) / sizeof(size_t);
15dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	assert_d_eq(mallctlnametomib("arenas.hchunk.0.size", mib, &miblen), 0,
16dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	    "Unexpected mallctlnametomib() error");
17dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	mib[2] = nhchunks - 1;
18dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
19dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	sz = sizeof(size_t);
208f61fdedb908c29905103b22dda32ceb29cd8edeJason Evans	assert_d_eq(mallctlbymib(mib, miblen, (void *)&max_size_class, &sz,
218f61fdedb908c29905103b22dda32ceb29cd8edeJason Evans	    NULL, 0), 0, "Unexpected mallctlbymib() error");
22dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
23dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	return (max_size_class);
24dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans}
25dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
26dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason EvansTEST_BEGIN(test_size_classes)
27dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans{
28dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	size_t size_class, max_size_class;
29d01fd19755bc0c2f5be3143349016dd0d7de7b36Jason Evans	szind_t index, max_index;
30dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
31dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	max_size_class = get_max_size_class();
32dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	max_index = size2index(max_size_class);
33dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
34dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	for (index = 0, size_class = index2size(index); index < max_index ||
35dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	    size_class < max_size_class; index++, size_class =
36dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	    index2size(index)) {
37dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		assert_true(index < max_index,
38dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    "Loop conditionals should be equivalent; index=%u, "
39dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    "size_class=%zu (%#zx)", index, size_class, size_class);
40dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		assert_true(size_class < max_size_class,
41dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    "Loop conditionals should be equivalent; index=%u, "
42dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    "size_class=%zu (%#zx)", index, size_class, size_class);
43dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
44dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		assert_u_eq(index, size2index(size_class),
45dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    "size2index() does not reverse index2size(): index=%u -->"
46dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    " size_class=%zu --> index=%u --> size_class=%zu", index,
47dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    size_class, size2index(size_class),
48dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    index2size(size2index(size_class)));
49dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		assert_zu_eq(size_class, index2size(size2index(size_class)),
50dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    "index2size() does not reverse size2index(): index=%u -->"
51dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    " size_class=%zu --> index=%u --> size_class=%zu", index,
52dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    size_class, size2index(size_class),
53dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    index2size(size2index(size_class)));
54dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
55dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		assert_u_eq(index+1, size2index(size_class+1),
56dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    "Next size_class does not round up properly");
57dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
58dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		assert_zu_eq(size_class, (index > 0) ?
59dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    s2u(index2size(index-1)+1) : s2u(1),
60dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    "s2u() does not round up to size class");
61dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		assert_zu_eq(size_class, s2u(size_class-1),
62dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    "s2u() does not round up to size class");
63dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		assert_zu_eq(size_class, s2u(size_class),
64dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    "s2u() does not compute same size class");
65dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		assert_zu_eq(s2u(size_class+1), index2size(index+1),
66dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans		    "s2u() does not round up to next size class");
67dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	}
68dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
69dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	assert_u_eq(index, size2index(index2size(index)),
70dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	    "size2index() does not reverse index2size()");
71dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	assert_zu_eq(max_size_class, index2size(size2index(max_size_class)),
72dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	    "index2size() does not reverse size2index()");
73dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
74dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	assert_zu_eq(size_class, s2u(index2size(index-1)+1),
75dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	    "s2u() does not round up to size class");
76dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	assert_zu_eq(size_class, s2u(size_class-1),
77dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	    "s2u() does not round up to size class");
78dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	assert_zu_eq(size_class, s2u(size_class),
79dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	    "s2u() does not compute same size class");
80dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans}
81dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason EvansTEST_END
82dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
831abb49f09d98e265ad92a831a056ccdfb4cf6041Jason EvansTEST_BEGIN(test_psize_classes)
841abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans{
851abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	size_t size_class, max_size_class;
861abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	pszind_t pind, max_pind;
871abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans
881abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	max_size_class = get_max_size_class();
891abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	max_pind = psz2ind(max_size_class);
901abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans
911abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	for (pind = 0, size_class = pind2sz(pind); pind < max_pind ||
921abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    size_class < max_size_class; pind++, size_class =
931abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    pind2sz(pind)) {
941abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		assert_true(pind < max_pind,
951abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    "Loop conditionals should be equivalent; pind=%u, "
961abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    "size_class=%zu (%#zx)", pind, size_class, size_class);
971abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		assert_true(size_class < max_size_class,
981abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    "Loop conditionals should be equivalent; pind=%u, "
991abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    "size_class=%zu (%#zx)", pind, size_class, size_class);
1001abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans
1011abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		assert_u_eq(pind, psz2ind(size_class),
1021abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    "psz2ind() does not reverse pind2sz(): pind=%u -->"
1031abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    " size_class=%zu --> pind=%u --> size_class=%zu", pind,
1041abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    size_class, psz2ind(size_class),
1051abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    pind2sz(psz2ind(size_class)));
1061abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		assert_zu_eq(size_class, pind2sz(psz2ind(size_class)),
1071abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    "pind2sz() does not reverse psz2ind(): pind=%u -->"
1081abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    " size_class=%zu --> pind=%u --> size_class=%zu", pind,
1091abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    size_class, psz2ind(size_class),
1101abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    pind2sz(psz2ind(size_class)));
1111abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans
1121abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		assert_u_eq(pind+1, psz2ind(size_class+1),
1131abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    "Next size_class does not round up properly");
1141abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans
1151abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		assert_zu_eq(size_class, (pind > 0) ?
1161abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    psz2u(pind2sz(pind-1)+1) : psz2u(1),
1171abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    "psz2u() does not round up to size class");
1181abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		assert_zu_eq(size_class, psz2u(size_class-1),
1191abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    "psz2u() does not round up to size class");
1201abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		assert_zu_eq(size_class, psz2u(size_class),
1211abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    "psz2u() does not compute same size class");
1221abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		assert_zu_eq(psz2u(size_class+1), pind2sz(pind+1),
1231abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans		    "psz2u() does not round up to next size class");
1241abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	}
1251abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans
1261abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_u_eq(pind, psz2ind(pind2sz(pind)),
1271abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "psz2ind() does not reverse pind2sz()");
1281abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_zu_eq(max_size_class, pind2sz(psz2ind(max_size_class)),
1291abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "pind2sz() does not reverse psz2ind()");
1301abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans
1311abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_zu_eq(size_class, psz2u(pind2sz(pind-1)+1),
1321abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "psz2u() does not round up to size class");
1331abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_zu_eq(size_class, psz2u(size_class-1),
1341abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "psz2u() does not round up to size class");
1351abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_zu_eq(size_class, psz2u(size_class),
1361abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "psz2u() does not compute same size class");
1371abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans}
1381abb49f09d98e265ad92a831a056ccdfb4cf6041Jason EvansTEST_END
1391abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans
1400c516a00c4cb28cff55ce0995f756b5aae074c9eJason EvansTEST_BEGIN(test_overflow)
1410c516a00c4cb28cff55ce0995f756b5aae074c9eJason Evans{
1420c516a00c4cb28cff55ce0995f756b5aae074c9eJason Evans	size_t max_size_class;
1430c516a00c4cb28cff55ce0995f756b5aae074c9eJason Evans
1440c516a00c4cb28cff55ce0995f756b5aae074c9eJason Evans	max_size_class = get_max_size_class();
1450c516a00c4cb28cff55ce0995f756b5aae074c9eJason Evans
1461abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_u_eq(size2index(max_size_class+1), NSIZES,
1471abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "size2index() should return NSIZES on overflow");
1481abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_u_eq(size2index(ZU(PTRDIFF_MAX)+1), NSIZES,
1491abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "size2index() should return NSIZES on overflow");
1501abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_u_eq(size2index(SIZE_T_MAX), NSIZES,
1511abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "size2index() should return NSIZES on overflow");
1521abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans
1531abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_zu_eq(s2u(max_size_class+1), 0,
1541abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "s2u() should return 0 for unsupported size");
1551abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_zu_eq(s2u(ZU(PTRDIFF_MAX)+1), 0,
1561abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "s2u() should return 0 for unsupported size");
1570c516a00c4cb28cff55ce0995f756b5aae074c9eJason Evans	assert_zu_eq(s2u(SIZE_T_MAX), 0,
1580c516a00c4cb28cff55ce0995f756b5aae074c9eJason Evans	    "s2u() should return 0 on overflow");
1591abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans
1601abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_u_eq(psz2ind(max_size_class+1), NPSIZES,
1611abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "psz2ind() should return NPSIZES on overflow");
1621abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_u_eq(psz2ind(ZU(PTRDIFF_MAX)+1), NPSIZES,
1631abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "psz2ind() should return NPSIZES on overflow");
1641abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_u_eq(psz2ind(SIZE_T_MAX), NPSIZES,
1651abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "psz2ind() should return NPSIZES on overflow");
1661abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans
1671abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_zu_eq(psz2u(max_size_class+1), 0,
1681abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "psz2u() should return 0 for unsupported size");
1691abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_zu_eq(psz2u(ZU(PTRDIFF_MAX)+1), 0,
1701abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "psz2u() should return 0 for unsupported size");
1711abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	assert_zu_eq(psz2u(SIZE_T_MAX), 0,
1721abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    "psz2u() should return 0 on overflow");
1730c516a00c4cb28cff55ce0995f756b5aae074c9eJason Evans}
1740c516a00c4cb28cff55ce0995f756b5aae074c9eJason EvansTEST_END
1750c516a00c4cb28cff55ce0995f756b5aae074c9eJason Evans
176dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evansint
177dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evansmain(void)
178dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans{
179dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans
180dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans	return (test(
1810c516a00c4cb28cff55ce0995f756b5aae074c9eJason Evans	    test_size_classes,
1821abb49f09d98e265ad92a831a056ccdfb4cf6041Jason Evans	    test_psize_classes,
1830c516a00c4cb28cff55ce0995f756b5aae074c9eJason Evans	    test_overflow));
184dde067264db6b801f7ffae9616a35dba5d2d9ad4Jason Evans}
185