>From d8de841b650d9dd635b8ea7a494f3b1cb82bd20d Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 4 Nov 2020 02:22:33 +0100 Subject: [PATCH 1/2] aligned_alloc: New module. * lib/stdlib.in.h (aligned_alloc): New declaration. * lib/aligned_alloc.c: New file. * m4/aligned_alloc.m4: New file. * m4/stdlib_h.m4 (gl_STDLIB_H): Test whether aligned_alloc is declared. (gl_STDLIB_H_DEFAULTS): Initialize GNULIB_ALIGNED_ALLOC, HAVE_ALIGNED_ALLOC, REPLACE_ALIGNED_ALLOC. * modules/stdlib (Makefile.am): Substitute GNULIB_ALIGNED_ALLOC, HAVE_ALIGNED_ALLOC, REPLACE_ALIGNED_ALLOC. * modules/aligned_alloc: New file. * tests/test-stdlib-c++.cc (aligned_alloc): Check signature. * doc/posix-functions/aligned_alloc.texi: Mention the new module and the AIX bug. --- ChangeLog | 16 ++++++++++++ doc/posix-functions/aligned_alloc.texi | 5 +++- lib/aligned_alloc.c | 30 ++++++++++++++++++++++ lib/stdlib.in.h | 25 ++++++++++++++++++ m4/aligned_alloc.m4 | 46 ++++++++++++++++++++++++++++++++++ m4/stdlib_h.m4 | 8 ++++-- modules/aligned_alloc | 28 +++++++++++++++++++++ modules/stdlib | 3 +++ tests/test-stdlib-c++.cc | 4 +++ 9 files changed, 162 insertions(+), 3 deletions(-) create mode 100644 lib/aligned_alloc.c create mode 100644 m4/aligned_alloc.m4 create mode 100644 modules/aligned_alloc diff --git a/ChangeLog b/ChangeLog index e4f606e..473a112 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,21 @@ 2020-11-03 Bruno Haible + aligned_alloc: New module. + * lib/stdlib.in.h (aligned_alloc): New declaration. + * lib/aligned_alloc.c: New file. + * m4/aligned_alloc.m4: New file. + * m4/stdlib_h.m4 (gl_STDLIB_H): Test whether aligned_alloc is declared. + (gl_STDLIB_H_DEFAULTS): Initialize GNULIB_ALIGNED_ALLOC, + HAVE_ALIGNED_ALLOC, REPLACE_ALIGNED_ALLOC. + * modules/stdlib (Makefile.am): Substitute GNULIB_ALIGNED_ALLOC, + HAVE_ALIGNED_ALLOC, REPLACE_ALIGNED_ALLOC. + * modules/aligned_alloc: New file. + * tests/test-stdlib-c++.cc (aligned_alloc): Check signature. + * doc/posix-functions/aligned_alloc.texi: Mention the new module and the + AIX bug. + +2020-11-03 Bruno Haible + posix_memalign: Add tests. * tests/test-posix_memalign.c: New file. * modules/posix_memalign-tests: New file. diff --git a/doc/posix-functions/aligned_alloc.texi b/doc/posix-functions/aligned_alloc.texi index d7a0e6f..ff21678 100644 --- a/doc/posix-functions/aligned_alloc.texi +++ b/doc/posix-functions/aligned_alloc.texi @@ -4,10 +4,13 @@ Documentation:@* @uref{https://www.kernel.org/doc/man-pages/online/pages/man3/aligned_alloc.3.html,,man aligned_alloc} -Gnulib module: --- +Gnulib module: aligned_alloc Portability problems fixed by Gnulib: @itemize +This function fails if the alignment argument is smaller than +@code{sizeof (void *)} on some platforms: +AIX 7.2. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/aligned_alloc.c b/lib/aligned_alloc.c new file mode 100644 index 0000000..1c6638d --- /dev/null +++ b/lib/aligned_alloc.c @@ -0,0 +1,30 @@ +/* An aligned_alloc() 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 + +void * +aligned_alloc (size_t alignment, size_t size) +#undef aligned_alloc +{ + if (alignment >= sizeof (void *)) + return aligned_alloc (alignment, size); + else + return malloc (size); +} diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 58e4bba..ee0499a 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -149,6 +149,31 @@ _GL_WARN_ON_USE (_Exit, "_Exit is unportable - " #endif +/* Allocate memory with indefinite extent and specified alignment. */ +#if @GNULIB_ALIGNED_ALLOC@ +# if @REPLACE_ALIGNED_ALLOC@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef aligned_alloc +# define aligned_alloc rpl_aligned_alloc +# endif +_GL_FUNCDECL_RPL (aligned_alloc, void *, (size_t alignment, size_t size)); +_GL_CXXALIAS_RPL (aligned_alloc, void *, (size_t alignment, size_t size)); +# else +# if @HAVE_ALIGNED_ALLOC@ +_GL_CXXALIAS_SYS (aligned_alloc, void *, (size_t alignment, size_t size)); +# endif +# endif +# if @HAVE_ALIGNED_ALLOC@ +_GL_CXXALIASWARN (aligned_alloc); +# endif +#elif defined GNULIB_POSIXCHECK +# undef aligned_alloc +# if HAVE_RAW_DECL_ALIGNED_ALLOC +_GL_WARN_ON_USE (aligned_alloc, "aligned_alloc is not portable - " + "use gnulib module aligned_alloc for portability"); +# endif +#endif + #if @GNULIB_ATOLL@ /* Parse a signed decimal integer. Returns the value of the integer. Errors are not detected. */ diff --git a/m4/aligned_alloc.m4 b/m4/aligned_alloc.m4 new file mode 100644 index 0000000..2697e96 --- /dev/null +++ b/m4/aligned_alloc.m4 @@ -0,0 +1,46 @@ +# aligned_alloc.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_ALIGNED_ALLOC], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Persuade glibc to declare aligned_alloc(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_FUNCS_ONCE([aligned_alloc]) + if test $ac_cv_func_aligned_alloc = yes; then + dnl On AIX 7.2, aligned_alloc returns NULL when the alignment argument is + dnl smaller than sizeof (void *). + AC_CACHE_CHECK([whether aligned_alloc works for small alignments], + [gl_cv_func_aligned_alloc_works], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], + [[return aligned_alloc (2, 18) == NULL; + ]]) + ], + [gl_cv_func_aligned_alloc_works=yes], + [gl_cv_func_aligned_alloc_works=no], + [case "$host_os" in + # Guess no on AIX. + aix*) gl_cv_func_aligned_alloc_works="guessing no" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_aligned_alloc_works="$gl_cross_guess_normal" ;; + esac + ]) + ]) + case "$gl_cv_func_aligned_alloc_works" in + *yes) ;; + *) REPLACE_ALIGNED_ALLOC=1 ;; + esac + else + dnl The system does not have aligned_alloc. + HAVE_ALIGNED_ALLOC=0 + fi +]) diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index d9b13b6..7e81f3a 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -1,4 +1,4 @@ -# stdlib_h.m4 serial 50 +# stdlib_h.m4 serial 51 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, @@ -22,7 +22,8 @@ AC_DEFUN([gl_STDLIB_H], #if HAVE_RANDOM_H # include #endif - ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt + ]], [_Exit aligned_alloc atoll canonicalize_file_name + getloadavg getsubopt grantpt initstate initstate_r mbtowc mkdtemp mkostemp mkostemps mkstemp mkstemps posix_memalign posix_openpt ptsname ptsname_r qsort_r random random_r reallocarray realpath rpmatch secure_getenv setenv @@ -44,6 +45,7 @@ AC_DEFUN([gl_STDLIB_MODULE_INDICATOR], AC_DEFUN([gl_STDLIB_H_DEFAULTS], [ GNULIB__EXIT=0; AC_SUBST([GNULIB__EXIT]) + GNULIB_ALIGNED_ALLOC=0; AC_SUBST([GNULIB_ALIGNED_ALLOC]) GNULIB_ATOLL=0; AC_SUBST([GNULIB_ATOLL]) GNULIB_CALLOC_POSIX=0; AC_SUBST([GNULIB_CALLOC_POSIX]) GNULIB_CANONICALIZE_FILE_NAME=0; AC_SUBST([GNULIB_CANONICALIZE_FILE_NAME]) @@ -81,6 +83,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], GNULIB_WCTOMB=0; AC_SUBST([GNULIB_WCTOMB]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE__EXIT=1; AC_SUBST([HAVE__EXIT]) + HAVE_ALIGNED_ALLOC=1; AC_SUBST([HAVE_ALIGNED_ALLOC]) HAVE_ATOLL=1; AC_SUBST([HAVE_ATOLL]) HAVE_CANONICALIZE_FILE_NAME=1; AC_SUBST([HAVE_CANONICALIZE_FILE_NAME]) HAVE_DECL_GETLOADAVG=1; AC_SUBST([HAVE_DECL_GETLOADAVG]) @@ -118,6 +121,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], HAVE_SYS_LOADAVG_H=0; AC_SUBST([HAVE_SYS_LOADAVG_H]) HAVE_UNLOCKPT=1; AC_SUBST([HAVE_UNLOCKPT]) HAVE_DECL_UNSETENV=1; AC_SUBST([HAVE_DECL_UNSETENV]) + REPLACE_ALIGNED_ALLOC=0; AC_SUBST([REPLACE_ALIGNED_ALLOC]) REPLACE_CALLOC=0; AC_SUBST([REPLACE_CALLOC]) REPLACE_CANONICALIZE_FILE_NAME=0; AC_SUBST([REPLACE_CANONICALIZE_FILE_NAME]) REPLACE_INITSTATE=0; AC_SUBST([REPLACE_INITSTATE]) diff --git a/modules/aligned_alloc b/modules/aligned_alloc new file mode 100644 index 0000000..f7757f4 --- /dev/null +++ b/modules/aligned_alloc @@ -0,0 +1,28 @@ +Description: +Allocate memory with indefinite extent and specified alignment. + +Files: +lib/aligned_alloc.c +m4/aligned_alloc.m4 + +Depends-on: +extensions +stdlib + +configure.ac: +gl_FUNC_ALIGNED_ALLOC +if test $REPLACE_ALIGNED_ALLOC = 1; then + AC_LIBOBJ([aligned_alloc]) +fi +gl_STDLIB_MODULE_INDICATOR([aligned_alloc]) + +Makefile.am: + +Include: + + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/stdlib b/modules/stdlib index df533a9..032a2e6 100644 --- a/modules/stdlib +++ b/modules/stdlib @@ -32,6 +32,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ -e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \ + -e 's/@''GNULIB_ALIGNED_ALLOC''@/$(GNULIB_ALIGNED_ALLOC)/g' \ -e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \ -e 's/@''GNULIB_CALLOC_POSIX''@/$(GNULIB_CALLOC_POSIX)/g' \ -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \ @@ -69,6 +70,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \ < $(srcdir)/stdlib.in.h | \ sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ + -e 's|@''HAVE_ALIGNED_ALLOC''@|$(HAVE_ALIGNED_ALLOC)|g' \ -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \ -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \ -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \ @@ -105,6 +107,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \ -e 's|@''HAVE_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \ -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \ + -e 's|@''REPLACE_ALIGNED_ALLOC''@|$(REPLACE_ALIGNED_ALLOC)|g' \ -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \ -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \ -e 's|@''REPLACE_INITSTATE''@|$(REPLACE_INITSTATE)|g' \ diff --git a/tests/test-stdlib-c++.cc b/tests/test-stdlib-c++.cc index 25b1c3d..09bae83 100644 --- a/tests/test-stdlib-c++.cc +++ b/tests/test-stdlib-c++.cc @@ -28,6 +28,10 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::_Exit, void, (int)); #endif +#if GNULIB_TEST_ALIGNED_ALLOC && HAVE_ALIGNED_ALLOC +SIGNATURE_CHECK (GNULIB_NAMESPACE::aligned_alloc, void *, (size_t, size_t)); +#endif + //SIGNATURE_CHECK (GNULIB_NAMESPACE::atexit, int, (void (*) (void))); #if GNULIB_TEST_ATOLL -- 2.7.4