[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: new module 'aligned-malloc'
From: |
Bruno Haible |
Subject: |
Re: new module 'aligned-malloc' |
Date: |
Tue, 21 Jul 2020 18:21:26 +0200 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-179-generic; KDE/5.18.0; x86_64; ; ) |
Hi Paul,
> C11 and C++17 have aligned_alloc, which Emacs uses in preference to
> posix_memalign.
Just noticed it as well, when looking at the glibc documentation [1].
Patch below.
> I suggest preferring aligned_alloc to
> posix_memalign since aligned_alloc should be available on more systems as the
> new standards take hold.
I prefer posix_memalign to aligned_alloc, because aligned_alloc requires
additionally that the SIZE is a multiple of the ALIGNMENT.
Currently all platforms that have aligned_alloc also have posix_memalign.
But I agree with you that there is hope that some systems (maybe native
Windows?)
may get aligned_alloc sooner than posix_memalign.
> Also, how about naming the new module 'aligned-alloc' and having it implement
> aligned_alloc? That would make for more-seamless integration.
This is not possible without overriding malloc and free - which surely would
cause a lot of trouble.
[1]
https://www.gnu.org/software/libc/manual/html_node/Aligned-Memory-Blocks.html
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'.
diff --git a/doc/posix-functions/aligned_alloc.texi
b/doc/posix-functions/aligned_alloc.texi
index c938f30..a4897b9 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 86382fd..9baaab4 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 29483d8..d562e3d 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:
- Re: new module 'aligned-malloc', (continued)
- Re: new module 'aligned-malloc', Paul Eggert, 2020/07/22
- Re: new module 'aligned-malloc', Bruno Haible, 2020/07/22
- Re: new module 'aligned-malloc', Jeffrey Walton, 2020/07/22
- Re: new module 'aligned-malloc', Paul Eggert, 2020/07/22
- Re: Minix, Bruno Haible, 2020/07/23
- Re: new module 'aligned-malloc', Florian Weimer, 2020/07/22
- Re: new module 'aligned-malloc', Paul Eggert, 2020/07/22
- Re: new module 'aligned-malloc', Florian Weimer, 2020/07/23
- Re: new module 'aligned-malloc', Paul Eggert, 2020/07/23
- Re: new module 'aligned-malloc', Florian Weimer, 2020/07/23
Re: new module 'aligned-malloc',
Bruno Haible <=