Home | History | Annotate | Download | only in integration
      1 #include "test/jemalloc_test.h"
      2 
      3 static unsigned
      4 get_nsizes_impl(const char *cmd)
      5 {
      6 	unsigned ret;
      7 	size_t z;
      8 
      9 	z = sizeof(unsigned);
     10 	assert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0,
     11 	    "Unexpected mallctl(\"%s\", ...) failure", cmd);
     12 
     13 	return (ret);
     14 }
     15 
     16 static unsigned
     17 get_nhuge(void)
     18 {
     19 
     20 	return (get_nsizes_impl("arenas.nhchunks"));
     21 }
     22 
     23 static size_t
     24 get_size_impl(const char *cmd, size_t ind)
     25 {
     26 	size_t ret;
     27 	size_t z;
     28 	size_t mib[4];
     29 	size_t miblen = 4;
     30 
     31 	z = sizeof(size_t);
     32 	assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
     33 	    0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
     34 	mib[2] = ind;
     35 	z = sizeof(size_t);
     36 	assert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0),
     37 	    0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
     38 
     39 	return (ret);
     40 }
     41 
     42 static size_t
     43 get_huge_size(size_t ind)
     44 {
     45 
     46 	return (get_size_impl("arenas.hchunk.0.size", ind));
     47 }
     48 
     49 TEST_BEGIN(test_overflow)
     50 {
     51 	size_t hugemax;
     52 
     53 	hugemax = get_huge_size(get_nhuge()-1);
     54 
     55 	assert_ptr_null(mallocx(hugemax+1, 0),
     56 	    "Expected OOM for mallocx(size=%#zx, 0)", hugemax+1);
     57 
     58 	assert_ptr_null(mallocx(ZU(PTRDIFF_MAX)+1, 0),
     59 	    "Expected OOM for mallocx(size=%#zx, 0)", ZU(PTRDIFF_MAX)+1);
     60 
     61 	assert_ptr_null(mallocx(SIZE_T_MAX, 0),
     62 	    "Expected OOM for mallocx(size=%#zx, 0)", SIZE_T_MAX);
     63 
     64 	assert_ptr_null(mallocx(1, MALLOCX_ALIGN(ZU(PTRDIFF_MAX)+1)),
     65 	    "Expected OOM for mallocx(size=1, MALLOCX_ALIGN(%#zx))",
     66 	    ZU(PTRDIFF_MAX)+1);
     67 }
     68 TEST_END
     69 
     70 TEST_BEGIN(test_oom)
     71 {
     72 	size_t hugemax, size, alignment;
     73 
     74 	hugemax = get_huge_size(get_nhuge()-1);
     75 
     76 	/*
     77 	 * It should be impossible to allocate two objects that each consume
     78 	 * more than half the virtual address space.
     79 	 */
     80 	{
     81 		void *p;
     82 
     83 		p = mallocx(hugemax, 0);
     84 		if (p != NULL) {
     85 			assert_ptr_null(mallocx(hugemax, 0),
     86 			    "Expected OOM for mallocx(size=%#zx, 0)", hugemax);
     87 			dallocx(p, 0);
     88 		}
     89 	}
     90 
     91 #if LG_SIZEOF_PTR == 3
     92 	size      = ZU(0x8000000000000000);
     93 	alignment = ZU(0x8000000000000000);
     94 #else
     95 	size      = ZU(0x80000000);
     96 	alignment = ZU(0x80000000);
     97 #endif
     98 	assert_ptr_null(mallocx(size, MALLOCX_ALIGN(alignment)),
     99 	    "Expected OOM for mallocx(size=%#zx, MALLOCX_ALIGN(%#zx)", size,
    100 	    alignment);
    101 }
    102 TEST_END
    103 
    104 TEST_BEGIN(test_basic)
    105 {
    106 #define	MAXSZ (((size_t)1) << 26)
    107 	size_t sz;
    108 
    109 	for (sz = 1; sz < MAXSZ; sz = nallocx(sz, 0) + 1) {
    110 		size_t nsz, rsz;
    111 		void *p;
    112 		nsz = nallocx(sz, 0);
    113 		assert_zu_ne(nsz, 0, "Unexpected nallocx() error");
    114 		p = mallocx(sz, 0);
    115 		assert_ptr_not_null(p, "Unexpected mallocx() error");
    116 		rsz = sallocx(p, 0);
    117 		assert_zu_ge(rsz, sz, "Real size smaller than expected");
    118 		assert_zu_eq(nsz, rsz, "nallocx()/sallocx() size mismatch");
    119 		dallocx(p, 0);
    120 
    121 		p = mallocx(sz, 0);
    122 		assert_ptr_not_null(p, "Unexpected mallocx() error");
    123 		dallocx(p, 0);
    124 
    125 		nsz = nallocx(sz, MALLOCX_ZERO);
    126 		assert_zu_ne(nsz, 0, "Unexpected nallocx() error");
    127 		p = mallocx(sz, MALLOCX_ZERO);
    128 		assert_ptr_not_null(p, "Unexpected mallocx() error");
    129 		rsz = sallocx(p, 0);
    130 		assert_zu_eq(nsz, rsz, "nallocx()/sallocx() rsize mismatch");
    131 		dallocx(p, 0);
    132 	}
    133 #undef MAXSZ
    134 }
    135 TEST_END
    136 
    137 TEST_BEGIN(test_alignment_and_size)
    138 {
    139 #define	MAXALIGN (((size_t)1) << 25)
    140 #define	NITER 4
    141 	size_t nsz, rsz, sz, alignment, total;
    142 	unsigned i;
    143 	void *ps[NITER];
    144 
    145 	for (i = 0; i < NITER; i++)
    146 		ps[i] = NULL;
    147 
    148 	for (alignment = 8;
    149 	    alignment <= MAXALIGN;
    150 	    alignment <<= 1) {
    151 		total = 0;
    152 		for (sz = 1;
    153 		    sz < 3 * alignment && sz < (1U << 31);
    154 		    sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
    155 			for (i = 0; i < NITER; i++) {
    156 				nsz = nallocx(sz, MALLOCX_ALIGN(alignment) |
    157 				    MALLOCX_ZERO);
    158 				assert_zu_ne(nsz, 0,
    159 				    "nallocx() error for alignment=%zu, "
    160 				    "size=%zu (%#zx)", alignment, sz, sz);
    161 				ps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) |
    162 				    MALLOCX_ZERO);
    163 				assert_ptr_not_null(ps[i],
    164 				    "mallocx() error for alignment=%zu, "
    165 				    "size=%zu (%#zx)", alignment, sz, sz);
    166 				rsz = sallocx(ps[i], 0);
    167 				assert_zu_ge(rsz, sz,
    168 				    "Real size smaller than expected for "
    169 				    "alignment=%zu, size=%zu", alignment, sz);
    170 				assert_zu_eq(nsz, rsz,
    171 				    "nallocx()/sallocx() size mismatch for "
    172 				    "alignment=%zu, size=%zu", alignment, sz);
    173 				assert_ptr_null(
    174 				    (void *)((uintptr_t)ps[i] & (alignment-1)),
    175 				    "%p inadequately aligned for"
    176 				    " alignment=%zu, size=%zu", ps[i],
    177 				    alignment, sz);
    178 				total += rsz;
    179 				if (total >= (MAXALIGN << 1))
    180 					break;
    181 			}
    182 			for (i = 0; i < NITER; i++) {
    183 				if (ps[i] != NULL) {
    184 					dallocx(ps[i], 0);
    185 					ps[i] = NULL;
    186 				}
    187 			}
    188 		}
    189 	}
    190 #undef MAXALIGN
    191 #undef NITER
    192 }
    193 TEST_END
    194 
    195 int
    196 main(void)
    197 {
    198 
    199 	return (test(
    200 	    test_overflow,
    201 	    test_oom,
    202 	    test_basic,
    203 	    test_alignment_and_size));
    204 }
    205