diff options
Diffstat (limited to '')
-rw-r--r-- | allocn.c | 118 |
1 files changed, 113 insertions, 5 deletions
@@ -4,11 +4,11 @@ static inline size_t -alloc_size_product(size_t n, va_list ap) +alloc_size_product(int *errp, size_t n, va_list ap) { size_t prod = n; if (!n) { - errno = EINVAL; + *errp = EINVAL; return 0; } for (;;) { @@ -16,7 +16,7 @@ alloc_size_product(size_t n, va_list ap) if (!n) break; if (n >= SIZE_MAX / prod) { - errno = ENOMEM; + *errp = ENOMEM; return 0; } prod *= n; @@ -27,17 +27,41 @@ alloc_size_product(size_t n, va_list ap) void * libsimple_vmalloczn(int clear, size_t n, va_list ap) { - n = alloc_size_product(n, ap); + n = alloc_size_product(&errno, n, ap); return !n ? NULL : clear ? calloc(1, n) : malloc(n); } void * libsimple_vreallocn(void *ptr, size_t n, va_list ap) { - n = alloc_size_product(n, ap); + n = alloc_size_product(&errno, n, ap); return !n ? NULL : realloc(ptr, n); } +void * +libsimple_valigned_alloczn(int clear, size_t alignment, size_t n, va_list ap) +{ + void *ret; + n = alloc_size_product(&errno, n, ap); + ret = !n ? NULL : aligned_alloc(alignment, n); + if (ret && clear) + memset(ret, 0, n); + return ret; +} + +int +libsimple_vposix_memalignzn(void **memptr, int clear, size_t alignment, size_t n, va_list ap) +{ + int ret = 0; + n = alloc_size_product(&ret, n, ap); + if (ret) + return ret; + ret = posix_memalign(memptr, alignment, n); + if (!ret && clear) + memset(*memptr, 0, n); + return ret; +} + #else #include "test.h" @@ -58,6 +82,15 @@ main(void) errno = 0; assert(!libsimple_reallocn(NULL, 0) && errno == EINVAL); errno = 0; + assert(!libsimple_aligned_alloczn(0, 128, 0) && errno == EINVAL); + errno = 0; + assert(!libsimple_aligned_alloczn(1, 128, 0) && errno == EINVAL); + errno = 0; + assert(!libsimple_aligned_allocn(128, 0) && errno == EINVAL); + errno = 0; + assert(libsimple_posix_memalignzn(&ptr, 0, 128, 0) == EINVAL && !errno); + assert(libsimple_posix_memalignzn(&ptr, 1, 128, 0) == EINVAL && !errno); + assert(libsimple_posix_memalignn(&ptr, 128, 0) == EINVAL && !errno); assert(!libsimple_malloczn(0, SIZE_MAX, 2, 0) && errno == ENOMEM); errno = 0; @@ -69,12 +102,22 @@ main(void) errno = 0; assert(!libsimple_reallocn(NULL, SIZE_MAX, 2, 0) && errno == ENOMEM); errno = 0; + assert(!libsimple_aligned_alloczn(0, 1024, SIZE_MAX, 2, 0) && errno == ENOMEM); + errno = 0; + assert(!libsimple_aligned_alloczn(1, 1024, SIZE_MAX, 2, 0) && errno == ENOMEM); + errno = 0; + assert(!libsimple_aligned_allocn(1024, SIZE_MAX, 2, 0) && errno == ENOMEM); + errno = 0; + assert(libsimple_posix_memalignzn(&ptr, 0, 1024, SIZE_MAX, 2, 0) == ENOMEM && !errno); + assert(libsimple_posix_memalignzn(&ptr, 1, 1024, SIZE_MAX, 2, 0) == ENOMEM && !errno); + assert(libsimple_posix_memalignn(&ptr, 1024, SIZE_MAX, 2, 0) == ENOMEM && !errno); assert((ptr = libsimple_malloczn(0, 10, 10, 0))); if (have_custom_malloc()) { assert((info = get_allocinfo(ptr))); assert(info->size == 100); assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); } free(ptr); @@ -83,6 +126,7 @@ main(void) assert((info = get_allocinfo(ptr))); assert(info->size == 400); assert(info->zeroed == 400); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); } free(ptr); @@ -91,6 +135,7 @@ main(void) assert((info = get_allocinfo(ptr))); assert(info->size == 121); assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); } free(ptr); @@ -99,6 +144,7 @@ main(void) assert((info = get_allocinfo(ptr))); assert(info->size == 484); assert(info->zeroed == 484); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); } free(ptr); @@ -108,6 +154,7 @@ main(void) assert(info->size == 5); assert(!info->zeroed); info->refcount += 1; + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); } stpcpy(ptr, "test"); assert((ptr = libsimple_reallocn(old = ptr, 10, 0))); @@ -116,11 +163,72 @@ main(void) assert((info = get_allocinfo(ptr))); assert(info->size == 10); assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); assert(ptr != old); free(old); } free(ptr); + assert((ptr = libsimple_aligned_alloczn(0, 8, 12, 12, 0))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 144); + assert(info->alignment == 8); + assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); + } + free(ptr); + + assert((ptr = libsimple_aligned_alloczn(1, 16, 12, 12, 2, 0))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 288); + assert(info->alignment == 16); + assert(info->zeroed == 288); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); + } + free(ptr); + + assert((ptr = libsimple_aligned_allocn(32, 12, 12, 4, 0))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 576); + assert(info->alignment == 32); + assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); + } + free(ptr); + + assert(!libsimple_posix_memalignzn(&ptr, 0, sizeof(void *), 12, 12, 0)); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 144); + assert(info->alignment == sizeof(void *)); + assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); + } + free(ptr); + + assert(!libsimple_posix_memalignzn(&ptr, 1, 2 * sizeof(void *), 12, 12, 2, 0)); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 288); + assert(info->alignment == 2 * sizeof(void *)); + assert(info->zeroed == 288); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); + } + free(ptr); + + assert(!libsimple_posix_memalignn(&ptr, 2 * sizeof(void *), 12, 12, 3, 0)); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 432); + assert(info->alignment == 2 *sizeof(void *)); + assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); + } + free(ptr); + assert(!errno); return 0; |