olaf@13: /* universe@103: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. olaf@13: * universe@259: * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved. universe@103: * universe@103: * Redistribution and use in source and binary forms, with or without universe@103: * modification, are permitted provided that the following conditions are met: universe@103: * universe@103: * 1. Redistributions of source code must retain the above copyright universe@103: * notice, this list of conditions and the following disclaimer. universe@103: * universe@103: * 2. Redistributions in binary form must reproduce the above copyright universe@103: * notice, this list of conditions and the following disclaimer in the universe@103: * documentation and/or other materials provided with the distribution. universe@103: * universe@103: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" universe@103: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE universe@103: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE universe@103: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE universe@103: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR universe@103: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF universe@103: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS universe@103: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN universe@103: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) universe@103: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE universe@103: * POSSIBILITY OF SUCH DAMAGE. olaf@13: */ olaf@13: olaf@219: #include olaf@30: olaf@13: #include "mpool_tests.h" olaf@13: universe@134: UCX_TEST(test_ucx_mempool_new) { universe@28: UcxMempool *pool = ucx_mempool_new(16); universe@33: UCX_TEST_BEGIN universe@40: UCX_TEST_ASSERT(pool->size == 16, "wrong size"); universe@40: UCX_TEST_ASSERT(pool->ndata == 0, "uninitialized counter"); universe@40: UCX_TEST_ASSERT(pool->data != NULL, "no memory addressed"); universe@33: UCX_TEST_END olaf@113: ucx_mempool_destroy(pool); olaf@13: } olaf@13: universe@134: UCX_TEST(test_ucx_mempool_malloc) { universe@28: universe@28: UcxMempool *pool = ucx_mempool_new(1); universe@33: UCX_TEST_BEGIN universe@32: intptr_t *test = (intptr_t*) ucx_mempool_malloc(pool, sizeof(intptr_t)); universe@28: universe@40: UCX_TEST_ASSERT(pool->ndata == 1, "counter not incremented"); universe@40: UCX_TEST_ASSERT(pool->size == 1, "chcap called"); universe@28: universe@32: intptr_t *pooladdr = universe@32: (intptr_t*)((char*)pool->data[0] + sizeof(ucx_destructor)); universe@28: *pooladdr = 5; universe@28: universe@40: UCX_TEST_ASSERT(*test == 5, "wrong pointer"); universe@28: universe@33: UCX_TEST_END olaf@113: ucx_mempool_destroy(pool); olaf@13: } olaf@13: universe@134: UCX_TEST(test_ucx_mempool_malloc_with_chcap) { universe@28: universe@28: UcxMempool *pool = ucx_mempool_new(1); universe@33: UCX_TEST_BEGIN universe@28: ucx_mempool_malloc(pool, sizeof(int)); universe@32: intptr_t *test = (intptr_t*) ucx_mempool_malloc(pool, sizeof(intptr_t)); universe@28: universe@40: UCX_TEST_ASSERT(pool->ndata == 2, "counter not incremented"); universe@241: UCX_TEST_ASSERT(pool->size == 2, "chcap not called"); universe@28: universe@32: intptr_t *pooladdr = universe@32: (intptr_t*)((char*)pool->data[1] + sizeof(ucx_destructor)); universe@28: *pooladdr = 5; universe@28: universe@40: UCX_TEST_ASSERT(*test == 5, "wrong pointer"); universe@28: olaf@270: // overflow test olaf@270: void *n0 = ucx_mempool_malloc(pool, (size_t)-1); olaf@270: void *n1 = ucx_mempool_malloc(pool, ((size_t)-1) - sizeof(void*)/2); olaf@270: olaf@270: UCX_TEST_ASSERT(n0 == NULL, "should not allocate SIZE_MAX bytes"); olaf@270: UCX_TEST_ASSERT(n1 == NULL, "should detect integer overflow"); olaf@270: universe@33: UCX_TEST_END olaf@113: ucx_mempool_destroy(pool); universe@28: } universe@19: universe@134: UCX_TEST(test_ucx_mempool_calloc) { universe@28: universe@28: UcxMempool *pool = ucx_mempool_new(1); universe@33: UCX_TEST_BEGIN universe@28: universe@32: intptr_t *test = (intptr_t*) ucx_mempool_calloc(pool, 2, sizeof(intptr_t)); universe@28: universe@40: UCX_TEST_ASSERT(test != NULL, "no memory for test data"); universe@40: UCX_TEST_ASSERT(test[0] == 0 && test[1] == 0, "failed"); universe@28: olaf@270: // overflow test olaf@270: void *n0 = ucx_mempool_calloc(pool, (size_t)-1, 1); olaf@270: void *n1 = ucx_mempool_calloc(pool, ((size_t)-1)/2, 3); olaf@270: olaf@270: UCX_TEST_ASSERT(n0 == NULL, "should not allocate SIZE_MAX bytes"); olaf@270: UCX_TEST_ASSERT(n1 == NULL, "should detect integer overflow"); olaf@270: universe@33: UCX_TEST_END olaf@113: ucx_mempool_destroy(pool); olaf@113: } olaf@113: universe@134: UCX_TEST(test_ucx_mempool_free) { olaf@113: UcxMempool *pool = ucx_mempool_new(16); olaf@113: void *mem1; olaf@113: void *mem2; olaf@113: olaf@113: UCX_TEST_BEGIN olaf@113: olaf@113: mem1 = ucx_mempool_malloc(pool, 16); olaf@113: ucx_mempool_free(pool, mem1); olaf@113: olaf@113: UCX_TEST_ASSERT(pool->ndata == 0, "mempool not empty"); olaf@113: olaf@113: ucx_mempool_malloc(pool, 16); olaf@113: ucx_mempool_malloc(pool, 16); olaf@113: mem1 = ucx_mempool_malloc(pool, 16); olaf@113: ucx_mempool_malloc(pool, 16); olaf@113: mem2 = ucx_mempool_malloc(pool, 16); olaf@113: olaf@113: ucx_mempool_free(pool, mem1); olaf@113: olaf@113: UCX_TEST_ASSERT(pool->ndata == 4, "wrong mempool size"); olaf@113: olaf@113: ucx_mempool_free(pool, mem2); olaf@113: olaf@113: UCX_TEST_ASSERT(pool->ndata == 3, "wrong mempool size"); olaf@113: olaf@113: UCX_TEST_END olaf@113: ucx_mempool_destroy(pool); universe@28: } olaf@13: universe@253: #ifdef __cplusplus universe@253: extern "C" universe@253: #endif universe@253: void test_setdestr(void* elem) { olaf@30: intptr_t *cb = (intptr_t*) ((intptr_t*) elem)[1]; universe@28: *cb = 42; universe@28: } olaf@13: universe@134: UCX_TEST(test_ucx_mempool_set_destr) { universe@28: universe@33: intptr_t *cb = (intptr_t*) malloc(sizeof(intptr_t)); universe@33: UCX_TEST_BEGIN universe@28: UcxMempool *pool = ucx_mempool_new(2); universe@28: universe@32: ucx_mempool_malloc(pool, sizeof(intptr_t)); olaf@30: intptr_t *test = (intptr_t*) ucx_mempool_calloc(pool, 2, sizeof(intptr_t)); universe@28: universe@40: UCX_TEST_ASSERT(cb != NULL && test != NULL, "no memory for test data"); universe@28: olaf@30: test[0] = 5; test[1] = (intptr_t) cb; universe@28: *cb = 13; universe@28: universe@28: ucx_mempool_set_destr(test, test_setdestr); universe@28: UCX_TEST_ASSERT( universe@28: *(ucx_destructor*)(pool->data[1]) == test_setdestr, "failed") universe@28: UCX_TEST_ASSERT( olaf@30: test[0] == 5 && test[1] == (intptr_t) cb, "setdestr destroyed data") universe@28: olaf@113: ucx_mempool_destroy(pool); universe@28: universe@40: UCX_TEST_ASSERT(*cb == 42, "destructor not called"); universe@28: universe@28: UCX_TEST_END universe@33: if (cb != NULL) free(cb); universe@28: } olaf@13: olaf@13: universe@134: UCX_TEST(test_ucx_mempool_reg_destr) { olaf@14: universe@33: intptr_t *test = (intptr_t*) calloc(2, sizeof(intptr_t)); universe@33: intptr_t *cb = (intptr_t*) malloc(sizeof(intptr_t)); universe@33: UCX_TEST_BEGIN universe@28: UcxMempool *pool = ucx_mempool_new(1); universe@28: universe@40: UCX_TEST_ASSERT(cb != NULL && test != NULL, "no memory for test data"); universe@28: olaf@30: test[0] = 5; test[1] = (intptr_t) cb; universe@28: *cb = 13; universe@28: universe@28: ucx_mempool_reg_destr(pool, test, test_setdestr); universe@28: universe@28: ucx_destructor *pooladdr = (ucx_destructor*) olaf@30: ((char*)pool->data[0] + sizeof(ucx_destructor)); universe@28: universe@40: UCX_TEST_ASSERT(*pooladdr == test_setdestr, "failed"); universe@28: olaf@113: ucx_mempool_destroy(pool); universe@40: UCX_TEST_ASSERT(*cb == 42, "destructor not called"); universe@33: UCX_TEST_END olaf@13: universe@33: if (test != NULL) free(test); universe@33: if (cb != NULL) free(cb); universe@28: } olaf@13: universe@134: UCX_TEST(test_ucx_mempool_realloc) { universe@33: universe@33: intptr_t *cb = (intptr_t*) malloc(sizeof(intptr_t)); universe@33: UCX_TEST_BEGIN universe@28: UcxMempool *pool = ucx_mempool_new(2); universe@28: universe@32: ucx_mempool_malloc(pool, sizeof(intptr_t)); olaf@30: intptr_t *test = (intptr_t*) ucx_mempool_calloc(pool, 2, sizeof(intptr_t)); universe@33: universe@40: UCX_TEST_ASSERT(cb != NULL && test != NULL, "no memory for test data"); universe@28: olaf@30: test[0] = 5; test[1] = (intptr_t) cb; universe@28: *cb = 13; universe@28: universe@28: ucx_mempool_set_destr(test, test_setdestr); universe@28: universe@69: intptr_t *rtest, n = 2; universe@28: do { universe@28: n *= 2; universe@40: UCX_TEST_ASSERT(n < 65536, "test corrupt - no movement for realloc"); universe@69: rtest = (intptr_t*) ucx_mempool_realloc(pool, test, n*sizeof(intptr_t)); universe@28: } while (rtest == test); universe@28: test = rtest; universe@28: universe@28: UCX_TEST_ASSERT(*(ucx_destructor*)(pool->data[1]) == test_setdestr, universe@28: "realloc killed destructor") universe@28: UCX_TEST_ASSERT( olaf@30: test[0] == 5 && test[1] == (intptr_t) cb, "realloc destroyed data") universe@28: olaf@113: ucx_mempool_destroy(pool); universe@28: universe@40: UCX_TEST_ASSERT(*cb == 42, "destructor not called"); universe@28: universe@28: UCX_TEST_END universe@33: if (cb != NULL) free(cb); olaf@13: }