diff --git a/configure.ac b/configure.ac index d6c23e53c011256694b4943f79b1f3370cc4cf11..35de036b1d88249e483e1d62d8aec1b624e29883 100644 --- a/configure.ac +++ b/configure.ac @@ -78,7 +78,7 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl]) ]) # Functions and headers -AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l) +AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l posix_memalign) save_libs="$LIBS" LIBS="$LIBS -lm" diff --git a/src/hb-private.hh b/src/hb-private.hh index 48a7db10eec13a8c9ca186b1e1998945b2639150..5660653158d2fa43acd196ebf46e54a562868d59 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -58,6 +58,7 @@ #define HB_PASTE1(a,b) a##b #define HB_PASTE(a,b) HB_PASTE1(a,b) + /* Compile-time custom allocator support. */ #if defined(hb_malloc_impl) \ @@ -72,6 +73,14 @@ extern "C" void hb_free_impl(void *ptr); #define calloc hb_calloc_impl #define realloc hb_realloc_impl #define free hb_free_impl + +#if defined(hb_memalign_impl +extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size); +#define posix_memalign hb_memalign_impl +#else +#undef HAVE_POSIX_MEMALIGN +#endif + #endif @@ -550,6 +559,10 @@ _hb_ceil_to_4 (unsigned int v) return ((v - 1) | 3) + 1; } +static inline bool _hb_ispow2 (unsigned int v) +{ + return 0 == (v & (v - 1)); +} /* @@ -1272,4 +1285,31 @@ _hb_round (double x) #endif +/* fallback for posix_memalign() */ +static inline int +_hb_memalign(void **memptr, size_t alignment, size_t size) +{ + if (unlikely (!_hb_ispow2 (alignment) || + !alignment || + 0 != (alignment & (sizeof (void *) - 1)))) + return EINVAL; + + char *p = (char *) malloc (size + alignment - 1); + if (unlikely (!p)) + return ENOMEM; + + size_t off = (size_t) p & (alignment - 1); + if (off) + p += alignment - off; + + *memptr = (void *) p; + + return 0; +} +#if !defined(posix_memalign) && !defined(HAVE_POSIX_MEMALIGN) +#define posix_memalign _hb_memalign +#endif + + + #endif /* HB_PRIVATE_HH */