On AIX 7.3.1, I see these two test failures: FAIL: test-thrd_create ======================
../../gltests/test-thrd_create.c:61: assertion 'ret == MAGIC' failed FAIL test-thrd_create (exit status: 134) FAIL: test-thrd_exit ==================== ../../gltests/test-thrd_exit.c:65: assertion 'ret == MAGIC' failed FAIL test-thrd_exit (exit status: 134) The cause is: - In AIX 7.[12], the type thrd_start_t is broken, and accordingly it was impossible to implement thrd_join correctly, since the exit code types did not match. - In AIX 7.3.1 they fixed the thrd_start_t type. But the thrd_join is still broken, for no good reason. This patch adds a workaround. 2023-08-18 Bruno Haible <br...@clisp.org> thrd: Work around thrd_join bug on AIX 7.3.1. * m4/threads_h.m4 (gl_THREADS_H): Test against AIX 7 thrd_join bug. Set BROKEN_THRD_JOIN. (gl_THREADS_H_DEFAULTS): Initialize BROKEN_THRD_JOIN. * m4/thrd.m4 (gl_FUNC_THRD_JOIN): Set REPLACE_THRD_* to 1 also if BROKEN_THRD_JOIN is 1. Define BROKEN_THRD_START_T_OR_JOIN instead of BROKEN_THRD_START_T. * modules/threads-h (Makefile.am): Substitute BROKEN_THRD_JOIN. * lib/threads.in.h (rpl_thrd_t, thrd_t): Define also if BROKEN_THRD_JOIN is 1. * lib/thrd.c: Test BROKEN_THRD_START_T_OR_JOIN instead of BROKEN_THRD_START_T. * doc/posix-functions/thrd_join.texi: Update. * doc/posix-functions/thrd_exit.texi: Likewise. thrd: Refactor. * m4/thrd.m4 (gl_FUNC_THRD_JOIN): Define BROKEN_THRD_JOIN_NULL, not BROKEN_THRD_JOIN. Rename gl_cv_func_thrd_join_works to gl_cv_func_thrd_join_null_works. * lib/thrd.c: Test BROKEN_THRD_JOIN_NULL instead of BROKEN_THRD_JOIN.
>From 51511a7a964f114eee12f34946e1b517c6e56d85 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 18 Aug 2023 21:14:40 +0200 Subject: [PATCH 1/2] thrd: Refactor. * m4/thrd.m4 (gl_FUNC_THRD_JOIN): Define BROKEN_THRD_JOIN_NULL, not BROKEN_THRD_JOIN. Rename gl_cv_func_thrd_join_works to gl_cv_func_thrd_join_null_works. * lib/thrd.c: Test BROKEN_THRD_JOIN_NULL instead of BROKEN_THRD_JOIN. --- ChangeLog | 8 ++++++++ lib/thrd.c | 2 +- m4/thrd.m4 | 20 ++++++++++---------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index b2c277f64d..7afaa9a0eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2023-08-18 Bruno Haible <br...@clisp.org> + + thrd: Refactor. + * m4/thrd.m4 (gl_FUNC_THRD_JOIN): Define BROKEN_THRD_JOIN_NULL, not + BROKEN_THRD_JOIN. Rename gl_cv_func_thrd_join_works to + gl_cv_func_thrd_join_null_works. + * lib/thrd.c: Test BROKEN_THRD_JOIN_NULL instead of BROKEN_THRD_JOIN. + 2023-08-18 Bruno Haible <br...@clisp.org> thrd tests: Add unit test for thrd_exit. diff --git a/lib/thrd.c b/lib/thrd.c index 9abea10a2c..d36cc894de 100644 --- a/lib/thrd.c +++ b/lib/thrd.c @@ -220,7 +220,7 @@ rpl_thrd_exit (int exitcode) # endif -# if BROKEN_THRD_JOIN +# if BROKEN_THRD_JOIN_NULL /* On Solaris 11.4, thrd_join crashes when the second argument is NULL. */ int diff --git a/m4/thrd.m4 b/m4/thrd.m4 index fed111695f..1c0a611ae2 100644 --- a/m4/thrd.m4 +++ b/m4/thrd.m4 @@ -1,4 +1,4 @@ -# thrd.m4 serial 2 +# thrd.m4 serial 3 dnl Copyright (C) 2019-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -25,8 +25,8 @@ AC_DEFUN([gl_FUNC_THRD_JOIN] fi dnl On Solaris 11.4, thrd_join crashes when the second argument is NULL. - AC_CACHE_CHECK([whether thrd_join works], - [gl_cv_func_thrd_join_works], + AC_CACHE_CHECK([whether thrd_join with NULL argument works], + [gl_cv_func_thrd_join_null_works], [save_LIBS="$LIBS" LIBS="$LIBS $LIBSTDTHREAD" AC_RUN_IFELSE( @@ -45,22 +45,22 @@ AC_DEFUN([gl_FUNC_THRD_JOIN] return 2; return 0; ]])], - [gl_cv_func_thrd_join_works=yes], - [gl_cv_func_thrd_join_works=no], + [gl_cv_func_thrd_join_null_works=yes], + [gl_cv_func_thrd_join_null_works=no], [case "$host_os" in # Only Solaris is known to be broken. - solaris*) gl_cv_func_thrd_join_works="guessing no" ;; - *) gl_cv_func_thrd_join_works="guessing yes" ;; + solaris*) gl_cv_func_thrd_join_null_works="guessing no" ;; + *) gl_cv_func_thrd_join_null_works="guessing yes" ;; esac ]) LIBS="$save_LIBS" ]) - case "$gl_cv_func_thrd_join_works" in + case "$gl_cv_func_thrd_join_null_works" in *yes) ;; *) REPLACE_THRD_JOIN=1 - AC_DEFINE([BROKEN_THRD_JOIN], [1], - [Define if the thrd_join function does not behave as in ISO C 11.]) + AC_DEFINE([BROKEN_THRD_JOIN_NULL], [1], + [Define if the thrd_join function, when given a NULL argument, does not behave as in ISO C 11.]) ;; esac fi -- 2.34.1
>From 2d963d69277dd30563312b0311af3cb53a9d142e Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 18 Aug 2023 22:38:04 +0200 Subject: [PATCH 2/2] thrd: Work around thrd_join bug on AIX 7.3.1. * m4/threads_h.m4 (gl_THREADS_H): Test against AIX 7 thrd_join bug. Set BROKEN_THRD_JOIN. (gl_THREADS_H_DEFAULTS): Initialize BROKEN_THRD_JOIN. * m4/thrd.m4 (gl_FUNC_THRD_JOIN): Set REPLACE_THRD_* to 1 also if BROKEN_THRD_JOIN is 1. Define BROKEN_THRD_START_T_OR_JOIN instead of BROKEN_THRD_START_T. * modules/threads-h (Makefile.am): Substitute BROKEN_THRD_JOIN. * lib/threads.in.h (rpl_thrd_t, thrd_t): Define also if BROKEN_THRD_JOIN is 1. * lib/thrd.c: Test BROKEN_THRD_START_T_OR_JOIN instead of BROKEN_THRD_START_T. * doc/posix-functions/thrd_join.texi: Update. * doc/posix-functions/thrd_exit.texi: Likewise. --- ChangeLog | 15 +++++++++++ doc/posix-functions/thrd_exit.texi | 2 +- doc/posix-functions/thrd_join.texi | 2 +- lib/thrd.c | 6 +++-- lib/threads.in.h | 2 ++ m4/thrd.m4 | 8 +++--- m4/threads_h.m4 | 43 +++++++++++++++++++++++++++++- modules/threads-h | 1 + 8 files changed, 70 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7afaa9a0eb..f588ef0128 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2023-08-18 Bruno Haible <br...@clisp.org> + thrd: Work around thrd_join bug on AIX 7.3.1. + * m4/threads_h.m4 (gl_THREADS_H): Test against AIX 7 thrd_join bug. Set + BROKEN_THRD_JOIN. + (gl_THREADS_H_DEFAULTS): Initialize BROKEN_THRD_JOIN. + * m4/thrd.m4 (gl_FUNC_THRD_JOIN): Set REPLACE_THRD_* to 1 also if + BROKEN_THRD_JOIN is 1. Define BROKEN_THRD_START_T_OR_JOIN instead of + BROKEN_THRD_START_T. + * modules/threads-h (Makefile.am): Substitute BROKEN_THRD_JOIN. + * lib/threads.in.h (rpl_thrd_t, thrd_t): Define also if BROKEN_THRD_JOIN + is 1. + * lib/thrd.c: Test BROKEN_THRD_START_T_OR_JOIN instead of + BROKEN_THRD_START_T. + * doc/posix-functions/thrd_join.texi: Update. + * doc/posix-functions/thrd_exit.texi: Likewise. + thrd: Refactor. * m4/thrd.m4 (gl_FUNC_THRD_JOIN): Define BROKEN_THRD_JOIN_NULL, not BROKEN_THRD_JOIN. Rename gl_cv_func_thrd_join_works to diff --git a/doc/posix-functions/thrd_exit.texi b/doc/posix-functions/thrd_exit.texi index a0e6e0983c..d212ce8d50 100644 --- a/doc/posix-functions/thrd_exit.texi +++ b/doc/posix-functions/thrd_exit.texi @@ -19,7 +19,7 @@ glibc 2.27, macOS 11.1, FreeBSD 9.3, NetBSD 8.0, OpenBSD 6.7, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.3, Cygwin 2.9, mingw, MSVC 14, Android 9.0. @item The exit code provided to this function is discarded on some platforms: -AIX 7.2. +AIX 7.3.1. @end itemize Portability problems not fixed by Gnulib: diff --git a/doc/posix-functions/thrd_join.texi b/doc/posix-functions/thrd_join.texi index 874212a99a..06c4ce9f7f 100644 --- a/doc/posix-functions/thrd_join.texi +++ b/doc/posix-functions/thrd_join.texi @@ -19,7 +19,7 @@ glibc 2.27, macOS 11.1, FreeBSD 9.3, NetBSD 8.0, OpenBSD 6.7, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.3, Cygwin 2.9, mingw, MSVC 14, Android 9.0. @item This function never stores an exit code on some platforms: -AIX 7.2. +AIX 7.3.1. @item This function crashes when the second argument is NULL on some platforms: Solaris 11.4. diff --git a/lib/thrd.c b/lib/thrd.c index d36cc894de..a71de9b8d2 100644 --- a/lib/thrd.c +++ b/lib/thrd.c @@ -26,13 +26,15 @@ #if HAVE_THREADS_H /* Provide workarounds. */ -# if BROKEN_THRD_START_T +# if BROKEN_THRD_START_T_OR_JOIN # undef thrd_t /* AIX 7.1..7.2 defines thrd_start_t incorrectly, namely as 'void * (*) (void *)' instead of 'int (*) (void *)'. - As a consequence, its thrd_join function never stores an exit code. */ + As a consequence, its thrd_join function never stores an exit code. + AIX 7.3.1 has a corrected thrd_start_t. But the thrd_join function still + never stores an exit code. */ /* The Thread-Specific Storage (TSS) key that allows to access each thread's 'struct thrd_with_exitcode *' pointer. */ diff --git a/lib/threads.in.h b/lib/threads.in.h index 6d1769cc53..dbf0c40538 100644 --- a/lib/threads.in.h +++ b/lib/threads.in.h @@ -139,6 +139,8 @@ typedef pthread_t thrd_t; #if @BROKEN_THRD_START_T@ /* Need to override thrd_start_t, to make thrd_create work. */ # define thrd_start_t rpl_thrd_start_t +#endif +#if @BROKEN_THRD_START_T@ || @BROKEN_THRD_JOIN@ /* Need to override thrd_t, to make thrd_join work. */ struct thrd_with_exitcode { diff --git a/m4/thrd.m4 b/m4/thrd.m4 index 1c0a611ae2..cffce1efb6 100644 --- a/m4/thrd.m4 +++ b/m4/thrd.m4 @@ -1,4 +1,4 @@ -# thrd.m4 serial 3 +# thrd.m4 serial 4 dnl Copyright (C) 2019-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -10,15 +10,15 @@ AC_DEFUN([gl_FUNC_THRD_JOIN] AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles if test $ac_cv_header_threads_h = yes; then - if test $BROKEN_THRD_START_T = 1; then + if test $BROKEN_THRD_START_T = 1 || test $BROKEN_THRD_JOIN = 1; then REPLACE_THRD_CREATE=1 REPLACE_THRD_CURRENT=1 REPLACE_THRD_DETACH=1 REPLACE_THRD_EQUAL=1 REPLACE_THRD_EXIT=1 REPLACE_THRD_JOIN=1 - AC_DEFINE([BROKEN_THRD_START_T], [1], - [Define if the thrd_start_t type is not as described in ISO C 11.]) + AC_DEFINE([BROKEN_THRD_START_T_OR_JOIN], [1], + [Define if the thrd_start_t type is not as described in ISO C 11 or if thrd_join discards the thread's exit code.]) dnl The thrd_exit replacement relies on pthread_exit, which on AIX is in dnl libpthread. LIBSTDTHREAD="$LIBSTDTHREAD $LIBPTHREAD" diff --git a/m4/threads_h.m4 b/m4/threads_h.m4 index f74c146173..1c63c7e1b7 100644 --- a/m4/threads_h.m4 +++ b/m4/threads_h.m4 @@ -1,4 +1,4 @@ -# threads_h.m4 serial 12 +# threads_h.m4 serial 13 dnl Copyright (C) 2019-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -45,6 +45,46 @@ AC_DEFUN_ONCE([gl_THREADS_H] ]) if test $gl_cv_thrd_start_t_correct != yes; then BROKEN_THRD_START_T=1 + else + dnl On AIX 7.3.1, thrd_join still never stores an exit code. + AC_CACHE_CHECK([whether thrd_join works], + [gl_cv_func_thrd_join_works], + [save_LIBS="$LIBS" + LIBS="$LIBS $LIBSTDTHREAD" + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include <stddef.h> + #include <threads.h> + #define MAGIC 1266074729 + static int func (void *arg) + { + return MAGIC; + } + ]], + [[thrd_t thread; + if (thrd_create (&thread, func, NULL) != thrd_success) + return 1; + int ret = 0xDEADBEEF; + if (thrd_join (thread, &ret) != thrd_success) + return 2; + if (ret != MAGIC) + return (ret == 0xDEADBEEF ? 3 : 4); + return 0; + ]])], + [gl_cv_func_thrd_join_works=yes], + [gl_cv_func_thrd_join_works=no], + [case "$host_os" in + # Only AIX is known to be broken. + aix*) gl_cv_func_thrd_join_works="guessing no" ;; + *) gl_cv_func_thrd_join_works="guessing yes" ;; + esac + ]) + LIBS="$save_LIBS" + ]) + case "$gl_cv_func_thrd_join_works" in + *yes) ;; + *) BROKEN_THRD_JOIN=1 ;; + esac fi fi @@ -170,6 +210,7 @@ AC_DEFUN([gl_THREADS_H_DEFAULTS] [ dnl Assume proper GNU behavior unless another module says otherwise. HAVE_THREAD_LOCAL=1; AC_SUBST([HAVE_THREAD_LOCAL]) + BROKEN_THRD_JOIN=0; AC_SUBST([BROKEN_THRD_JOIN]) BROKEN_THRD_START_T=0; AC_SUBST([BROKEN_THRD_START_T]) REPLACE_THRD_CREATE=0; AC_SUBST([REPLACE_THRD_CREATE]) REPLACE_THRD_CURRENT=0; AC_SUBST([REPLACE_THRD_CURRENT]) diff --git a/modules/threads-h b/modules/threads-h index 2056df01f0..8e9da83eee 100644 --- a/modules/threads-h +++ b/modules/threads-h @@ -56,6 +56,7 @@ threads.h: threads.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(_NORETURN_H -e 's/@''GNULIB_THRD''@/$(GNULIB_THRD)/g' \ -e 's/@''GNULIB_TSS''@/$(GNULIB_TSS)/g' \ -e 's|@''HAVE_THREAD_LOCAL''@|$(HAVE_THREAD_LOCAL)|g' \ + -e 's|@''BROKEN_THRD_JOIN''@|$(BROKEN_THRD_JOIN)|g' \ -e 's|@''BROKEN_THRD_START_T''@|$(BROKEN_THRD_START_T)|g' \ -e 's|@''REPLACE_THRD_CREATE''@|$(REPLACE_THRD_CREATE)|g' \ -e 's|@''REPLACE_THRD_CURRENT''@|$(REPLACE_THRD_CURRENT)|g' \ -- 2.34.1