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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
+
+ 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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
+ 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