threads-h: New module.
authorBruno Haible <bruno@clisp.org>
Thu, 20 Jun 2019 02:17:30 +0000 (04:17 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 20 Jun 2019 02:25:34 +0000 (04:25 +0200)
* lib/threads.in.h: New file.
* m4/threads.m4: New file.
* m4/yield.m4 (gl_YIELD): Update comment.
* modules/threads-h: New file.
* modules/yields (configure.ac): Use AC_REQUIRE.
* doc/posix-headers/threads.texi: Mention the new module and the AIX
bugs.

ChangeLog
doc/posix-headers/threads.texi
lib/threads.in.h [new file with mode: 0644]
m4/threads.m4 [new file with mode: 0644]
m4/yield.m4
modules/threads-h [new file with mode: 0644]
modules/yield

index ab97f37093b1de255c35dd29bb6c3cb45b2f2bd3..22b942ba63627935757e271797e86e32f37dd20e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2019-06-20  Bruno Haible  <bruno@clisp.org>
+
+       threads-h: New module.
+       * lib/threads.in.h: New file.
+       * m4/threads.m4: New file.
+       * m4/yield.m4 (gl_YIELD): Update comment.
+       * modules/threads-h: New file.
+       * modules/yields (configure.ac): Use AC_REQUIRE.
+       * doc/posix-headers/threads.texi: Mention the new module and the AIX
+       bugs.
+
 2019-06-20  Bruno Haible  <bruno@clisp.org>
 
        windows-thread: New module.
index 989253918296e106f4f5f6b81d149fb1229bcd92..71ae43a48b329ee05f05e8e4bcc55be6d4a86b6c 100644 (file)
@@ -3,15 +3,21 @@
 
 Defines the multithreading facility of ISO C11.
 
-Gnulib module: ---
+Gnulib module: threads-h
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This header file is missing on many platforms:
+glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0.
+@item
+This header file defines @code{thrd_start_t} incorrectly on some platforms:
+AIX 7.2.
+@item
+This header file does not define @code{TSS_DTOR_ITERATIONS} on some platforms:
+AIX 7.2.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
-@item
-This header file is missing on many platforms:
-glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0.
 @end itemize
diff --git a/lib/threads.in.h b/lib/threads.in.h
new file mode 100644 (file)
index 0000000..a18d64b
--- /dev/null
@@ -0,0 +1,649 @@
+/* An ISO C 11 compatible <threads.h>.
+
+   Copyright (C) 2019 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 2, 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/>.  */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#ifndef _@GUARD_PREFIX@_THREADS_H
+
+/* The include_next requires a split double-inclusion guard.  */
+#if @HAVE_THREADS_H@
+# @INCLUDE_NEXT@ @NEXT_THREADS_H@
+#endif
+
+#ifndef _@GUARD_PREFIX@_THREADS_H
+#define _@GUARD_PREFIX@_THREADS_H
+
+#if !@HAVE_THREADS_H@
+
+# include <time.h>
+
+# if defined _WIN32 && ! defined __CYGWIN__
+/* Use Windows threads.  */
+
+#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
+#  include <windows.h>
+
+# else
+/* Use POSIX threads.  */
+
+#  include <pthread.h>
+
+# endif
+
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _Noreturn is copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+/* Storage class specifier for thread-local storage.  */
+#ifdef _AIX
+/* The macro definition from AIX 7.1..7.2 <threads.h> is unusable, because
+   its expansion ends in a semicolon.  */
+# undef thread_local
+#endif
+#if !@HAVE_THREADS_H@ || !defined thread_local
+# define thread_local _Thread_local
+#endif
+
+
+/* =========== ISO C 11 7.26.5 Thread functions =========== */
+
+#if !@HAVE_THREADS_H@
+
+/* Return codes.  */
+enum
+{
+  thrd_success  = 0,
+  thrd_timedout = 1,
+  thrd_busy     = 2,
+  thrd_nomem    = 3,
+  thrd_error    = 4
+};
+
+# if defined _WIN32 && ! defined __CYGWIN__
+/* Use Windows threads.  */
+
+#  include "windows-thread.h"
+
+typedef glwthread_thread_t thrd_t;
+
+# else
+/* Use POSIX threads.  */
+
+typedef pthread_t thrd_t;
+
+# endif
+
+#endif
+
+#if @BROKEN_THRD_START_T@
+/* Need to override thrd_start_t, to make thrd_create work.  */
+# define thrd_start_t rpl_thrd_start_t
+/* Need to override thrd_t, to make thrd_join work.  */
+struct thrd_with_exitcode
+{
+  thrd_t volatile tid;
+  int volatile detached;
+  int volatile exitcode;
+};
+typedef struct thrd_with_exitcode *rpl_thrd_t;
+# define thrd_t rpl_thrd_t
+#endif
+/* Type of the main function of a thread.  */
+#if !@HAVE_THREADS_H@ || @BROKEN_THRD_START_T@
+typedef int (* thrd_start_t) (void *);
+#endif
+
+#if @GNULIB_THRD@
+# if @REPLACE_THRD_CREATE@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define thrd_create rpl_thrd_create
+#  endif
+_GL_FUNCDECL_RPL (thrd_create, int, (thrd_t *, thrd_start_t, void *)
+                                    _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (thrd_create, int, (thrd_t *, thrd_start_t, void *));
+# else
+#  if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (thrd_create, int, (thrd_t *, thrd_start_t, void *)
+                                    _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (thrd_create, int, (thrd_t *, thrd_start_t, void *));
+# endif
+_GL_CXXALIASWARN (thrd_create);
+#elif defined GNULIB_POSIXCHECK
+# undef thrd_create
+# if HAVE_RAW_DECL_THRD_CREATE
+_GL_WARN_ON_USE (thrd_create, "thrd_create is unportable - "
+                 "use gnulib module thrd for portability");
+# endif
+#endif
+
+#if @GNULIB_THRD@
+# if @REPLACE_THRD_CURRENT@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define thrd_current rpl_thrd_current
+#  endif
+_GL_FUNCDECL_RPL (thrd_current, thrd_t, (void) _GL_ATTRIBUTE_PURE);
+_GL_CXXALIAS_RPL (thrd_current, thrd_t, (void));
+# else
+#  if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (thrd_current, thrd_t, (void) _GL_ATTRIBUTE_PURE);
+#  endif
+_GL_CXXALIAS_SYS (thrd_current, thrd_t, (void));
+# endif
+_GL_CXXALIASWARN (thrd_current);
+#elif defined GNULIB_POSIXCHECK
+# undef thrd_current
+# if HAVE_RAW_DECL_THRD_CURRENT
+_GL_WARN_ON_USE (thrd_current, "thrd_current is unportable - "
+                 "use gnulib module thrd for portability");
+# endif
+#endif
+
+#if @GNULIB_THRD@
+# if @REPLACE_THRD_EQUAL@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define thrd_equal rpl_thrd_equal
+#  endif
+_GL_FUNCDECL_RPL (thrd_equal, int, (thrd_t, thrd_t) _GL_ATTRIBUTE_PURE);
+_GL_CXXALIAS_RPL (thrd_equal, int, (thrd_t, thrd_t));
+# else
+#  if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (thrd_equal, int, (thrd_t, thrd_t) _GL_ATTRIBUTE_PURE);
+#  endif
+_GL_CXXALIAS_SYS (thrd_equal, int, (thrd_t, thrd_t));
+# endif
+_GL_CXXALIASWARN (thrd_equal);
+#elif defined GNULIB_POSIXCHECK
+# undef thrd_equal
+# if HAVE_RAW_DECL_THRD_EQUAL
+_GL_WARN_ON_USE (thrd_equal, "thrd_equal is unportable - "
+                 "use gnulib module thrd for portability");
+# endif
+#endif
+
+#if @GNULIB_THRD@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (thrd_sleep, int,
+                              (const struct timespec *, struct timespec *)
+                              _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (thrd_sleep, int,
+                              (const struct timespec *, struct timespec *));
+_GL_CXXALIASWARN (thrd_sleep);
+#elif defined GNULIB_POSIXCHECK
+# undef thrd_sleep
+# if HAVE_RAW_DECL_THRD_SLEEP
+_GL_WARN_ON_USE (thrd_sleep, "thrd_sleep is unportable - "
+                 "use gnulib module thrd for portability");
+# endif
+#endif
+
+#if @GNULIB_THRD@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (thrd_yield, void, (void));
+# endif
+_GL_CXXALIAS_SYS (thrd_yield, void, (void));
+_GL_CXXALIASWARN (thrd_yield);
+#elif defined GNULIB_POSIXCHECK
+# undef thrd_yield
+# if HAVE_RAW_DECL_THRD_YIELD
+_GL_WARN_ON_USE (thrd_yield, "thrd_yield is unportable - "
+                 "use gnulib module thrd for portability");
+# endif
+#endif
+
+#if @GNULIB_THRD@
+# if @REPLACE_THRD_DETACH@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define thrd_detach rpl_thrd_detach
+#  endif
+_GL_FUNCDECL_RPL (thrd_detach, int, (thrd_t));
+_GL_CXXALIAS_RPL (thrd_detach, int, (thrd_t));
+# else
+#  if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (thrd_detach, int, (thrd_t));
+#  endif
+_GL_CXXALIAS_SYS (thrd_detach, int, (thrd_t));
+# endif
+_GL_CXXALIASWARN (thrd_detach);
+#elif defined GNULIB_POSIXCHECK
+# undef thrd_detach
+# if HAVE_RAW_DECL_THRD_DETACH
+_GL_WARN_ON_USE (thrd_detach, "thrd_detach is unportable - "
+                 "use gnulib module thrd for portability");
+# endif
+#endif
+
+#if @GNULIB_THRD@
+# if @REPLACE_THRD_JOIN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define thrd_join rpl_thrd_join
+#  endif
+_GL_FUNCDECL_RPL (thrd_join, int, (thrd_t, int *));
+_GL_CXXALIAS_RPL (thrd_join, int, (thrd_t, int *));
+# else
+#  if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (thrd_join, int, (thrd_t, int *));
+#  endif
+_GL_CXXALIAS_SYS (thrd_join, int, (thrd_t, int *));
+# endif
+_GL_CXXALIASWARN (thrd_join);
+#elif defined GNULIB_POSIXCHECK
+# undef thrd_join
+# if HAVE_RAW_DECL_THRD_JOIN
+_GL_WARN_ON_USE (thrd_join, "thrd_join is unportable - "
+                 "use gnulib module thrd for portability");
+# endif
+#endif
+
+#if @GNULIB_THRD@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (thrd_exit, _Noreturn void, (int));
+# endif
+_GL_CXXALIAS_SYS (thrd_exit, _Noreturn void, (int));
+_GL_CXXALIASWARN (thrd_exit);
+#elif defined GNULIB_POSIXCHECK
+# undef thrd_exit
+# if HAVE_RAW_DECL_THRD_EXIT
+_GL_WARN_ON_USE (thrd_exit, "thrd_exit is unportable - "
+                 "use gnulib module thrd for portability");
+# endif
+#endif
+
+
+/* =========== ISO C 11 7.26.4 Mutex functions =========== */
+
+#if !@HAVE_THREADS_H@
+
+/* Types of mutexes.  */
+enum
+{
+  mtx_plain     = 0,
+  mtx_timed     = 1,
+  mtx_recursive = 2
+};
+
+# if defined _WIN32 && ! defined __CYGWIN__
+/* Use Windows threads.  */
+
+#  include "windows-mutex.h"
+#  include "windows-recmutex.h"
+#  include "windows-timedmutex.h"
+#  include "windows-timedrecmutex.h"
+
+typedef struct
+        {
+          int type;
+          union
+            {
+              glwthread_mutex_t         u_mutex;
+              glwthread_recmutex_t      u_recmutex;
+              glwthread_timedmutex_t    u_timedmutex;
+              glwthread_timedrecmutex_t u_timedrecmutex;
+            }
+          u;
+        }
+        mtx_t;
+
+# else
+/* Use POSIX threads.  */
+
+typedef pthread_mutex_t mtx_t;
+
+# endif
+
+#endif
+
+#if @GNULIB_MTX@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (mtx_init, int, (mtx_t *, int) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mtx_init, int, (mtx_t *, int));
+_GL_CXXALIASWARN (mtx_init);
+#elif defined GNULIB_POSIXCHECK
+# undef mtx_init
+# if HAVE_RAW_DECL_MTX_INIT
+_GL_WARN_ON_USE (mtx_init, "mtx_init is unportable - "
+                 "use gnulib module mtx for portability");
+# endif
+#endif
+
+#if @GNULIB_MTX@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (mtx_lock, int, (mtx_t *) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mtx_lock, int, (mtx_t *));
+_GL_CXXALIASWARN (mtx_lock);
+#elif defined GNULIB_POSIXCHECK
+# undef mtx_lock
+# if HAVE_RAW_DECL_MTX_LOCK
+_GL_WARN_ON_USE (mtx_lock, "mtx_lock is unportable - "
+                 "use gnulib module mtx for portability");
+# endif
+#endif
+
+#if @GNULIB_MTX@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (mtx_trylock, int, (mtx_t *) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mtx_trylock, int, (mtx_t *));
+_GL_CXXALIASWARN (mtx_trylock);
+#elif defined GNULIB_POSIXCHECK
+# undef mtx_trylock
+# if HAVE_RAW_DECL_MTX_TRYLOCK
+_GL_WARN_ON_USE (mtx_trylock, "mtx_trylock is unportable - "
+                 "use gnulib module mtx for portability");
+# endif
+#endif
+
+#if @GNULIB_MTX@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (mtx_timedlock, int, (mtx_t *, const struct timespec *)
+                                      _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (mtx_timedlock, int, (mtx_t *, const struct timespec *));
+_GL_CXXALIASWARN (mtx_timedlock);
+#elif defined GNULIB_POSIXCHECK
+# undef mtx_timedlock
+# if HAVE_RAW_DECL_MTX_TIMEDLOCK
+_GL_WARN_ON_USE (mtx_timedlock, "mtx_timedlock is unportable - "
+                 "use gnulib module mtx for portability");
+# endif
+#endif
+
+#if @GNULIB_MTX@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (mtx_unlock, int, (mtx_t *) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mtx_unlock, int, (mtx_t *));
+_GL_CXXALIASWARN (mtx_unlock);
+#elif defined GNULIB_POSIXCHECK
+# undef mtx_unlock
+# if HAVE_RAW_DECL_MTX_UNLOCK
+_GL_WARN_ON_USE (mtx_unlock, "mtx_unlock is unportable - "
+                 "use gnulib module mtx for portability");
+# endif
+#endif
+
+#if @GNULIB_MTX@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (mtx_destroy, void, (mtx_t *) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mtx_destroy, void, (mtx_t *));
+_GL_CXXALIASWARN (mtx_destroy);
+#elif defined GNULIB_POSIXCHECK
+# undef mtx_destroy
+# if HAVE_RAW_DECL_MTX_DESTROY
+_GL_WARN_ON_USE (mtx_destroy, "mtx_destroy is unportable - "
+                 "use gnulib module mtx for portability");
+# endif
+#endif
+
+
+/* =========== ISO C 11 7.26.2 Initialization functions =========== */
+
+#if !@HAVE_THREADS_H@
+
+/* Type that contains a flag for use by call_once.  */
+# if defined _WIN32 && ! defined __CYGWIN__
+/* Use Windows threads.  */
+
+#  include "windows-once.h"
+
+typedef glwthread_once_t once_flag;
+#  define ONCE_FLAG_INIT GLWTHREAD_ONCE_INIT
+
+# else
+/* Use POSIX threads.  */
+
+typedef pthread_once_t once_flag;
+#  define ONCE_FLAG_INIT PTHREAD_ONCE_INIT
+
+# endif
+
+#endif
+
+#if @GNULIB_MTX@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (call_once, void, (once_flag *, void (*) (void))
+                                   _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (call_once, void, (once_flag *, void (*) (void)));
+_GL_CXXALIASWARN (call_once);
+#elif defined GNULIB_POSIXCHECK
+# undef call_once
+# if HAVE_RAW_DECL_CALL_ONCE
+_GL_WARN_ON_USE (call_once, "call_once is unportable - "
+                 "use gnulib module mtx for portability");
+# endif
+#endif
+
+
+/* =========== ISO C 11 7.26.3 Condition variable functions =========== */
+
+#if !@HAVE_THREADS_H@
+
+# if defined _WIN32 && ! defined __CYGWIN__
+/* Use Windows threads.  */
+
+#  include "windows-cond.h"
+
+typedef glwthread_cond_t cnd_t;
+
+# else
+/* Use POSIX threads.  */
+
+typedef pthread_cond_t cnd_t;
+
+# endif
+
+#endif
+
+#if @GNULIB_CND@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (cnd_init, int, (cnd_t *) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (cnd_init, int, (cnd_t *));
+_GL_CXXALIASWARN (cnd_init);
+#elif defined GNULIB_POSIXCHECK
+# undef cnd_init
+# if HAVE_RAW_DECL_CND_INIT
+_GL_WARN_ON_USE (cnd_init, "cnd_init is unportable - "
+                 "use gnulib module cnd for portability");
+# endif
+#endif
+
+#if @GNULIB_CND@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (cnd_wait, int, (cnd_t *, mtx_t *) _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (cnd_wait, int, (cnd_t *, mtx_t *));
+_GL_CXXALIASWARN (cnd_wait);
+#elif defined GNULIB_POSIXCHECK
+# undef cnd_wait
+# if HAVE_RAW_DECL_CND_WAIT
+_GL_WARN_ON_USE (cnd_wait, "cnd_wait is unportable - "
+                 "use gnulib module cnd for portability");
+# endif
+#endif
+
+#if @GNULIB_CND@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (cnd_timedwait, int,
+                                 (cnd_t *, mtx_t *, const struct timespec *)
+                                 _GL_ARG_NONNULL ((1, 2, 3)));
+# endif
+_GL_CXXALIAS_SYS (cnd_timedwait, int,
+                                 (cnd_t *, mtx_t *, const struct timespec *));
+_GL_CXXALIASWARN (cnd_timedwait);
+#elif defined GNULIB_POSIXCHECK
+# undef cnd_timedwait
+# if HAVE_RAW_DECL_CND_TIMEDWAIT
+_GL_WARN_ON_USE (cnd_timedwait, "cnd_timedwait is unportable - "
+                 "use gnulib module cnd for portability");
+# endif
+#endif
+
+#if @GNULIB_CND@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (cnd_signal, int, (cnd_t *) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (cnd_signal, int, (cnd_t *));
+_GL_CXXALIASWARN (cnd_signal);
+#elif defined GNULIB_POSIXCHECK
+# undef cnd_signal
+# if HAVE_RAW_DECL_CND_SIGNAL
+_GL_WARN_ON_USE (cnd_signal, "cnd_signal is unportable - "
+                 "use gnulib module cnd for portability");
+# endif
+#endif
+
+#if @GNULIB_CND@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (cnd_broadcast, int, (cnd_t *) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (cnd_broadcast, int, (cnd_t *));
+_GL_CXXALIASWARN (cnd_broadcast);
+#elif defined GNULIB_POSIXCHECK
+# undef cnd_broadcast
+# if HAVE_RAW_DECL_CND_BROADCAST
+_GL_WARN_ON_USE (cnd_broadcast, "cnd_broadcast is unportable - "
+                 "use gnulib module cnd for portability");
+# endif
+#endif
+
+#if @GNULIB_CND@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (cnd_destroy, void, (cnd_t *) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (cnd_destroy, void, (cnd_t *));
+_GL_CXXALIASWARN (cnd_destroy);
+#elif defined GNULIB_POSIXCHECK
+# undef cnd_destroy
+# if HAVE_RAW_DECL_CND_DESTROY
+_GL_WARN_ON_USE (cnd_destroy, "cnd_destroy is unportable - "
+                 "use gnulib module cnd for portability");
+# endif
+#endif
+
+
+/* =========== ISO C 11 7.26.6 Thread-specific storage functions =========== */
+
+#if !@HAVE_THREADS_H@
+
+# if defined _WIN32 && ! defined __CYGWIN__
+/* Use Windows threads.  */
+
+#  include "windows-tls.h"
+
+typedef glwthread_tls_key_t tss_t;
+#  define TSS_DTOR_ITERATIONS 0    /* Destructors are currently unsupported.  */
+
+# else
+/* Use POSIX threads.  */
+
+#  include <limits.h>
+
+typedef pthread_key_t tss_t;
+
+# endif
+
+/* Type for the destructor of a thread-specific storage pointer.  */
+typedef void (*tss_dtor_t) (void *);
+
+#endif
+
+/* AIX 7.1 <threads.h> does not define TSS_DTOR_ITERATIONS.  */
+#ifndef TSS_DTOR_ITERATIONS
+# ifdef PTHREAD_DESTRUCTOR_ITERATIONS
+#  define TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS
+# else
+   /* IRIX 6.5 does not define PTHREAD_DESTRUCTOR_ITERATIONS.
+      This value is a wild guess.  */
+#  define TSS_DTOR_ITERATIONS 1
+# endif
+#endif
+
+#if @GNULIB_TSS@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (tss_create, int, (tss_t *, tss_dtor_t) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (tss_create, int, (tss_t *, tss_dtor_t));
+_GL_CXXALIASWARN (tss_create);
+#elif defined GNULIB_POSIXCHECK
+# undef tss_create
+# if HAVE_RAW_DECL_TSS_CREATE
+_GL_WARN_ON_USE (tss_create, "tss_create is unportable - "
+                 "use gnulib module tss for portability");
+# endif
+#endif
+
+#if @GNULIB_TSS@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (tss_set, int, (tss_t, void *));
+# endif
+_GL_CXXALIAS_SYS (tss_set, int, (tss_t, void *));
+_GL_CXXALIASWARN (tss_set);
+#elif defined GNULIB_POSIXCHECK
+# undef tss_set
+# if HAVE_RAW_DECL_TSS_SET
+_GL_WARN_ON_USE (tss_set, "tss_set is unportable - "
+                 "use gnulib module tss for portability");
+# endif
+#endif
+
+#if @GNULIB_TSS@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (tss_get, void *, (tss_t));
+# endif
+_GL_CXXALIAS_SYS (tss_get, void *, (tss_t));
+_GL_CXXALIASWARN (tss_get);
+#elif defined GNULIB_POSIXCHECK
+# undef tss_get
+# if HAVE_RAW_DECL_TSS_GET
+_GL_WARN_ON_USE (tss_get, "tss_get is unportable - "
+                 "use gnulib module tss for portability");
+# endif
+#endif
+
+#if @GNULIB_TSS@
+# if !@HAVE_THREADS_H@
+_GL_FUNCDECL_SYS (tss_delete, void, (tss_t));
+# endif
+_GL_CXXALIAS_SYS (tss_delete, void, (tss_t));
+_GL_CXXALIASWARN (tss_delete);
+#elif defined GNULIB_POSIXCHECK
+# undef tss_delete
+# if HAVE_RAW_DECL_TSS_DELETE
+_GL_WARN_ON_USE (tss_delete, "tss_delete is unportable - "
+                 "use gnulib module tss for portability");
+# endif
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_THREADS_H */
+#endif /* _@GUARD_PREFIX@_THREADS_H */
diff --git a/m4/threads.m4 b/m4/threads.m4
new file mode 100644 (file)
index 0000000..3cb3ae1
--- /dev/null
@@ -0,0 +1,126 @@
+# threads.m4 serial 1
+dnl Copyright (C) 2019 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_THREADS_H],
+[
+  AC_REQUIRE([gl_THREADS_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([gl_THREADLIB_BODY])
+  AC_REQUIRE([gl_YIELD])
+
+  gl_CHECK_NEXT_HEADERS([threads.h])
+  if test $ac_cv_header_threads_h = yes; then
+    HAVE_THREADS_H=1
+  else
+    HAVE_THREADS_H=0
+  fi
+  AC_SUBST([HAVE_THREADS_H])
+
+  if test $HAVE_THREADS_H = 1; then
+    dnl AIX 7.1..7.2 defines thrd_start_t incorrectly, namely as
+    dnl 'void * (*) (void *)' instead of 'int (*) (void *)'.
+    AC_CACHE_CHECK([whether thrd_start_t is correct],
+      [gl_cv_thrd_start_t_correct],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM([[
+            #include <threads.h>
+            #ifdef __cplusplus
+            extern "C" {
+            #endif
+            extern void foo (thrd_start_t);
+            extern void foo (int (*) (void *));
+            #ifdef __cplusplus
+            }
+            #endif
+          ]], [[]])],
+         [gl_cv_thrd_start_t_correct=yes],
+         [gl_cv_thrd_start_t_correct=no])
+      ])
+    if test $gl_cv_thrd_start_t_correct != yes; then
+      BROKEN_THRD_START_T=1
+    fi
+  fi
+
+  case "$host_os" in
+    mingw*)
+      LIBSTDTHREAD=
+      LTLIBSTDTHREAD=
+      ;;
+    *)
+      if test $ac_cv_header_threads_h = yes; then
+        dnl glibc >= 2.29 has thrd_create in libpthread.
+        dnl FreeBSD >= 10 has thrd_create in libstdthreads.
+        dnl AIX >= 7.1 and Solaris >= 11.4 have thrd_create in libc.
+        AC_CHECK_FUNCS([thrd_create])
+        if test $ac_cv_func_thrd_create = yes; then
+          LIBSTDTHREAD=
+          LTLIBSTDTHREAD=
+        else
+          AC_CHECK_LIB([stdthreads], [thrd_create], [
+            LIBSTDTHREAD='-lstdthreads'
+            LTLIBSTDTHREAD='-lstdthreads'
+          ], [
+            dnl Guess that thrd_create is in libpthread.
+            LIBSTDTHREAD="$LIBMULTITHREAD"
+            LTLIBSTDTHREAD="$LTLIBMULTITHREAD"
+          ])
+        fi
+      else
+        dnl Libraries needed by thrd.c, mtx.c, cnd.c, tss.c.
+        LIBSTDTHREAD="$LIBMULTITHREAD $YIELD_LIB"
+        LTLIBSTDTHREAD="$LTLIBMULTITHREAD $YIELD_LIB"
+      fi
+      ;;
+  esac
+  AC_SUBST([LIBSTDTHREAD])
+  AC_SUBST([LTLIBSTDTHREAD])
+
+  AH_VERBATIM([thread_local],
+[/* The _Thread_local keyword of C11.  */
+#ifndef _Thread_local
+# if defined __GNUC__
+#  define _Thread_local __thread
+# elif defined _MSC_VER
+#  define _Thread_local __declspec (thread)
+# endif
+#endif
+])
+
+  dnl Check for declarations of anything we want to poison if the
+  dnl corresponding gnulib module is not in use, and which is not
+  dnl guaranteed by C89.
+  gl_WARN_ON_USE_PREPARE([[#include <threads.h>
+    ]], [call_once
+    cnd_broadcast cnd_destroy cnd_init cnd_signal cnd_timedwait cnd_wait
+    mtx_destroy mtx_init mtx_lock mtx_timedlock mtx_trylock mtx_unlock
+    thrd_create thrd_current thrd_detach thrd_equal thrd_exit thrd_join
+    thrd_sleep thrd_yield
+    tss_create tss_delete tss_get tss_set])
+])
+
+AC_DEFUN([gl_THREADS_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_THREADS_H_DEFAULTS])
+  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+  dnl Define it also as a C macro, for the benefit of the unit tests.
+  gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_THREADS_H_DEFAULTS],
+[
+  GNULIB_CND=0;           AC_SUBST([GNULIB_CND])
+  GNULIB_MTX=0;           AC_SUBST([GNULIB_MTX])
+  GNULIB_THRD=0;          AC_SUBST([GNULIB_THRD])
+  GNULIB_TSS=0;           AC_SUBST([GNULIB_TSS])
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  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])
+  REPLACE_THRD_DETACH=0;  AC_SUBST([REPLACE_THRD_DETACH])
+  REPLACE_THRD_EQUAL=0;   AC_SUBST([REPLACE_THRD_EQUAL])
+  REPLACE_THRD_JOIN=0;    AC_SUBST([REPLACE_THRD_JOIN])
+])
index 13f6f204a524bb8bbbfd0dc26ba70ec187bf1e7a..59c8c38eb4f3a1433b6cf46931e2db1e5d1a4dbd 100644 (file)
@@ -1,4 +1,4 @@
-# yield.m4 serial 2
+# yield.m4 serial 3
 dnl Copyright (C) 2005-2019 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,7 +10,7 @@ AC_DEFUN([gl_YIELD],
   dnl On some systems, sched_yield is in librt, rather than in libpthread.
   YIELD_LIB=
   if test $gl_threads_api = posix; then
-    dnl Solaris has sched_yield in librt, not in libpthread or libc.
+    dnl Solaris 7...10 has sched_yield in librt, not in libpthread or libc.
     AC_CHECK_LIB([rt], [sched_yield], [YIELD_LIB=-lrt],
       [dnl Solaris 2.5.1, 2.6 has sched_yield in libposix4, not librt.
        AC_CHECK_LIB([posix4], [sched_yield], [YIELD_LIB=-lposix4])])
diff --git a/modules/threads-h b/modules/threads-h
new file mode 100644 (file)
index 0000000..238955c
--- /dev/null
@@ -0,0 +1,73 @@
+Description:
+An ISO C 11 compatible <threads.h>.
+
+Files:
+lib/threads.in.h
+lib/windows-thread.h
+lib/windows-mutex.h
+lib/windows-recmutex.h
+lib/windows-timedmutex.h
+lib/windows-timedrecmutex.h
+lib/windows-once.h
+lib/windows-cond.h
+lib/windows-tls.h
+lib/windows-spinlock.h
+m4/threads.m4
+m4/threadlib.m4
+m4/yield.m4
+build-aux/config.rpath
+
+Depends-on:
+include_next
+snippet/c++defs
+snippet/_Noreturn
+snippet/arg-nonnull
+snippet/warn-on-use
+time
+havelib
+
+configure.ac-early:
+gl_THREADLIB_EARLY
+
+configure.ac:
+AC_REQUIRE([gl_THREADS_H])
+
+Makefile.am:
+BUILT_SOURCES += threads.h
+
+# We need the following in order to create <threads.h> when the system
+# doesn't have one.
+threads.h: threads.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+       $(AM_V_GEN)rm -f $@-t $@ && \
+       { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+         sed -e 's|@''GUARD_PREFIX''@|${gl_include_guard_prefix}|g' \
+             -e 's|@''HAVE_THREADS_H''@|$(HAVE_THREADS_H)|g' \
+             -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+             -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+             -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+             -e 's|@''NEXT_THREADS_H''@|$(NEXT_THREADS_H)|g' \
+             -e 's/@''GNULIB_CND''@/$(GNULIB_CND)/g' \
+             -e 's/@''GNULIB_MTX''@/$(GNULIB_MTX)/g' \
+             -e 's/@''GNULIB_THRD''@/$(GNULIB_THRD)/g' \
+             -e 's/@''GNULIB_TSS''@/$(GNULIB_TSS)/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' \
+             -e 's|@''REPLACE_THRD_DETACH''@|$(REPLACE_THRD_DETACH)|g' \
+             -e 's|@''REPLACE_THRD_EQUAL''@|$(REPLACE_THRD_EQUAL)|g' \
+             -e 's|@''REPLACE_THRD_JOIN''@|$(REPLACE_THRD_JOIN)|g' \
+             < $(srcdir)/threads.in.h; \
+       } > $@-t && \
+       mv $@-t $@
+MOSTLYCLEANFILES += threads.h threads.h-t
+
+Include:
+<threads.h>
+
+Link:
+
+License:
+LGPLv2+
+
+Maintainer:
+all
index 24ffcdd2434f3623f6e45a63ad44b28eae143e56..71e00ea73d61ea8ca77d7b1e5598799eeb056c0c 100644 (file)
@@ -9,7 +9,7 @@ Depends-on:
 threadlib
 
 configure.ac:
-gl_YIELD
+AC_REQUIRE([gl_YIELD])
 
 Makefile.am:
 lib_SOURCES += glthread/yield.h