1 1.1 christos #include "test/jemalloc_test.h" 2 1.1 christos 3 1.1 christos static size_t 4 1.1 christos get_max_size_class(void) { 5 1.1 christos unsigned nlextents; 6 1.1 christos size_t mib[4]; 7 1.1 christos size_t sz, miblen, max_size_class; 8 1.1 christos 9 1.1 christos sz = sizeof(unsigned); 10 1.1.1.2 christos expect_d_eq(mallctl("arenas.nlextents", (void *)&nlextents, &sz, NULL, 11 1.1 christos 0), 0, "Unexpected mallctl() error"); 12 1.1 christos 13 1.1 christos miblen = sizeof(mib) / sizeof(size_t); 14 1.1.1.2 christos expect_d_eq(mallctlnametomib("arenas.lextent.0.size", mib, &miblen), 0, 15 1.1 christos "Unexpected mallctlnametomib() error"); 16 1.1 christos mib[2] = nlextents - 1; 17 1.1 christos 18 1.1 christos sz = sizeof(size_t); 19 1.1.1.2 christos expect_d_eq(mallctlbymib(mib, miblen, (void *)&max_size_class, &sz, 20 1.1 christos NULL, 0), 0, "Unexpected mallctlbymib() error"); 21 1.1 christos 22 1.1 christos return max_size_class; 23 1.1 christos } 24 1.1 christos 25 1.1 christos TEST_BEGIN(test_size_classes) { 26 1.1 christos size_t size_class, max_size_class; 27 1.1 christos szind_t index, max_index; 28 1.1 christos 29 1.1 christos max_size_class = get_max_size_class(); 30 1.1 christos max_index = sz_size2index(max_size_class); 31 1.1 christos 32 1.1 christos for (index = 0, size_class = sz_index2size(index); index < max_index || 33 1.1 christos size_class < max_size_class; index++, size_class = 34 1.1 christos sz_index2size(index)) { 35 1.1.1.2 christos expect_true(index < max_index, 36 1.1 christos "Loop conditionals should be equivalent; index=%u, " 37 1.1 christos "size_class=%zu (%#zx)", index, size_class, size_class); 38 1.1.1.2 christos expect_true(size_class < max_size_class, 39 1.1 christos "Loop conditionals should be equivalent; index=%u, " 40 1.1 christos "size_class=%zu (%#zx)", index, size_class, size_class); 41 1.1 christos 42 1.1.1.2 christos expect_u_eq(index, sz_size2index(size_class), 43 1.1 christos "sz_size2index() does not reverse sz_index2size(): index=%u" 44 1.1 christos " --> size_class=%zu --> index=%u --> size_class=%zu", 45 1.1 christos index, size_class, sz_size2index(size_class), 46 1.1 christos sz_index2size(sz_size2index(size_class))); 47 1.1.1.2 christos expect_zu_eq(size_class, 48 1.1 christos sz_index2size(sz_size2index(size_class)), 49 1.1 christos "sz_index2size() does not reverse sz_size2index(): index=%u" 50 1.1 christos " --> size_class=%zu --> index=%u --> size_class=%zu", 51 1.1 christos index, size_class, sz_size2index(size_class), 52 1.1 christos sz_index2size(sz_size2index(size_class))); 53 1.1 christos 54 1.1.1.2 christos expect_u_eq(index+1, sz_size2index(size_class+1), 55 1.1 christos "Next size_class does not round up properly"); 56 1.1 christos 57 1.1.1.2 christos expect_zu_eq(size_class, (index > 0) ? 58 1.1 christos sz_s2u(sz_index2size(index-1)+1) : sz_s2u(1), 59 1.1 christos "sz_s2u() does not round up to size class"); 60 1.1.1.2 christos expect_zu_eq(size_class, sz_s2u(size_class-1), 61 1.1 christos "sz_s2u() does not round up to size class"); 62 1.1.1.2 christos expect_zu_eq(size_class, sz_s2u(size_class), 63 1.1 christos "sz_s2u() does not compute same size class"); 64 1.1.1.2 christos expect_zu_eq(sz_s2u(size_class+1), sz_index2size(index+1), 65 1.1 christos "sz_s2u() does not round up to next size class"); 66 1.1 christos } 67 1.1 christos 68 1.1.1.2 christos expect_u_eq(index, sz_size2index(sz_index2size(index)), 69 1.1 christos "sz_size2index() does not reverse sz_index2size()"); 70 1.1.1.2 christos expect_zu_eq(max_size_class, sz_index2size( 71 1.1 christos sz_size2index(max_size_class)), 72 1.1 christos "sz_index2size() does not reverse sz_size2index()"); 73 1.1 christos 74 1.1.1.2 christos expect_zu_eq(size_class, sz_s2u(sz_index2size(index-1)+1), 75 1.1 christos "sz_s2u() does not round up to size class"); 76 1.1.1.2 christos expect_zu_eq(size_class, sz_s2u(size_class-1), 77 1.1 christos "sz_s2u() does not round up to size class"); 78 1.1.1.2 christos expect_zu_eq(size_class, sz_s2u(size_class), 79 1.1 christos "sz_s2u() does not compute same size class"); 80 1.1 christos } 81 1.1 christos TEST_END 82 1.1 christos 83 1.1 christos TEST_BEGIN(test_psize_classes) { 84 1.1 christos size_t size_class, max_psz; 85 1.1 christos pszind_t pind, max_pind; 86 1.1 christos 87 1.1 christos max_psz = get_max_size_class() + PAGE; 88 1.1 christos max_pind = sz_psz2ind(max_psz); 89 1.1 christos 90 1.1 christos for (pind = 0, size_class = sz_pind2sz(pind); 91 1.1 christos pind < max_pind || size_class < max_psz; 92 1.1 christos pind++, size_class = sz_pind2sz(pind)) { 93 1.1.1.2 christos expect_true(pind < max_pind, 94 1.1 christos "Loop conditionals should be equivalent; pind=%u, " 95 1.1 christos "size_class=%zu (%#zx)", pind, size_class, size_class); 96 1.1.1.2 christos expect_true(size_class < max_psz, 97 1.1 christos "Loop conditionals should be equivalent; pind=%u, " 98 1.1 christos "size_class=%zu (%#zx)", pind, size_class, size_class); 99 1.1 christos 100 1.1.1.2 christos expect_u_eq(pind, sz_psz2ind(size_class), 101 1.1 christos "sz_psz2ind() does not reverse sz_pind2sz(): pind=%u -->" 102 1.1 christos " size_class=%zu --> pind=%u --> size_class=%zu", pind, 103 1.1 christos size_class, sz_psz2ind(size_class), 104 1.1 christos sz_pind2sz(sz_psz2ind(size_class))); 105 1.1.1.2 christos expect_zu_eq(size_class, sz_pind2sz(sz_psz2ind(size_class)), 106 1.1 christos "sz_pind2sz() does not reverse sz_psz2ind(): pind=%u -->" 107 1.1 christos " size_class=%zu --> pind=%u --> size_class=%zu", pind, 108 1.1 christos size_class, sz_psz2ind(size_class), 109 1.1 christos sz_pind2sz(sz_psz2ind(size_class))); 110 1.1 christos 111 1.1.1.2 christos if (size_class == SC_LARGE_MAXCLASS) { 112 1.1.1.2 christos expect_u_eq(SC_NPSIZES, sz_psz2ind(size_class + 1), 113 1.1.1.2 christos "Next size_class does not round up properly"); 114 1.1.1.2 christos } else { 115 1.1.1.2 christos expect_u_eq(pind + 1, sz_psz2ind(size_class + 1), 116 1.1.1.2 christos "Next size_class does not round up properly"); 117 1.1.1.2 christos } 118 1.1 christos 119 1.1.1.2 christos expect_zu_eq(size_class, (pind > 0) ? 120 1.1 christos sz_psz2u(sz_pind2sz(pind-1)+1) : sz_psz2u(1), 121 1.1 christos "sz_psz2u() does not round up to size class"); 122 1.1.1.2 christos expect_zu_eq(size_class, sz_psz2u(size_class-1), 123 1.1 christos "sz_psz2u() does not round up to size class"); 124 1.1.1.2 christos expect_zu_eq(size_class, sz_psz2u(size_class), 125 1.1 christos "sz_psz2u() does not compute same size class"); 126 1.1.1.2 christos expect_zu_eq(sz_psz2u(size_class+1), sz_pind2sz(pind+1), 127 1.1 christos "sz_psz2u() does not round up to next size class"); 128 1.1 christos } 129 1.1 christos 130 1.1.1.2 christos expect_u_eq(pind, sz_psz2ind(sz_pind2sz(pind)), 131 1.1 christos "sz_psz2ind() does not reverse sz_pind2sz()"); 132 1.1.1.2 christos expect_zu_eq(max_psz, sz_pind2sz(sz_psz2ind(max_psz)), 133 1.1 christos "sz_pind2sz() does not reverse sz_psz2ind()"); 134 1.1 christos 135 1.1.1.2 christos expect_zu_eq(size_class, sz_psz2u(sz_pind2sz(pind-1)+1), 136 1.1 christos "sz_psz2u() does not round up to size class"); 137 1.1.1.2 christos expect_zu_eq(size_class, sz_psz2u(size_class-1), 138 1.1 christos "sz_psz2u() does not round up to size class"); 139 1.1.1.2 christos expect_zu_eq(size_class, sz_psz2u(size_class), 140 1.1 christos "sz_psz2u() does not compute same size class"); 141 1.1 christos } 142 1.1 christos TEST_END 143 1.1 christos 144 1.1 christos TEST_BEGIN(test_overflow) { 145 1.1 christos size_t max_size_class, max_psz; 146 1.1 christos 147 1.1 christos max_size_class = get_max_size_class(); 148 1.1 christos max_psz = max_size_class + PAGE; 149 1.1 christos 150 1.1.1.2 christos expect_u_eq(sz_size2index(max_size_class+1), SC_NSIZES, 151 1.1 christos "sz_size2index() should return NSIZES on overflow"); 152 1.1.1.2 christos expect_u_eq(sz_size2index(ZU(PTRDIFF_MAX)+1), SC_NSIZES, 153 1.1 christos "sz_size2index() should return NSIZES on overflow"); 154 1.1.1.2 christos expect_u_eq(sz_size2index(SIZE_T_MAX), SC_NSIZES, 155 1.1 christos "sz_size2index() should return NSIZES on overflow"); 156 1.1 christos 157 1.1.1.2 christos expect_zu_eq(sz_s2u(max_size_class+1), 0, 158 1.1 christos "sz_s2u() should return 0 for unsupported size"); 159 1.1.1.2 christos expect_zu_eq(sz_s2u(ZU(PTRDIFF_MAX)+1), 0, 160 1.1 christos "sz_s2u() should return 0 for unsupported size"); 161 1.1.1.2 christos expect_zu_eq(sz_s2u(SIZE_T_MAX), 0, 162 1.1 christos "sz_s2u() should return 0 on overflow"); 163 1.1 christos 164 1.1.1.2 christos expect_u_eq(sz_psz2ind(max_size_class+1), SC_NPSIZES, 165 1.1 christos "sz_psz2ind() should return NPSIZES on overflow"); 166 1.1.1.2 christos expect_u_eq(sz_psz2ind(ZU(PTRDIFF_MAX)+1), SC_NPSIZES, 167 1.1 christos "sz_psz2ind() should return NPSIZES on overflow"); 168 1.1.1.2 christos expect_u_eq(sz_psz2ind(SIZE_T_MAX), SC_NPSIZES, 169 1.1 christos "sz_psz2ind() should return NPSIZES on overflow"); 170 1.1 christos 171 1.1.1.2 christos expect_zu_eq(sz_psz2u(max_size_class+1), max_psz, 172 1.1 christos "sz_psz2u() should return (LARGE_MAXCLASS + PAGE) for unsupported" 173 1.1 christos " size"); 174 1.1.1.2 christos expect_zu_eq(sz_psz2u(ZU(PTRDIFF_MAX)+1), max_psz, 175 1.1 christos "sz_psz2u() should return (LARGE_MAXCLASS + PAGE) for unsupported " 176 1.1 christos "size"); 177 1.1.1.2 christos expect_zu_eq(sz_psz2u(SIZE_T_MAX), max_psz, 178 1.1 christos "sz_psz2u() should return (LARGE_MAXCLASS + PAGE) on overflow"); 179 1.1 christos } 180 1.1 christos TEST_END 181 1.1 christos 182 1.1 christos int 183 1.1 christos main(void) { 184 1.1 christos return test( 185 1.1 christos test_size_classes, 186 1.1 christos test_psize_classes, 187 1.1 christos test_overflow); 188 1.1 christos } 189