From c3e397e6618b6190741b6fff3e7a5bb424818feb Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 22 Jan 2015 20:49:57 -0600 Subject: [PATCH] Portable aligned memory allocation --- CMakeLists.txt | 2 ++ src/aligned_malloc.c | 36 ++++++++++++++++++++++++++++++++++++ src/aligned_malloc.h | 14 ++++++++++++++ src/deflate_compress.c | 5 +++-- 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/aligned_malloc.c create mode 100644 src/aligned_malloc.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bebfce..0dc7f09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,8 @@ if(SUPPORT_GZIP) endif() endif() +set(LIB_SOURCES ${LIB_SOURCES} src/aligned_malloc.c) + option(SUPPORT_NEAR_OPTIMAL_PARSING "Support near optimal parsing (high compression mode)" ON) if(SUPPORT_NEAR_OPTIMAL_PARSING) add_definitions(-DSUPPORT_NEAR_OPTIMAL_PARSING=1) diff --git a/src/aligned_malloc.c b/src/aligned_malloc.c new file mode 100644 index 0000000..2d53140 --- /dev/null +++ b/src/aligned_malloc.c @@ -0,0 +1,36 @@ +/* + * aligned_malloc.c + * + * Aligned memory allocation using only malloc() and free(). + * Avoids portability problems with posix_memalign(), aligned_alloc(), etc. + * + * This file has no copyright assigned and is placed in the Public Domain. + */ + +#include "aligned_malloc.h" + +#include +#include + +void * +aligned_malloc(size_t alignment, size_t size) +{ + const uintptr_t mask = alignment - 1; + char *ptr = NULL; + char *raw_ptr; + + raw_ptr = malloc(mask + sizeof(size_t) + size); + if (raw_ptr) { + ptr = (char *)raw_ptr + sizeof(size_t); + ptr = (void *)(((uintptr_t)ptr + mask) & ~mask); + *((size_t *)ptr - 1) = ptr - raw_ptr; + } + return ptr; +} + +void +aligned_free(void *ptr) +{ + if (ptr) + free((char *)ptr - *((size_t *)ptr - 1)); +} diff --git a/src/aligned_malloc.h b/src/aligned_malloc.h new file mode 100644 index 0000000..a84e029 --- /dev/null +++ b/src/aligned_malloc.h @@ -0,0 +1,14 @@ +/* + * aligned_malloc.c + * + * Aligned memory allocation. + * + * This file has no copyright assigned and is placed in the Public Domain. + */ + +#pragma once + +#include + +extern void *aligned_malloc(size_t alignment, size_t size); +extern void aligned_free(void *ptr); diff --git a/src/deflate_compress.c b/src/deflate_compress.c index e730eea..6ca0b67 100644 --- a/src/deflate_compress.c +++ b/src/deflate_compress.c @@ -10,6 +10,7 @@ #include "libdeflate.h" +#include "aligned_malloc.h" #include "deflate_compress.h" #include "deflate_constants.h" #include "unaligned.h" @@ -2197,7 +2198,7 @@ deflate_alloc_compressor(unsigned int compression_level) #endif size = offsetof(struct deflate_compressor, nonoptimal_end); - c = aligned_alloc(MATCHFINDER_ALIGNMENT, size); + c = aligned_malloc(MATCHFINDER_ALIGNMENT, size); if (!c) return NULL; @@ -2313,7 +2314,7 @@ deflate_compress(struct deflate_compressor *c, LIBEXPORT void deflate_free_compressor(struct deflate_compressor *c) { - free(c); + aligned_free(c); } unsigned int