Home | History | Annotate | Line # | Download | only in integration
      1  1.1  christos #include "test/jemalloc_test.h"
      2  1.1  christos 
      3  1.1  christos static unsigned
      4  1.1  christos get_nsizes_impl(const char *cmd) {
      5  1.1  christos 	unsigned ret;
      6  1.1  christos 	size_t z;
      7  1.1  christos 
      8  1.1  christos 	z = sizeof(unsigned);
      9  1.1  christos 	assert_d_eq(mallctl(cmd, (void *)&ret, &z, NULL, 0), 0,
     10  1.1  christos 	    "Unexpected mallctl(\"%s\", ...) failure", cmd);
     11  1.1  christos 
     12  1.1  christos 	return ret;
     13  1.1  christos }
     14  1.1  christos 
     15  1.1  christos static unsigned
     16  1.1  christos get_nlarge(void) {
     17  1.1  christos 	return get_nsizes_impl("arenas.nlextents");
     18  1.1  christos }
     19  1.1  christos 
     20  1.1  christos static size_t
     21  1.1  christos get_size_impl(const char *cmd, size_t ind) {
     22  1.1  christos 	size_t ret;
     23  1.1  christos 	size_t z;
     24  1.1  christos 	size_t mib[4];
     25  1.1  christos 	size_t miblen = 4;
     26  1.1  christos 
     27  1.1  christos 	z = sizeof(size_t);
     28  1.1  christos 	assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
     29  1.1  christos 	    0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
     30  1.1  christos 	mib[2] = ind;
     31  1.1  christos 	z = sizeof(size_t);
     32  1.1  christos 	assert_d_eq(mallctlbymib(mib, miblen, (void *)&ret, &z, NULL, 0),
     33  1.1  christos 	    0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
     34  1.1  christos 
     35  1.1  christos 	return ret;
     36  1.1  christos }
     37  1.1  christos 
     38  1.1  christos static size_t
     39  1.1  christos get_large_size(size_t ind) {
     40  1.1  christos 	return get_size_impl("arenas.lextent.0.size", ind);
     41  1.1  christos }
     42  1.1  christos 
     43  1.1  christos /*
     44  1.1  christos  * On systems which can't merge extents, tests that call this function generate
     45  1.1  christos  * a lot of dirty memory very quickly.  Purging between cycles mitigates
     46  1.1  christos  * potential OOM on e.g. 32-bit Windows.
     47  1.1  christos  */
     48  1.1  christos static void
     49  1.1  christos purge(void) {
     50  1.1  christos 	assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
     51  1.1  christos 	    "Unexpected mallctl error");
     52  1.1  christos }
     53  1.1  christos 
     54  1.1  christos TEST_BEGIN(test_overflow) {
     55  1.1  christos 	size_t largemax;
     56  1.1  christos 
     57  1.1  christos 	largemax = get_large_size(get_nlarge()-1);
     58  1.1  christos 
     59  1.1  christos 	assert_ptr_null(mallocx(largemax+1, 0),
     60  1.1  christos 	    "Expected OOM for mallocx(size=%#zx, 0)", largemax+1);
     61  1.1  christos 
     62  1.1  christos 	assert_ptr_null(mallocx(ZU(PTRDIFF_MAX)+1, 0),
     63  1.1  christos 	    "Expected OOM for mallocx(size=%#zx, 0)", ZU(PTRDIFF_MAX)+1);
     64  1.1  christos 
     65  1.1  christos 	assert_ptr_null(mallocx(SIZE_T_MAX, 0),
     66  1.1  christos 	    "Expected OOM for mallocx(size=%#zx, 0)", SIZE_T_MAX);
     67  1.1  christos 
     68  1.1  christos 	assert_ptr_null(mallocx(1, MALLOCX_ALIGN(ZU(PTRDIFF_MAX)+1)),
     69  1.1  christos 	    "Expected OOM for mallocx(size=1, MALLOCX_ALIGN(%#zx))",
     70  1.1  christos 	    ZU(PTRDIFF_MAX)+1);
     71  1.1  christos }
     72  1.1  christos TEST_END
     73  1.1  christos 
     74  1.1  christos TEST_BEGIN(test_oom) {
     75  1.1  christos 	size_t largemax;
     76  1.1  christos 	bool oom;
     77  1.1  christos 	void *ptrs[3];
     78  1.1  christos 	unsigned i;
     79  1.1  christos 
     80  1.1  christos 	/*
     81  1.1  christos 	 * It should be impossible to allocate three objects that each consume
     82  1.1  christos 	 * nearly half the virtual address space.
     83  1.1  christos 	 */
     84  1.1  christos 	largemax = get_large_size(get_nlarge()-1);
     85  1.1  christos 	oom = false;
     86  1.1  christos 	for (i = 0; i < sizeof(ptrs) / sizeof(void *); i++) {
     87  1.1  christos 		ptrs[i] = mallocx(largemax, 0);
     88  1.1  christos 		if (ptrs[i] == NULL) {
     89  1.1  christos 			oom = true;
     90  1.1  christos 		}
     91  1.1  christos 	}
     92  1.1  christos 	assert_true(oom,
     93  1.1  christos 	    "Expected OOM during series of calls to mallocx(size=%zu, 0)",
     94  1.1  christos 	    largemax);
     95  1.1  christos 	for (i = 0; i < sizeof(ptrs) / sizeof(void *); i++) {
     96  1.1  christos 		if (ptrs[i] != NULL) {
     97  1.1  christos 			dallocx(ptrs[i], 0);
     98  1.1  christos 		}
     99  1.1  christos 	}
    100  1.1  christos 	purge();
    101  1.1  christos 
    102  1.1  christos #if LG_SIZEOF_PTR == 3
    103  1.1  christos 	assert_ptr_null(mallocx(0x8000000000000000ULL,
    104  1.1  christos 	    MALLOCX_ALIGN(0x8000000000000000ULL)),
    105  1.1  christos 	    "Expected OOM for mallocx()");
    106  1.1  christos 	assert_ptr_null(mallocx(0x8000000000000000ULL,
    107  1.1  christos 	    MALLOCX_ALIGN(0x80000000)),
    108  1.1  christos 	    "Expected OOM for mallocx()");
    109  1.1  christos #else
    110  1.1  christos 	assert_ptr_null(mallocx(0x80000000UL, MALLOCX_ALIGN(0x80000000UL)),
    111  1.1  christos 	    "Expected OOM for mallocx()");
    112  1.1  christos #endif
    113  1.1  christos }
    114  1.1  christos TEST_END
    115  1.1  christos 
    116  1.1  christos TEST_BEGIN(test_basic) {
    117  1.1  christos #define MAXSZ (((size_t)1) << 23)
    118  1.1  christos 	size_t sz;
    119  1.1  christos 
    120  1.1  christos 	for (sz = 1; sz < MAXSZ; sz = nallocx(sz, 0) + 1) {
    121  1.1  christos 		size_t nsz, rsz;
    122  1.1  christos 		void *p;
    123  1.1  christos 		nsz = nallocx(sz, 0);
    124  1.1  christos 		assert_zu_ne(nsz, 0, "Unexpected nallocx() error");
    125  1.1  christos 		p = mallocx(sz, 0);
    126  1.1  christos 		assert_ptr_not_null(p,
    127  1.1  christos 		    "Unexpected mallocx(size=%zx, flags=0) error", sz);
    128  1.1  christos 		rsz = sallocx(p, 0);
    129  1.1  christos 		assert_zu_ge(rsz, sz, "Real size smaller than expected");
    130  1.1  christos 		assert_zu_eq(nsz, rsz, "nallocx()/sallocx() size mismatch");
    131  1.1  christos 		dallocx(p, 0);
    132  1.1  christos 
    133  1.1  christos 		p = mallocx(sz, 0);
    134  1.1  christos 		assert_ptr_not_null(p,
    135  1.1  christos 		    "Unexpected mallocx(size=%zx, flags=0) error", sz);
    136  1.1  christos 		dallocx(p, 0);
    137  1.1  christos 
    138  1.1  christos 		nsz = nallocx(sz, MALLOCX_ZERO);
    139  1.1  christos 		assert_zu_ne(nsz, 0, "Unexpected nallocx() error");
    140  1.1  christos 		p = mallocx(sz, MALLOCX_ZERO);
    141  1.1  christos 		assert_ptr_not_null(p,
    142  1.1  christos 		    "Unexpected mallocx(size=%zx, flags=MALLOCX_ZERO) error",
    143  1.1  christos 		    nsz);
    144  1.1  christos 		rsz = sallocx(p, 0);
    145  1.1  christos 		assert_zu_eq(nsz, rsz, "nallocx()/sallocx() rsize mismatch");
    146  1.1  christos 		dallocx(p, 0);
    147  1.1  christos 		purge();
    148  1.1  christos 	}
    149  1.1  christos #undef MAXSZ
    150  1.1  christos }
    151  1.1  christos TEST_END
    152  1.1  christos 
    153  1.1  christos TEST_BEGIN(test_alignment_and_size) {
    154  1.1  christos 	const char *percpu_arena;
    155  1.1  christos 	size_t sz = sizeof(percpu_arena);
    156  1.1  christos 
    157  1.1  christos 	if(mallctl("opt.percpu_arena", (void *)&percpu_arena, &sz, NULL, 0) ||
    158  1.1  christos 	    strcmp(percpu_arena, "disabled") != 0) {
    159  1.1  christos 		test_skip("test_alignment_and_size skipped: "
    160  1.1  christos 		    "not working with percpu arena.");
    161  1.1  christos 	};
    162  1.1  christos #define MAXALIGN (((size_t)1) << 23)
    163  1.1  christos #define NITER 4
    164  1.1  christos 	size_t nsz, rsz, alignment, total;
    165  1.1  christos 	unsigned i;
    166  1.1  christos 	void *ps[NITER];
    167  1.1  christos 
    168  1.1  christos 	for (i = 0; i < NITER; i++) {
    169  1.1  christos 		ps[i] = NULL;
    170  1.1  christos 	}
    171  1.1  christos 
    172  1.1  christos 	for (alignment = 8;
    173  1.1  christos 	    alignment <= MAXALIGN;
    174  1.1  christos 	    alignment <<= 1) {
    175  1.1  christos 		total = 0;
    176  1.1  christos 		for (sz = 1;
    177  1.1  christos 		    sz < 3 * alignment && sz < (1U << 31);
    178  1.1  christos 		    sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
    179  1.1  christos 			for (i = 0; i < NITER; i++) {
    180  1.1  christos 				nsz = nallocx(sz, MALLOCX_ALIGN(alignment) |
    181  1.1  christos 				    MALLOCX_ZERO);
    182  1.1  christos 				assert_zu_ne(nsz, 0,
    183  1.1  christos 				    "nallocx() error for alignment=%zu, "
    184  1.1  christos 				    "size=%zu (%#zx)", alignment, sz, sz);
    185  1.1  christos 				ps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) |
    186  1.1  christos 				    MALLOCX_ZERO);
    187  1.1  christos 				assert_ptr_not_null(ps[i],
    188  1.1  christos 				    "mallocx() error for alignment=%zu, "
    189  1.1  christos 				    "size=%zu (%#zx)", alignment, sz, sz);
    190  1.1  christos 				rsz = sallocx(ps[i], 0);
    191  1.1  christos 				assert_zu_ge(rsz, sz,
    192  1.1  christos 				    "Real size smaller than expected for "
    193  1.1  christos 				    "alignment=%zu, size=%zu", alignment, sz);
    194  1.1  christos 				assert_zu_eq(nsz, rsz,
    195  1.1  christos 				    "nallocx()/sallocx() size mismatch for "
    196  1.1  christos 				    "alignment=%zu, size=%zu", alignment, sz);
    197  1.1  christos 				assert_ptr_null(
    198  1.1  christos 				    (void *)((uintptr_t)ps[i] & (alignment-1)),
    199  1.1  christos 				    "%p inadequately aligned for"
    200  1.1  christos 				    " alignment=%zu, size=%zu", ps[i],
    201  1.1  christos 				    alignment, sz);
    202  1.1  christos 				total += rsz;
    203  1.1  christos 				if (total >= (MAXALIGN << 1)) {
    204  1.1  christos 					break;
    205  1.1  christos 				}
    206  1.1  christos 			}
    207  1.1  christos 			for (i = 0; i < NITER; i++) {
    208  1.1  christos 				if (ps[i] != NULL) {
    209  1.1  christos 					dallocx(ps[i], 0);
    210  1.1  christos 					ps[i] = NULL;
    211  1.1  christos 				}
    212  1.1  christos 			}
    213  1.1  christos 		}
    214  1.1  christos 		purge();
    215  1.1  christos 	}
    216  1.1  christos #undef MAXALIGN
    217  1.1  christos #undef NITER
    218  1.1  christos }
    219  1.1  christos TEST_END
    220  1.1  christos 
    221  1.1  christos int
    222  1.1  christos main(void) {
    223  1.1  christos 	return test(
    224  1.1  christos 	    test_overflow,
    225  1.1  christos 	    test_oom,
    226  1.1  christos 	    test_basic,
    227  1.1  christos 	    test_alignment_and_size);
    228  1.1  christos }
    229