]> Savannah Git Hosting - gnulib.git/commitdiff
posix_memalign: New module.
authorBruno Haible <bruno@clisp.org>
Wed, 4 Nov 2020 01:19:08 +0000 (02:19 +0100)
committerBruno Haible <bruno@clisp.org>
Wed, 4 Nov 2020 01:19:08 +0000 (02:19 +0100)
* lib/stdlib.in.h (posix_memalign): New declaration.
* lib/posix_memalign.c: New file.
* m4/posix_memalign.m4: New file.
* m4/stdlib_h.m4 (gl_STDLIB_H): Test whether posix_memalign is declared.
(gl_STDLIB_H_DEFAULTS): Initialize GNULIB_POSIX_MEMALIGN,
HAVE_POSIX_MEMALIGN, REPLACE_POSIX_MEMALIGN.
* modules/stdlib (Makefile.am): Substitute GNULIB_POSIX_MEMALIGN,
HAVE_POSIX_MEMALIGN, REPLACE_POSIX_MEMALIGN.
* modules/posix_memalign: New file.
* tests/test-stdlib-c++.cc (posix_memalign): Check signature.
* doc/posix-functions/posix_memalign.texi: Mention the new module and
the OpenBSD bug.

ChangeLog
doc/posix-functions/posix_memalign.texi
lib/posix_memalign.c [new file with mode: 0644]
lib/stdlib.in.h
m4/posix_memalign.m4 [new file with mode: 0644]
m4/stdlib_h.m4
modules/posix_memalign [new file with mode: 0644]
modules/stdlib
tests/test-stdlib-c++.cc

index e6089930a081d063380bbcdf50086175853bafb5..fd72d3e850428c28d02af458df0b6d512100d97e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2020-11-03  Bruno Haible  <bruno@clisp.org>
+
+       posix_memalign: New module.
+       * lib/stdlib.in.h (posix_memalign): New declaration.
+       * lib/posix_memalign.c: New file.
+       * m4/posix_memalign.m4: New file.
+       * m4/stdlib_h.m4 (gl_STDLIB_H): Test whether posix_memalign is declared.
+       (gl_STDLIB_H_DEFAULTS): Initialize GNULIB_POSIX_MEMALIGN,
+       HAVE_POSIX_MEMALIGN, REPLACE_POSIX_MEMALIGN.
+       * modules/stdlib (Makefile.am): Substitute GNULIB_POSIX_MEMALIGN,
+       HAVE_POSIX_MEMALIGN, REPLACE_POSIX_MEMALIGN.
+       * modules/posix_memalign: New file.
+       * tests/test-stdlib-c++.cc (posix_memalign): Check signature.
+       * doc/posix-functions/posix_memalign.texi: Mention the new module and
+       the OpenBSD bug.
+
 2020-11-03  Bruno Haible  <bruno@clisp.org>
 
        memalign: Add tests.
index 084841bd9af584cc35c8b699287a2398ac8567a5..7f58c691fcddb83ef3f5f2cd23c6a7015388ebe9 100644 (file)
@@ -4,10 +4,13 @@
 
 POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html}
 
-Gnulib module: ---
+Gnulib module: posix_memalign
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function produces misaligned results on some platforms:
+OpenBSD 6.1.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/lib/posix_memalign.c b/lib/posix_memalign.c
new file mode 100644 (file)
index 0000000..ef85768
--- /dev/null
@@ -0,0 +1,35 @@
+/* A posix_memalign() function that works around platform bugs.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <stdlib.h>
+
+#include <errno.h>
+
+int
+posix_memalign (void **memptr, size_t alignment, size_t size)
+#undef posix_memalign
+{
+  /* Round up SIZE to the next multiple of ALIGNMENT, namely
+     (SIZE + ALIGNMENT - 1) & ~(ALIGNMENT - 1).  */
+  size += alignment - 1;
+  if (size >= alignment - 1) /* no overflow? */
+    return posix_memalign (memptr, alignment, size & ~(size_t)(alignment - 1));
+  else
+    return ENOMEM;
+}
index 47a1309e633dceddb9490698dba0e5855936e84c..58e4bba0a8f816910c1b46911a3e009f2bc9e62b 100644 (file)
@@ -488,6 +488,35 @@ _GL_WARN_ON_USE (mkstemps, "mkstemps is unportable - "
 # define mktemp _mktemp
 #endif
 
+/* Allocate memory with indefinite extent and specified alignment.  */
+#if @GNULIB_POSIX_MEMALIGN@
+# if @REPLACE_POSIX_MEMALIGN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef posix_memalign
+#   define posix_memalign rpl_posix_memalign
+#  endif
+_GL_FUNCDECL_RPL (posix_memalign, int,
+                  (void **memptr, size_t alignment, size_t size)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_memalign, int,
+                  (void **memptr, size_t alignment, size_t size));
+# else
+#  if @HAVE_POSIX_MEMALIGN@
+_GL_CXXALIAS_SYS (posix_memalign, int,
+                  (void **memptr, size_t alignment, size_t size));
+#  endif
+# endif
+# if @HAVE_POSIX_MEMALIGN@
+_GL_CXXALIASWARN (posix_memalign);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_memalign
+# if HAVE_RAW_DECL_POSIX_MEMALIGN
+_GL_WARN_ON_USE (posix_memalign, "posix_memalign is not portable - "
+                 "use gnulib module posix_memalign for portability");
+# endif
+#endif
+
 #if @GNULIB_POSIX_OPENPT@
 /* Return an FD open to the master side of a pseudo-terminal.  Flags should
    include O_RDWR, and may also include O_NOCTTY.  */
diff --git a/m4/posix_memalign.m4 b/m4/posix_memalign.m4
new file mode 100644 (file)
index 0000000..67c11b9
--- /dev/null
@@ -0,0 +1,50 @@
+# posix_memalign.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.
+
+AC_DEFUN([gl_FUNC_POSIX_MEMALIGN],
+[
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+  dnl Persuade glibc <stdlib.h> to declare posix_memalign().
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  AC_CHECK_FUNCS_ONCE([posix_memalign])
+  if test $ac_cv_func_posix_memalign = yes; then
+    dnl On OpenBSD 6.1, posix_memalign (&p, 32, 2406) returns a pointer
+    dnl that is not a multiple of 32.
+    AC_CACHE_CHECK([whether posix_memalign works for large alignments],
+      [gl_cv_func_posix_memalign_works],
+      [AC_RUN_IFELSE(
+         [AC_LANG_PROGRAM(
+            [[#include <stdlib.h>
+            ]],
+            [[void *p;
+              if (posix_memalign (&p, 32, 2406) == 0)
+                if (((unsigned long)p % 32) != 0)
+                  return 1;
+              return 0;
+            ]])
+         ],
+         [gl_cv_func_posix_memalign_works=yes],
+         [gl_cv_func_posix_memalign_works=no],
+         [case "$host_os" in
+                      # Guess no on OpenBSD.
+            openbsd*) gl_cv_func_posix_memalign_works="guessing no" ;;
+                      # If we don't know, obey --enable-cross-guesses.
+            *)        gl_cv_func_posix_memalign_works="$gl_cross_guess_normal" ;;
+          esac
+         ])
+      ])
+    case "$gl_cv_func_posix_memalign_works" in
+      *yes) ;;
+      *) REPLACE_POSIX_MEMALIGN=1 ;;
+    esac
+  else
+    dnl The system does not have posix_memalign.
+    HAVE_POSIX_MEMALIGN=0
+  fi
+])
index 743066a6336f9c3632813ea8cabe9f42a099ddcc..d9b13b6d1f856720bb6ff2dbb36201a7b18e6fd7 100644 (file)
@@ -1,4 +1,4 @@
-# stdlib_h.m4 serial 49
+# stdlib_h.m4 serial 50
 dnl Copyright (C) 2007-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,
@@ -24,9 +24,10 @@ AC_DEFUN([gl_STDLIB_H],
 #endif
     ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt
     initstate initstate_r mbtowc mkdtemp mkostemp mkostemps mkstemp mkstemps
-    posix_openpt ptsname ptsname_r qsort_r random random_r reallocarray
-    realpath rpmatch secure_getenv setenv setstate setstate_r srandom
-    srandom_r strtod strtold strtoll strtoull unlockpt unsetenv])
+    posix_memalign posix_openpt ptsname ptsname_r qsort_r
+    random random_r reallocarray realpath rpmatch secure_getenv setenv
+    setstate setstate_r srandom srandom_r
+    strtod strtold strtoll strtoull unlockpt unsetenv])
 
   AC_REQUIRE([AC_C_RESTRICT])
 ])
@@ -56,6 +57,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   GNULIB_MKOSTEMPS=0;     AC_SUBST([GNULIB_MKOSTEMPS])
   GNULIB_MKSTEMP=0;       AC_SUBST([GNULIB_MKSTEMP])
   GNULIB_MKSTEMPS=0;      AC_SUBST([GNULIB_MKSTEMPS])
+  GNULIB_POSIX_MEMALIGN=0;AC_SUBST([GNULIB_POSIX_MEMALIGN])
   GNULIB_POSIX_OPENPT=0;  AC_SUBST([GNULIB_POSIX_OPENPT])
   GNULIB_PTSNAME=0;       AC_SUBST([GNULIB_PTSNAME])
   GNULIB_PTSNAME_R=0;     AC_SUBST([GNULIB_PTSNAME_R])
@@ -92,6 +94,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   HAVE_MKOSTEMPS=1;          AC_SUBST([HAVE_MKOSTEMPS])
   HAVE_MKSTEMP=1;            AC_SUBST([HAVE_MKSTEMP])
   HAVE_MKSTEMPS=1;           AC_SUBST([HAVE_MKSTEMPS])
+  HAVE_POSIX_MEMALIGN=1;     AC_SUBST([HAVE_POSIX_MEMALIGN])
   HAVE_POSIX_OPENPT=1;       AC_SUBST([HAVE_POSIX_OPENPT])
   HAVE_PTSNAME=1;            AC_SUBST([HAVE_PTSNAME])
   HAVE_PTSNAME_R=1;          AC_SUBST([HAVE_PTSNAME_R])
@@ -121,6 +124,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   REPLACE_MALLOC=0;          AC_SUBST([REPLACE_MALLOC])
   REPLACE_MBTOWC=0;          AC_SUBST([REPLACE_MBTOWC])
   REPLACE_MKSTEMP=0;         AC_SUBST([REPLACE_MKSTEMP])
+  REPLACE_POSIX_MEMALIGN=0;  AC_SUBST([REPLACE_POSIX_MEMALIGN])
   REPLACE_PTSNAME=0;         AC_SUBST([REPLACE_PTSNAME])
   REPLACE_PTSNAME_R=0;       AC_SUBST([REPLACE_PTSNAME_R])
   REPLACE_PUTENV=0;          AC_SUBST([REPLACE_PUTENV])
diff --git a/modules/posix_memalign b/modules/posix_memalign
new file mode 100644 (file)
index 0000000..86e8a52
--- /dev/null
@@ -0,0 +1,28 @@
+Description:
+Allocate memory with indefinite extent and specified alignment.
+
+Files:
+lib/posix_memalign.c
+m4/posix_memalign.m4
+
+Depends-on:
+extensions
+stdlib
+
+configure.ac:
+gl_FUNC_POSIX_MEMALIGN
+if test $REPLACE_POSIX_MEMALIGN = 1; then
+  AC_LIBOBJ([posix_memalign])
+fi
+gl_STDLIB_MODULE_INDICATOR([posix_memalign])
+
+Makefile.am:
+
+Include:
+<stdlib.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+all
index ea838c91702511c28a225eeb8556fc3e0335a2a3..df533a96e2ccb788cb6aa5fce78aec942c999f07 100644 (file)
@@ -45,6 +45,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
              -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \
              -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \
              -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \
+             -e 's/@''GNULIB_POSIX_MEMALIGN''@/$(GNULIB_POSIX_MEMALIGN)/g' \
              -e 's/@''GNULIB_POSIX_OPENPT''@/$(GNULIB_POSIX_OPENPT)/g' \
              -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \
              -e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \
@@ -81,6 +82,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
              -e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \
              -e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \
              -e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \
+             -e 's|@''HAVE_POSIX_MEMALIGN''@|$(HAVE_POSIX_MEMALIGN)|g' \
              -e 's|@''HAVE_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \
              -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \
              -e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \
@@ -109,6 +111,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
              -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \
              -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \
              -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
+             -e 's|@''REPLACE_POSIX_MEMALIGN''@|$(REPLACE_POSIX_MEMALIGN)|g' \
              -e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \
              -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \
              -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
index 405c8144d53dcde745c02572d13634658da3d6ee..25b1c3d44436038ae9485f8ee9d755e2722ce7dc 100644 (file)
@@ -85,6 +85,11 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::mkstemp, int, (char *));
 SIGNATURE_CHECK (GNULIB_NAMESPACE::mkstemps, int, (char *, int));
 #endif
 
+#if GNULIB_TEST_POSIX_MEMALIGN && HAVE_POSIX_MEMALIGN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_memalign, int,
+                 (void **, size_t, size_t));
+#endif
+
 #if GNULIB_TEST_POSIX_OPENPT
 SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_openpt, int, (int));
 #endif