diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | doc/posix-functions/thrd_create.texi | 11 | ||||
-rw-r--r-- | doc/posix-functions/thrd_current.texi | 8 | ||||
-rw-r--r-- | doc/posix-functions/thrd_detach.texi | 8 | ||||
-rw-r--r-- | doc/posix-functions/thrd_equal.texi | 8 | ||||
-rw-r--r-- | doc/posix-functions/thrd_exit.texi | 8 | ||||
-rw-r--r-- | doc/posix-functions/thrd_join.texi | 14 | ||||
-rw-r--r-- | doc/posix-functions/thrd_sleep.texi | 8 | ||||
-rw-r--r-- | doc/posix-functions/thrd_yield.texi | 8 | ||||
-rw-r--r-- | lib/thrd.c | 427 | ||||
-rw-r--r-- | m4/thrd.m4 | 63 | ||||
-rw-r--r-- | modules/thrd | 33 |
12 files changed, 581 insertions, 32 deletions
@@ -1,5 +1,22 @@ 2019-06-20 Bruno Haible <bruno@clisp.org> + thrd: New module. + * lib/thrd.c: New file. + * m4/thrd.m4: New file. + * modules/thrd: New file. + * doc/posix-functions/thrd_current.texi: Mention the new module. + * doc/posix-functions/thrd_detach.texi: Likewise. + * doc/posix-functions/thrd_equal.texi: Likewise. + * doc/posix-functions/thrd_exit.texi: Likewise. + * doc/posix-functions/thrd_sleep.texi: Likewise. + * doc/posix-functions/thrd_yield.texi: Likewise. + * doc/posix-functions/thrd_create.texi: Mention the new module and the + AIX bug. + * doc/posix-functions/thrd_join.texi: Mention the new module and the + AIX and Solaris bugs. + +2019-06-20 Bruno Haible <bruno@clisp.org> + threads-h: Add tests. * tests/test-threads.c: New file. * modules/threads-h-tests: New file. diff --git a/doc/posix-functions/thrd_create.texi b/doc/posix-functions/thrd_create.texi index eb3fd5049b..9fe35f489c 100644 --- a/doc/posix-functions/thrd_create.texi +++ b/doc/posix-functions/thrd_create.texi @@ -10,15 +10,18 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Thread-Management.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: thrd Portability problems fixed by Gnulib: @itemize +@item +This function 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 function uses an incorrectly defined @code{thrd_start_t} on some platforms: +AIX 7.2. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function 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/doc/posix-functions/thrd_current.texi b/doc/posix-functions/thrd_current.texi index 03f33a5d7e..ea81185313 100644 --- a/doc/posix-functions/thrd_current.texi +++ b/doc/posix-functions/thrd_current.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Thread-Management.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: thrd Portability problems fixed by Gnulib: @itemize +@item +This function 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 Portability problems not fixed by Gnulib: @itemize -@item -This function 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/doc/posix-functions/thrd_detach.texi b/doc/posix-functions/thrd_detach.texi index 3cfb318167..bb8f6c316a 100644 --- a/doc/posix-functions/thrd_detach.texi +++ b/doc/posix-functions/thrd_detach.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Thread-Management.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: thrd Portability problems fixed by Gnulib: @itemize +@item +This function 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 Portability problems not fixed by Gnulib: @itemize -@item -This function 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/doc/posix-functions/thrd_equal.texi b/doc/posix-functions/thrd_equal.texi index 58f5a02377..185550244c 100644 --- a/doc/posix-functions/thrd_equal.texi +++ b/doc/posix-functions/thrd_equal.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Thread-Management.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: thrd Portability problems fixed by Gnulib: @itemize +@item +This function 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 Portability problems not fixed by Gnulib: @itemize -@item -This function 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/doc/posix-functions/thrd_exit.texi b/doc/posix-functions/thrd_exit.texi index a2683b6a7d..75ae888936 100644 --- a/doc/posix-functions/thrd_exit.texi +++ b/doc/posix-functions/thrd_exit.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Thread-Management.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: thrd Portability problems fixed by Gnulib: @itemize +@item +This function 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 Portability problems not fixed by Gnulib: @itemize -@item -This function 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/doc/posix-functions/thrd_join.texi b/doc/posix-functions/thrd_join.texi index 2199a8f110..51b2ec9df3 100644 --- a/doc/posix-functions/thrd_join.texi +++ b/doc/posix-functions/thrd_join.texi @@ -10,15 +10,21 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Thread-Management.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: thrd Portability problems fixed by Gnulib: @itemize +@item +This function 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 function never stores an exit code on some platforms: +AIX 7.2. +@item +This function crashes when the second argument is NULL on some platforms: +Solaris 11.4. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function 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/doc/posix-functions/thrd_sleep.texi b/doc/posix-functions/thrd_sleep.texi index afdb3ea6a1..5e02eb1e4e 100644 --- a/doc/posix-functions/thrd_sleep.texi +++ b/doc/posix-functions/thrd_sleep.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Thread-Management.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: thrd Portability problems fixed by Gnulib: @itemize +@item +This function 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 Portability problems not fixed by Gnulib: @itemize -@item -This function 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/doc/posix-functions/thrd_yield.texi b/doc/posix-functions/thrd_yield.texi index a787a69708..dde2a718e8 100644 --- a/doc/posix-functions/thrd_yield.texi +++ b/doc/posix-functions/thrd_yield.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Thread-Management.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: thrd Portability problems fixed by Gnulib: @itemize +@item +This function 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 Portability problems not fixed by Gnulib: @itemize -@item -This function 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/thrd.c b/lib/thrd.c new file mode 100644 index 0000000000..e8f29bc09c --- /dev/null +++ b/lib/thrd.c @@ -0,0 +1,427 @@ +/* Creating and controlling ISO C 11 threads. + Copyright (C) 2005-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/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>, 2005, 2019. + Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-win32.h. */ + +#include <config.h> + +#include <threads.h> + +#include <stdlib.h> + +#if HAVE_THREADS_H +/* Provide workarounds. */ + +# if BROKEN_THRD_START_T + +# 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. */ + +/* The Thread-Specific Storage (TSS) key that allows to access each thread's + 'struct thrd_with_exitcode *' pointer. */ +static tss_t thrd_with_exitcode_key; + +/* Initializes thrd_with_exitcode_key. + This function must only be called once. */ +static void +do_init_thrd_with_exitcode_key (void) +{ + if (tss_create (&thrd_with_exitcode_key, NULL) != thrd_success) + abort (); +} + +/* Initializes thrd_with_exitcode_key. */ +static void +init_thrd_with_exitcode_key (void) +{ + static once_flag once = ONCE_FLAG_INIT; + call_once (&once, do_init_thrd_with_exitcode_key); +} + +typedef union + { + struct thrd_with_exitcode t; + struct + { + thrd_t tid; /* reserve memory for t.tid */ + int detached; /* reserve memory for t.detached */ + thrd_start_t mainfunc; + void *arg; + } a; + } + main_arg_t; + +static void * +thrd_main_func (void *pmarg) +{ + /* Unpack the object that combines mainfunc and arg. */ + main_arg_t *main_arg = (main_arg_t *) pmarg; + thrd_start_t mainfunc = main_arg->a.mainfunc; + void *arg = main_arg->a.arg; + + if (tss_set (thrd_with_exitcode_key, &main_arg->t) != thrd_success) + abort (); + + /* Execute mainfunc, with arg as argument. */ + { + int exitcode = mainfunc (arg); + /* Store the exitcode, for use by thrd_join(). */ + main_arg->t.exitcode = exitcode; + if (main_arg->t.detached) + { + /* Clean up the thread, like thrd_join would do. */ + free (&main_arg->t); + } + return NULL; + } +} + +int +rpl_thrd_create (rpl_thrd_t *threadp, thrd_start_t mainfunc, void *arg) +# undef thrd_create +{ + init_thrd_with_exitcode_key (); + { + /* Combine mainfunc and arg in a single object. + A stack-allocated object does not work, because it would be out of + existence when thrd_create returns before pthread_main_func is + entered. So, allocate it in the heap. */ + main_arg_t *main_arg = (main_arg_t *) malloc (sizeof (main_arg_t)); + if (main_arg == NULL) + return thrd_nomem; + main_arg->a.mainfunc = mainfunc; + main_arg->a.arg = arg; + main_arg->t.detached = 0; + { + int err = + thrd_create ((thrd_t *) &main_arg->t.tid, thrd_main_func, main_arg); + if (err == thrd_success) + *threadp = &main_arg->t; + else + free (main_arg); + return err; + } + } +} + +rpl_thrd_t +rpl_thrd_current (void) +# undef thrd_current +{ + init_thrd_with_exitcode_key (); + { + rpl_thrd_t thread = + (struct thrd_with_exitcode *) tss_get (thrd_with_exitcode_key); + if (thread == NULL) + { + /* This happens only in threads that have not been created through + thrd_create(), such as the main thread. */ + for (;;) + { + thread = + (struct thrd_with_exitcode *) + malloc (sizeof (struct thrd_with_exitcode)); + if (thread != NULL) + break; + /* Memory allocation failed. There is not much we can do. Have to + busy-loop, waiting for the availability of memory. */ + { + struct timespec ts; + ts.tv_sec = 1; + ts.tv_nsec = 0; + thrd_sleep (&ts, NULL); + } + } + thread->tid = thrd_current (); + thread->detached = 0; /* This can lead to a memory leak. */ + thread->exitcode = 0; /* just to be deterministic */ + if (tss_set (thrd_with_exitcode_key, thread) != thrd_success) + abort (); + } + return thread; + } +} + +int +rpl_thrd_equal (rpl_thrd_t thread1, rpl_thrd_t thread2) +{ + return thread1 == thread2; +} + +int +rpl_thrd_detach (rpl_thrd_t thread) +# undef thrd_detach +{ + if (thread->detached) + return thrd_error; + { + int err = + thrd_detach (thread == rpl_thrd_current () + ? /* thread->tid may not be initialized at this point. */ + thrd_current () + : thread->tid); + if (err == thrd_success) + thread->detached = 1; + return err; + } +} + +int +rpl_thrd_join (rpl_thrd_t thread, int *exitcodep) +# undef thrd_join +{ + if (thread == rpl_thrd_current () || thread->detached) + return thrd_error; + { + int err = thrd_join (thread->tid, NULL); + if (err == thrd_success) + { + if (exitcodep != NULL) + *exitcodep = thread->exitcode; + free (thread); + } + return err; + } +} + +# endif + +# if BROKEN_THRD_JOIN + +/* On Solaris 11.4, thrd_join crashes when the second argument is NULL. */ +int +rpl_thrd_join (thrd_t thread, int *exitcodep) +# undef thrd_join +{ + int exitcode; + int err = thrd_join (thread, &exitcode); + if (err == 0 && exitcodep != NULL) + *exitcodep = exitcode; + return err; +} + +# endif + +#else + +# include <errno.h> +# include <stdint.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> +# include <sched.h> + +# endif + +/* The main functions passed to thrd_create and + pthread_create/glwthread_thread_create have different return types: + 'int' vs. 'void *'. */ + +struct pthread_main_arg_t +{ + thrd_start_t mainfunc; + void *arg; +}; + +static void * +pthread_main_func (void *pmarg) +{ + /* Unpack the object that combines mainfunc and arg. */ + struct pthread_main_arg_t *pthread_main_arg = + (struct pthread_main_arg_t *) pmarg; + thrd_start_t mainfunc = pthread_main_arg->mainfunc; + void *arg = pthread_main_arg->arg; + + /* Free it. */ + free (pmarg); + + /* Execute mainfunc, with arg as argument. */ + { + int exitcode = mainfunc (arg); + return (void *) (intptr_t) exitcode; + } +} + +# if defined _WIN32 && ! defined __CYGWIN__ +/* Use Windows threads. */ + +int +thrd_create (thrd_t *threadp, thrd_start_t mainfunc, void *arg) +{ + /* Combine mainfunc and arg in a single object. + A stack-allocated object does not work, because it would be out of + existence when thrd_create returns before pthread_main_func is + entered. So, allocate it in the heap. */ + struct pthread_main_arg_t *pthread_main_arg = + (struct pthread_main_arg_t *) malloc (sizeof (struct pthread_main_arg_t)); + if (pthread_main_arg == NULL) + return thrd_nomem; + pthread_main_arg->mainfunc = mainfunc; + pthread_main_arg->arg = arg; + + { + int err = glwthread_thread_create (threadp, + pthread_main_func, pthread_main_arg); + if (err != 0) + free (pthread_main_arg); + return (err == 0 ? thrd_success : + err == ENOMEM /* || err == EAGAIN */ ? thrd_nomem : + thrd_error); + } +} + +thrd_t +thrd_current (void) +{ + return glwthread_thread_self (); +} + +int +thrd_equal (thrd_t thread1, thrd_t thread2) +{ + return thread1 == thread2; +} + +void +thrd_yield (void) +{ + Sleep (0); +} + +int +thrd_detach (thrd_t thread) +{ + int err = glwthread_thread_detach (thread); + return (err == 0 ? thrd_success : thrd_error); +} + +int +thrd_join (thrd_t thread, int *exitcodep) +{ + void *exitptr; + int err = glwthread_thread_join (thread, &exitptr); + if (err == 0) + { + if (exitcodep != NULL) + *exitcodep = (int) (intptr_t) exitptr; + return thrd_success; + } + else + return thrd_error; +} + +_Noreturn void +thrd_exit (int exitcode) +{ + glwthread_thread_exit ((void *) (intptr_t) exitcode); +} + +# else +/* Use POSIX threads. */ + +int +thrd_create (thrd_t *threadp, thrd_start_t mainfunc, void *arg) +{ + /* Combine mainfunc and arg in a single object. + A stack-allocated object does not work, because it would be out of + existence when thrd_create returns before pthread_main_func is + entered. So, allocate it in the heap. */ + struct pthread_main_arg_t *pthread_main_arg = + (struct pthread_main_arg_t *) malloc (sizeof (struct pthread_main_arg_t)); + if (pthread_main_arg == NULL) + return thrd_nomem; + pthread_main_arg->mainfunc = mainfunc; + pthread_main_arg->arg = arg; + + { + int err = pthread_create (threadp, NULL, + pthread_main_func, pthread_main_arg); + if (err != 0) + free (pthread_main_arg); + return (err == 0 ? thrd_success : + err == ENOMEM /* || err == EAGAIN */ ? thrd_nomem : + thrd_error); + } +} + +thrd_t +thrd_current (void) +{ + return pthread_self (); +} + +int +thrd_equal (thrd_t thread1, thrd_t thread2) +{ + return pthread_equal (thread1, thread2); +} + +void +thrd_yield (void) +{ + sched_yield (); +} + +int +thrd_detach (thrd_t thread) +{ + int err = pthread_detach (thread); + return (err == 0 ? thrd_success : thrd_error); +} + +int +thrd_join (thrd_t thread, int *exitcodep) +{ + void *exitptr; + int err = pthread_join (thread, &exitptr); + if (err == 0) + { + if (exitcodep != NULL) + *exitcodep = (int) (intptr_t) exitptr; + return thrd_success; + } + else + return thrd_error; +} + +_Noreturn void +thrd_exit (int exitcode) +{ + pthread_exit ((void *) (intptr_t) exitcode); +} + +# endif + +int +thrd_sleep (const struct timespec *duration, struct timespec *remaining) +{ + int ret = nanosleep (duration, remaining); + return (ret == 0 ? 0 : errno == EINTR ? -1 : -2); +} + +#endif diff --git a/m4/thrd.m4 b/m4/thrd.m4 new file mode 100644 index 0000000000..6e9c8f44cc --- /dev/null +++ b/m4/thrd.m4 @@ -0,0 +1,63 @@ +# thrd.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_FUNC_THRD_JOIN], +[ + AC_REQUIRE([gl_THREADS_H]) + 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 + REPLACE_THRD_CREATE=1 + REPLACE_THRD_CURRENT=1 + REPLACE_THRD_DETACH=1 + REPLACE_THRD_EQUAL=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.]) + 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], + [save_LIBS="$LIBS" + LIBS="$LIBS $LIBSTDTHREAD" + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include <stddef.h> + #include <threads.h> + static int func (void *arg) + { + return (arg != NULL); + } + ]], + [[thrd_t thread; + if (thrd_create (&thread, func, NULL) != thrd_success) + return 1; + if (thrd_join (thread, NULL) != thrd_success) + return 2; + return 0; + ]])], + [gl_cv_func_thrd_join_works=yes], + [gl_cv_func_thrd_join_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" ;; + esac + ]) + LIBS="$save_LIBS" + ]) + case "$gl_cv_func_thrd_join_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.]) + ;; + esac + fi +]) diff --git a/modules/thrd b/modules/thrd new file mode 100644 index 0000000000..3fd606305d --- /dev/null +++ b/modules/thrd @@ -0,0 +1,33 @@ +Description: +ISO C 11 thread functions. + +Files: +lib/thrd.c +m4/thrd.m4 + +Depends-on: +threads-h +windows-thread +nanosleep + +configure.ac: +AC_REQUIRE([gl_THREADS_H]) +gl_FUNC_THRD_JOIN +if test $HAVE_THREADS_H = 0 || test $REPLACE_THRD_CREATE = 1 || test $REPLACE_THRD_JOIN = 1; then + AC_LIBOBJ([thrd]) +fi +gl_THREADS_MODULE_INDICATOR([thrd]) + +Makefile.am: + +Include: +<threads.h> + +Link: +$(LTLIBSTDTHREAD) when linking with libtool, $(LIBSTDTHREAD) otherwise + +License: +LGPLv2+ + +Maintainer: +all |