spawn: Use special invocation for <spawn.h> on OS/2 kLIBC.
[gnulib.git] / m4 / malloc-align.m4
blob83df72fe0ae15b4c97b5d5db049325215f5e0731
1 # malloc-align.m4 serial 1
2 dnl Copyright (C) 2020-2021 Free Software Foundation, Inc.
3 dnl This file is free software; the Free Software Foundation
4 dnl gives unlimited permission to copy and/or distribute it,
5 dnl with or without modifications, as long as this notice is preserved.
7 dnl Defines a C macro MALLOC_ALIGNMENT, whose value is a numeric constant,
8 dnl a power of 2, with the property that
9 dnl   (uintptr_t) malloc (N)
10 dnl is always guaranteed to be a multiple of MALLOC_ALIGNMENT.
12 AC_DEFUN([gl_MALLOC_ALIGNMENT],
14   AC_REQUIRE([AC_CANONICAL_HOST])
15   AC_CACHE_CHECK([for the malloc() alignment],
16     [gl_cv_malloc_alignment],
17     [gl_cv_malloc_alignment=
18      AC_RUN_IFELSE(
19        [AC_LANG_PROGRAM(
20           [[#include <stdio.h>
21             #include <stdlib.h>
22             #if defined _WIN32 && !defined __CYGWIN__
23             # include <inttypes.h>
24             /* uintptr_t is equivalent to 'unsigned long long' if _WIN64,
25                or to 'unsigned long' otherwise.  */
26             #else
27             # undef uintptr_t
28             # define uintptr_t unsigned long
29             #endif
30           ]],
31           [[FILE *fp = fopen ("conftest.out", "w");
32             if (fp == NULL)
33               return 1;
34             {
35               uintptr_t bits = 0;
36               bits |= (uintptr_t) malloc (1);
37               bits |= (uintptr_t) malloc (1);
38               bits |= (uintptr_t) malloc (1);
39               bits |= (uintptr_t) malloc (2);
40               bits |= (uintptr_t) malloc (2);
41               bits |= (uintptr_t) malloc (2);
42               bits |= (uintptr_t) malloc (3);
43               bits |= (uintptr_t) malloc (3);
44               bits |= (uintptr_t) malloc (3);
45               bits |= (uintptr_t) malloc (5);
46               bits |= (uintptr_t) malloc (8);
47               bits |= (uintptr_t) malloc (8);
48               bits |= (uintptr_t) malloc (13);
49               bits |= (uintptr_t) malloc (13);
50               bits |= (uintptr_t) malloc (19);
51               bits |= (uintptr_t) malloc (19);
52               bits |= (uintptr_t) malloc (28);
53               bits |= (uintptr_t) malloc (28);
54               bits |= (uintptr_t) malloc (37);
55               bits |= (uintptr_t) malloc (37);
56               bits |= (uintptr_t) malloc (73);
57               bits |= (uintptr_t) malloc (73);
58               bits |= (uintptr_t) malloc (117);
59               bits |= (uintptr_t) malloc (117);
60               bits |= (uintptr_t) malloc (351);
61               bits |= (uintptr_t) malloc (351);
62               bits |= (uintptr_t) malloc (914);
63               bits |= (uintptr_t) malloc (914);
64               bits |= (uintptr_t) malloc (1712);
65               bits |= (uintptr_t) malloc (1712);
66               bits |= (uintptr_t) malloc (4021);
67               bits |= (uintptr_t) malloc (4021);
68               bits |= (uintptr_t) malloc (7641);
69               bits |= (uintptr_t) malloc (7641);
70               bits |= (uintptr_t) malloc (17027);
71               bits |= (uintptr_t) malloc (17027);
72               bits |= (uintptr_t) malloc (81231);
73               bits |= (uintptr_t) malloc (81231);
74               fprintf (fp, "%u\n", (unsigned int) (((bits ^ (bits - 1)) + 1) >> 1));
75             }
76             if (fclose (fp) != 0)
77               return 2;
78             return 0;
79           ]])
80        ],
81        [gl_cv_malloc_alignment=`cat conftest.out`],
82        [gl_cv_malloc_alignment="unknown"],
83        [dnl When cross-compiling, guess a value. Note that it's OK to return
84         dnl a smaller value (e.g. 4 instead of 8 or 16).
85         gl_cv_malloc_alignment="unknown"
86         case "$host_os" in
87           linux* | mingw*)
88             dnl On Linux:
89             dnl - It's 8 on most 32-bit platforms, except 16 on x86_64-x32 and
90             dnl   (with newer versions of glibc) on i386 and powerpc.  8 is a
91             dnl   safe guess.
92             dnl - It's 16 on all 64-bit platforms.
93             dnl On Windows: It's 8 on 32-bit Windows, 16 on 64-bit Windows.
94             for nn in 4 8 16 32; do
95               AC_COMPILE_IFELSE(
96                 [AC_LANG_PROGRAM([[
97                    #define MALLOC_ALIGN (2 * sizeof (void *))
98                    int test [MALLOC_ALIGN <= $nn ? 1 : -1];
99                    ]])
100                 ],
101                 [gl_cv_malloc_alignment="guessing $nn"
102                  break
103                 ],
104                 [:])
105             done
106             ;;
107           *)
108             dnl If we don't know, assume the worst.
109             dnl This minimum is e.g. reached on NetBSD/i386 and NetBSD/sparc.
110             for nn in 4 8 16; do
111               AC_COMPILE_IFELSE(
112                 [AC_LANG_PROGRAM([[
113                    #define MALLOC_ALIGN (sizeof (void *))
114                    int test [MALLOC_ALIGN <= $nn ? 1 : -1];
115                    ]])
116                 ],
117                 [gl_cv_malloc_alignment="guessing $nn"
118                  break
119                 ],
120                 [:])
121             done
122             ;;
123         esac
124        ])
125     ])
126   case "$gl_cv_malloc_alignment" in
127     "unknown")
128       dnl Assume the worst.
129       value=4
130     ;;
131     "guessing "*)
132       value=`echo "$gl_cv_malloc_alignment" | sed -e 's/guessing //'`
133       ;;
134     *)
135       value="$gl_cv_malloc_alignment"
136       ;;
137   esac
138   AC_DEFINE_UNQUOTED([MALLOC_ALIGNMENT], [$value],
139     [Define to the guaranteed alignment of malloc() return values.])