>From 419322ec4c4c6ff1df518378d86162b7a53bf2c0 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 4 Nov 2020 02:19:08 +0100 Subject: [PATCH 1/2] 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. --- ChangeLog | 16 +++++++++++ doc/posix-functions/posix_memalign.texi | 5 +++- lib/posix_memalign.c | 35 +++++++++++++++++++++++ lib/stdlib.in.h | 29 +++++++++++++++++++ m4/posix_memalign.m4 | 50 +++++++++++++++++++++++++++++++++ m4/stdlib_h.m4 | 12 +++++--- modules/posix_memalign | 28 ++++++++++++++++++ modules/stdlib | 3 ++ tests/test-stdlib-c++.cc | 5 ++++ 9 files changed, 178 insertions(+), 5 deletions(-) create mode 100644 lib/posix_memalign.c create mode 100644 m4/posix_memalign.m4 create mode 100644 modules/posix_memalign diff --git a/ChangeLog b/ChangeLog index e608993..fd72d3e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,21 @@ 2020-11-03 Bruno Haible + 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 + memalign: Add tests. * tests/test-memalign.c: New file. * modules/memalign-tests: New file. diff --git a/doc/posix-functions/posix_memalign.texi b/doc/posix-functions/posix_memalign.texi index 084841b..7f58c69 100644 --- a/doc/posix-functions/posix_memalign.texi +++ b/doc/posix-functions/posix_memalign.texi @@ -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 index 0000000..ef85768 --- /dev/null +++ b/lib/posix_memalign.c @@ -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 . */ + +#include + +/* Specification. */ +#include + +#include + +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; +} diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 47a1309..58e4bba 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -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 index 0000000..67c11b9 --- /dev/null +++ b/m4/posix_memalign.m4 @@ -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 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 + ]], + [[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 +]) diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index 743066a..d9b13b6 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -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 index 0000000..86e8a52 --- /dev/null +++ b/modules/posix_memalign @@ -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: + + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/stdlib b/modules/stdlib index ea838c9..df533a9 100644 --- a/modules/stdlib +++ b/modules/stdlib @@ -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' \ diff --git a/tests/test-stdlib-c++.cc b/tests/test-stdlib-c++.cc index 405c814..25b1c3d 100644 --- a/tests/test-stdlib-c++.cc +++ b/tests/test-stdlib-c++.cc @@ -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 -- 2.7.4