summaryrefslogtreecommitdiff
path: root/m4/malloc-align.m4
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2020-07-21 10:03:42 +0200
committerBruno Haible <bruno@clisp.org>2020-07-21 10:37:17 +0200
commit8ce76ed581d7ad000c8d72d9fe759929d653f171 (patch)
tree93c894b1a2e51256e069090a9f758384e4d117e6 /m4/malloc-align.m4
parentb768bbdd15f2473d2d60b31702ef54d93a65d537 (diff)
downloadgnulib-8ce76ed581d7ad000c8d72d9fe759929d653f171.tar.gz
aligned-malloc: New module.
* lib/aligned-malloc.h: New file. * m4/malloc-align.m4: New file. * modules/aligned-malloc: New file. * doc/posix-functions/posix_memalign.texi: Mention the new module. * doc/glibc-functions/memalign.texi: Likewise.
Diffstat (limited to 'm4/malloc-align.m4')
-rw-r--r--m4/malloc-align.m4140
1 files changed, 140 insertions, 0 deletions
diff --git a/m4/malloc-align.m4 b/m4/malloc-align.m4
new file mode 100644
index 0000000000..7ee8343680
--- /dev/null
+++ b/m4/malloc-align.m4
@@ -0,0 +1,140 @@
+# malloc-align.m4 serial 1
+dnl Copyright (C) 2020 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Defines a C macro MALLOC_ALIGNMENT, whose value is a numeric constant,
+dnl a power of 2, with the property that
+dnl (uintptr_t) malloc (N)
+dnl is always guaranteed to be a multiple of MALLOC_ALIGNMENT.
+
+AC_DEFUN([gl_MALLOC_ALIGNMENT],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_CACHE_CHECK([for the malloc() alignment],
+ [gl_cv_malloc_alignment],
+ [gl_cv_malloc_alignment=
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <stdio.h>
+ #include <stdlib.h>
+ #if defined _WIN32 && !defined __CYGWIN__
+ # include <inttypes.h>
+ /* uintptr_t is equivalent to 'unsigned long long' if _WIN64,
+ or to 'unsigned long' otherwise. */
+ #else
+ # undef uintptr_t
+ # define uintptr_t unsigned long
+ #endif
+ ]],
+ [[FILE *fp = fopen ("conftest.out", "w");
+ if (fp == NULL)
+ return 1;
+ {
+ uintptr_t bits = 0;
+ bits |= (uintptr_t) malloc (1);
+ bits |= (uintptr_t) malloc (1);
+ bits |= (uintptr_t) malloc (1);
+ bits |= (uintptr_t) malloc (2);
+ bits |= (uintptr_t) malloc (2);
+ bits |= (uintptr_t) malloc (2);
+ bits |= (uintptr_t) malloc (3);
+ bits |= (uintptr_t) malloc (3);
+ bits |= (uintptr_t) malloc (3);
+ bits |= (uintptr_t) malloc (5);
+ bits |= (uintptr_t) malloc (8);
+ bits |= (uintptr_t) malloc (8);
+ bits |= (uintptr_t) malloc (13);
+ bits |= (uintptr_t) malloc (13);
+ bits |= (uintptr_t) malloc (19);
+ bits |= (uintptr_t) malloc (19);
+ bits |= (uintptr_t) malloc (28);
+ bits |= (uintptr_t) malloc (28);
+ bits |= (uintptr_t) malloc (37);
+ bits |= (uintptr_t) malloc (37);
+ bits |= (uintptr_t) malloc (73);
+ bits |= (uintptr_t) malloc (73);
+ bits |= (uintptr_t) malloc (117);
+ bits |= (uintptr_t) malloc (117);
+ bits |= (uintptr_t) malloc (351);
+ bits |= (uintptr_t) malloc (351);
+ bits |= (uintptr_t) malloc (914);
+ bits |= (uintptr_t) malloc (914);
+ bits |= (uintptr_t) malloc (1712);
+ bits |= (uintptr_t) malloc (1712);
+ bits |= (uintptr_t) malloc (4021);
+ bits |= (uintptr_t) malloc (4021);
+ bits |= (uintptr_t) malloc (7641);
+ bits |= (uintptr_t) malloc (7641);
+ bits |= (uintptr_t) malloc (17027);
+ bits |= (uintptr_t) malloc (17027);
+ bits |= (uintptr_t) malloc (81231);
+ bits |= (uintptr_t) malloc (81231);
+ fprintf (fp, "%u\n", (unsigned int) (((bits ^ (bits - 1)) + 1) >> 1));
+ }
+ if (fclose (fp) != 0)
+ return 2;
+ return 0;
+ ]])
+ ],
+ [gl_cv_malloc_alignment=`cat conftest.out`],
+ [gl_cv_malloc_alignment="unknown"],
+ [dnl When cross-compiling, guess a value. Note that it's OK to return
+ dnl a smaller value (e.g. 4 instead of 8 or 16).
+ gl_cv_malloc_alignment="unknown"
+ case "$host_os" in
+ linux* | mingw*)
+ dnl On Linux:
+ dnl - It's 8 on most 32-bit platforms, except 16 on x86_64-x32 and
+ dnl (with newer versions of glibc) on i386 and powerpc. 8 is a
+ dnl safe guess.
+ dnl - It's 16 on all 64-bit platforms.
+ dnl On Windows: It's 8 on 32-bit Windows, 16 on 64-bit Windows.
+ for nn in 4 8 16 32; do
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #define MALLOC_ALIGN (2 * sizeof (void *))
+ int test [MALLOC_ALIGN <= $nn ? 1 : -1];
+ ]])
+ ],
+ [gl_cv_malloc_alignment="guessing $nn"
+ break
+ ],
+ [:])
+ done
+ ;;
+ *)
+ dnl If we don't know, assume the worst.
+ dnl This minimum is e.g. reached on NetBSD/i386 and NetBSD/sparc.
+ for nn in 4 8 16; do
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #define MALLOC_ALIGN (sizeof (void *))
+ int test [MALLOC_ALIGN <= $nn ? 1 : -1];
+ ]])
+ ],
+ [gl_cv_malloc_alignment="guessing $nn"
+ break
+ ],
+ [:])
+ done
+ ;;
+ esac
+ ])
+ ])
+ case "$gl_cv_malloc_alignment" in
+ "unknown")
+ dnl Assume the worst.
+ value=4
+ ;;
+ "guessing "*)
+ value=`echo "$gl_cv_malloc_alignment" | sed -e 's/guessing //'`
+ ;;
+ *)
+ value="$gl_cv_malloc_alignment"
+ ;;
+ esac
+ AC_DEFINE_UNQUOTED([MALLOC_ALIGNMENT], [$value],
+ [Define to the guaranteed alignment of malloc() return values.])
+])