>From 80d24481060742c00cfe83a6a772db3856d1e7cb Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 20 Jun 2019 04:17:30 +0200 Subject: [PATCH 16/26] 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. --- ChangeLog | 11 + doc/posix-headers/threads.texi | 14 +- lib/threads.in.h | 649 +++++++++++++++++++++++++++++++++++++++++ m4/threads.m4 | 126 ++++++++ m4/yield.m4 | 4 +- modules/threads-h | 73 +++++ modules/yield | 2 +- 7 files changed, 872 insertions(+), 7 deletions(-) create mode 100644 lib/threads.in.h create mode 100644 m4/threads.m4 create mode 100644 modules/threads-h diff --git a/ChangeLog b/ChangeLog index ab97f37..22b942b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2019-06-20 Bruno Haible + 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 + windows-thread: New module. * lib/windows-thread.h: New file, based on lib/glthread/thread.h. * lib/windows-thread.c: New file, based on lib/glthread/thread.c. diff --git a/doc/posix-headers/threads.texi b/doc/posix-headers/threads.texi index 9892539..71ae43a 100644 --- a/doc/posix-headers/threads.texi +++ b/doc/posix-headers/threads.texi @@ -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 index 0000000..a18d64b --- /dev/null +++ b/lib/threads.in.h @@ -0,0 +1,649 @@ +/* An ISO C 11 compatible . + + 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 . */ + +#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 + +# if defined _WIN32 && ! defined __CYGWIN__ +/* Use Windows threads. */ + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# else +/* Use POSIX threads. */ + +# include + +# 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 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 + +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 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 index 0000000..3cb3ae1 --- /dev/null +++ b/m4/threads.m4 @@ -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 + #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 + ]], [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]) +]) diff --git a/m4/yield.m4 b/m4/yield.m4 index 13f6f20..59c8c38 100644 --- a/m4/yield.m4 +++ b/m4/yield.m4 @@ -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 index 0000000..238955c --- /dev/null +++ b/modules/threads-h @@ -0,0 +1,73 @@ +Description: +An ISO C 11 compatible . + +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 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: + + +Link: + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/yield b/modules/yield index 24ffcdd..71e00ea 100644 --- a/modules/yield +++ b/modules/yield @@ -9,7 +9,7 @@ Depends-on: threadlib configure.ac: -gl_YIELD +AC_REQUIRE([gl_YIELD]) Makefile.am: lib_SOURCES += glthread/yield.h -- 2.7.4