From: Bruno Haible <bruno@clisp.org> Date: Tue, 21 Jul 2020 16:09:35 +0000 (+0200) Subject: aligned-malloc: Optionally use aligned_alloc. X-Git-Tag: v1.0~3874 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=ac34618e85013bfec4650f02e8e79c5de6d80fb3;p=gnulib.git aligned-malloc: Optionally use aligned_alloc. * lib/aligned-malloc.h: Verify the alignment. (aligned_malloc): Use aligned_alloc as an alternative. * modules/aligned-malloc (configure.ac): Test for aligned_alloc. * doc/posix-functions/aligned_alloc.texi: Mention the modules 'aligned-malloc' and 'pagealign_alloc'. --- diff --git a/ChangeLog b/ChangeLog index 8da483c857..8cac948ad2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2020-07-21 Bruno Haible <bruno@clisp.org> + + aligned-malloc: Optionally use aligned_alloc. + * lib/aligned-malloc.h: Verify the alignment. + (aligned_malloc): Use aligned_alloc as an alternative. + * modules/aligned-malloc (configure.ac): Test for aligned_alloc. + * doc/posix-functions/aligned_alloc.texi: Mention the modules + 'aligned-malloc' and 'pagealign_alloc'. + 2020-07-21 Bruno Haible <bruno@clisp.org> aligned-malloc: Add tests. diff --git a/doc/posix-functions/aligned_alloc.texi b/doc/posix-functions/aligned_alloc.texi index c938f30d71..a4897b9167 100644 --- a/doc/posix-functions/aligned_alloc.texi +++ b/doc/posix-functions/aligned_alloc.texi @@ -16,3 +16,9 @@ Portability problems not fixed by Gnulib: This function is missing on all non-glibc platforms: glibc 2.15, Mac OS X 10.5, FreeBSD 6.4, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.3, Cygwin, mingw, MSVC 14, Android 8.1. @end itemize + +The Gnulib module @code{aligned-malloc} provides functions for +allocating and freeing blocks of suitably aligned memory. + +The Gnulib module @code{pagealign_alloc} provides a similar API for +allocating and freeing blocks of memory aligned on a system page boundary. diff --git a/lib/aligned-malloc.h b/lib/aligned-malloc.h index 86382fd25b..9baaab4cfe 100644 --- a/lib/aligned-malloc.h +++ b/lib/aligned-malloc.h @@ -29,17 +29,29 @@ The block can be freed through aligned_free(), NOT through free(). Upon failure, it returns NULL. */ -/* This module exists instead of a posix_memalign() or memalign() emulation, - because we can't reasonably emulate posix_memalign() or memalign(): +/* This module exists instead of a posix_memalign(), aligned_alloc(), or + memalign() emulation, because we can't reasonably emulate posix_memalign(), + aligned_alloc(), or memalign(): If malloc() returned p, only free (p) is allowed, not free (p + 1), free (p + 2), free (p + 4), free (p + 8), or similar. - We can use posix_memalign(). On older systems, we can alternatively use - memalign() instead. In the Solaris documentation of memalign() it is not - specified how a memory block returned by memalign() can be freed, but - it actually can be freed with free(). */ + We can use posix_memalign(), a POSIX function. -#if ((ALIGNMENT) <= MALLOC_ALIGNMENT) || HAVE_POSIX_MEMALIGN || HAVE_MEMALIGN + We can also use aligned_alloc(), an ISO C11 and POSIX function. But it's + a bit more awkward to use. + + On older systems, we can alternatively use memalign() instead. In the + Solaris documentation of memalign() it is not specified how a memory block + returned by memalign() can be freed, but it actually can be freed with + free(). */ + +#if !defined ALIGNMENT +# error "ALIGNMENT is not defined" +#endif +#if !((ALIGNMENT) > 0 && ((ALIGNMENT) & ((ALIGNMENT) - 1)) == 0) +# error "ALIGNMENT is not a power of 2" +#endif +#if ((ALIGNMENT) <= MALLOC_ALIGNMENT) || HAVE_POSIX_MEMALIGN || HAVE_ALIGNED_ALLOC || HAVE_MEMALIGN # if (ALIGNMENT) <= MALLOC_ALIGNMENT /* Simply use malloc. */ @@ -70,6 +82,23 @@ aligned_malloc (size_t size) return NULL; } +# elif HAVE_ALIGNED_ALLOC +/* Use aligned_alloc. */ + +static inline void * +aligned_malloc (size_t size) +{ + /* Round up SIZE to the next multiple of ALIGNMENT, + namely (SIZE + ALIGNMENT - 1) & ~(ALIGNMENT - 1). */ + size += (ALIGNMENT) - 1; + if (size >= (ALIGNMENT) - 1) /* no overflow? */ + { + size &= ~(size_t)((ALIGNMENT) - 1); + return aligned_alloc ((ALIGNMENT), size); + } + return NULL; +} + # elif HAVE_MEMALIGN /* HP-UX, IRIX, Solaris <= 10 */ /* Use memalign. */ diff --git a/modules/aligned-malloc b/modules/aligned-malloc index 29483d83d7..d562e3d6b9 100644 --- a/modules/aligned-malloc +++ b/modules/aligned-malloc @@ -11,7 +11,7 @@ stdint configure.ac: gl_MALLOC_ALIGNMENT AC_REQUIRE([AC_C_INLINE]) -AC_CHECK_FUNCS([posix_memalign memalign]) +AC_CHECK_FUNCS([posix_memalign aligned_alloc memalign]) Makefile.am: