diff options
author | Eric Wong <normalperson@yhbt.net> | 2015-12-21 09:37:52 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2017-11-06 19:43:15 +0000 |
commit | bd8036aba78085829f8862a58645077f8ca0f6d0 (patch) | |
tree | 73f27302ef87078a9803430532cf7961d0e3a429 | |
parent | 1495ada2093892ecb068f95c689d2d5079a5af2c (diff) | |
download | sox-bd8036aba78085829f8862a58645077f8ca0f6d0.tar.gz |
always support aligned heap allocation
The new sdm effect will not work correctly on AVX systems without 32-byte alignment; so we need to support older systems without C11 aligned_alloc. The fallback emulation is based on code found in gc.c in Ruby 2.0+ (BSD-licensed)
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | src/util.h | 31 |
2 files changed, 33 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac index 9c812630..cffa9b68 100644 --- a/configure.ac +++ b/configure.ac @@ -203,9 +203,12 @@ AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h unistd.h byteswap.h sys/stat.h sys/time.h sys/timeb.h sys/types.h sys/utsname.h termios.h glob.h fenv.h) dnl Checks for library functions. -AC_CHECK_FUNCS(strcasecmp strdup popen vsnprintf gettimeofday mkstemp fmemopen aligned_alloc) +AC_CHECK_FUNCS(strcasecmp strdup popen vsnprintf gettimeofday mkstemp fmemopen) AC_CHECK_FUNCS(posix_fadvise) +dnl aligned alloc required for sdm_x86.h using AVX (32-byte) or SSE2 (16-byte) +AC_CHECK_FUNCS(aligned_alloc memalign posix_memalign) + dnl Check if math library is needed. AC_SEARCH_LIBS([pow], [m]) AC_SEARCH_LIBS([lrint], [m]) @@ -196,12 +196,39 @@ #ifdef HAVE_ALIGNED_ALLOC #define aligned_free(p) free(p) +#elif defined(HAVE_MEMALIGN) + #include <malloc.h> + #define aligned_alloc(a, s) memalign(a, s) + #define aligned_free(p) free(p) +#elif defined(HAVE_POSIX_MEMALIGN) + #include <errno.h> +static inline void *sox_aligned_alloc_pm(size_t align, size_t size) +{ + void *ptr; + int err = posix_memalign(&ptr, align, size); + + if (!err) return ptr; + errno = err; + return 0; +} + #define aligned_alloc(a, s) sox_aligned_alloc_pm(a, s) + #define aligned_free(p) free(p) #elif defined _MSC_VER #define aligned_alloc(a, s) _aligned_malloc(s, a) #define aligned_free(p) _aligned_free(p) #else - #define aligned_alloc(a, s) malloc(s) - #define aligned_free(p) free(p) +static inline void *sox_aligned_alloc_m(size_t align, size_t size) +{ + void *res = malloc(align + size + sizeof(void *)); + char *aligned = (char *)res + align + sizeof(void *); + + aligned -= ((uintptr_t)aligned & (align - 1)); + ((void **)aligned)[-1] = res; + return (void *)aligned; +} + + #define aligned_alloc(a, s) sox_aligned_alloc_m(a, s) + #define aligned_free(p) free(((void**)p)[-1]); #endif /*------------------------------- Maths stuff --------------------------------*/ |