summary refs log tree commit
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2015-12-21 09:37:52 +0000
committerEric Wong <e@80x24.org>2017-11-06 19:43:15 +0000
commitbd8036aba78085829f8862a58645077f8ca0f6d0 (patch)
tree73f27302ef87078a9803430532cf7961d0e3a429
parent1495ada2093892ecb068f95c689d2d5079a5af2c (diff)
downloadsox-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.ac5
-rw-r--r--src/util.h31
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])
diff --git a/src/util.h b/src/util.h
index b5cc9b89..a1da1e94 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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 --------------------------------*/