diff --git a/CMakeLists.txt b/CMakeLists.txt index d5e05da6..1610e8b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -447,6 +447,9 @@ if(NOT HAVE_STRERROR) endif() set(CMAKE_REQUIRED_FLAGS) +# +# Check for aligned memory allocation support: POSIX +# set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=200112L) set(CMAKE_REQUIRED_FLAGS "${ADDITIONAL_CHECK_FLAGS}") check_symbol_exists(posix_memalign stdlib.h HAVE_POSIX_MEMALIGN) @@ -456,6 +459,9 @@ endif() set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_DEFINITIONS) +# +# Check for aligned memory allocation support: C11 +# set(CMAKE_REQUIRED_DEFINITIONS -D_ISOC11_SOURCE=1) set(CMAKE_REQUIRED_FLAGS "${ADDITIONAL_CHECK_FLAGS}") check_symbol_exists(aligned_alloc stdlib.h HAVE_ALIGNED_ALLOC) @@ -465,6 +471,28 @@ endif() set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_DEFINITIONS) +# +# Check for aligned memory allocation support: GNU extension +# Note: memalign() is deprecated in glibc +# +check_symbol_exists(memalign malloc.h HAVE_MEMALIGN) +if(HAVE_MEMALIGN) + add_definitions(-DHAVE_MEMALIGN) +endif() +set(CMAKE_REQUIRED_DEFINITIONS) + +# +# Check for aligned memory allocation support: MSVC extensions +# +check_symbol_exists(_aligned_malloc malloc.h HAVE__ALIGNED_MALLOC) +if(HAVE__ALIGNED_MALLOC) + add_definitions(-DHAVE__ALIGNED_MALLOC) +endif() +set(CMAKE_REQUIRED_DEFINITIONS) + +# +# Check whether a sanitizer was requested +# if(WITH_SANITIZER STREQUAL "Address") add_address_sanitizer() elseif(WITH_SANITIZER STREQUAL "Memory") diff --git a/configure b/configure index 15bb5933..fe19641b 100755 --- a/configure +++ b/configure @@ -724,6 +724,8 @@ EOF fi echo >> configure.log + +# check for aligned memory allocation support: POSIX cat > $test.c < @@ -744,6 +746,7 @@ else fi echo >> configure.log +# check for aligned memory allocation support: C11 cat > $test.c < @@ -763,6 +766,47 @@ else fi echo >> configure.log + +# check for aligned memory allocation support: GNU extension +# Note: memalign() is deprecated in glibc +cat > $test.c < +int main(void) { + void *ptr = memalign(64, 10); + if (ptr) + free(ptr); + return 0; +} +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for memalign... Yes." | tee -a configure.log + CFLAGS="${CFLAGS} -DHAVE_MEMALIGN" + SFLAGS="${SFLAGS} -DHAVE_MEMALIGN" +else + echo "Checking for memalign... No." | tee -a configure.log +fi +echo >> configure.log + +# check for aligned memory allocation support: MSVC extensions +cat > $test.c < +int main(void) { + void *ptr = _aligned_malloc(10, 64); + if (ptr) + _aligned_free(ptr); + return 0; +} +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for _aligned_malloc... Yes." | tee -a configure.log + CFLAGS="${CFLAGS} -DHAVE__ALIGNED_MALLOC" + SFLAGS="${SFLAGS} -DHAVE__ALIGNED_MALLOC" +else + echo "Checking for _aligned_malloc... No." | tee -a configure.log +fi +echo >> configure.log + + # check for strerror() for use by gz* functions cat > $test.c < diff --git a/zutil_p.h b/zutil_p.h index 835e12f4..8f596eb4 100644 --- a/zutil_p.h +++ b/zutil_p.h @@ -5,13 +5,16 @@ #ifndef ZUTIL_P_H #define ZUTIL_P_H -#if defined(__APPLE__) || defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_ALIGNED_ALLOC) +#if defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_ALIGNED_ALLOC) # include #elif defined(__FreeBSD__) # include # include -#else +#elif defined(HAVE_MEMALIGN) || defined(HAVE__ALIGNED_MALLOC) # include +#else +/* Fallback, when no other aligned allocation function was found */ +# include #endif /* Function to allocate 16 or 64-byte aligned memory */ @@ -23,20 +26,22 @@ static inline void *zng_alloc(size_t size) { #elif defined(HAVE_POSIX_MEMALIGN) void *ptr; return posix_memalign(&ptr, 64, size) ? NULL : ptr; -#elif defined(_WIN32) +#elif defined(HAVE__ALIGNED_MALLOC) + /* Fallback: Use MSVC extensions: _aligned_malloc() / _aligned_free() */ return (void *)_aligned_malloc(size, 64); -#elif defined(__APPLE__) - /* Fallback for when posix_memalign and aligned_alloc are not available. - * On macOS, it always aligns to 16 bytes. */ - return (void *)malloc(size); -#else +#elif defined(HAVE_MEMALIGN) + /* Fallback: Use deprecated GNU extension: memalign() */ return (void *)memalign(64, size); +#else + /* Fallback: Use a normal allocation (On macOS, alignment is 16 bytes) */ + /* zlib-ng adjust allocations for [de]compression to be properly aligned */ + return (void *)malloc(size); #endif } /* Function that can free aligned memory */ static inline void zng_free(void *ptr) { -#if defined(_WIN32) +#if defined(HAVE__ALIGNED_MALLOC) && !defined(HAVE_POSIX_MEMALIGN) && !defined(HAVE_ALIGNED_ALLOC) _aligned_free(ptr); #else free(ptr);