diff options
author | Bruno Haible <bruno@clisp.org> | 2020-07-21 10:03:42 +0200 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2020-07-21 10:37:17 +0200 |
commit | 8ce76ed581d7ad000c8d72d9fe759929d653f171 (patch) | |
tree | 93c894b1a2e51256e069090a9f758384e4d117e6 /m4/malloc-align.m4 | |
parent | b768bbdd15f2473d2d60b31702ef54d93a65d537 (diff) | |
download | gnulib-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.m4 | 140 |
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.]) +]) |