From be8efac78d067c138ad8dda03df4336e73f94887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sat, 8 Jan 2022 11:51:07 +0100 Subject: New upstream version 1.0 --- tests/glthread/thread.c | 320 +++++++++++++++++++++++------------------------- tests/glthread/thread.h | 229 ++++++++++------------------------ tests/glthread/yield.h | 57 +++------ 3 files changed, 236 insertions(+), 370 deletions(-) (limited to 'tests/glthread') diff --git a/tests/glthread/thread.c b/tests/glthread/thread.c index 0387406..0b923c0 100644 --- a/tests/glthread/thread.c +++ b/tests/glthread/thread.c @@ -1,27 +1,25 @@ /* Creating and controlling threads. - Copyright (C) 2005-2018 Free Software Foundation, Inc. + Copyright (C) 2005-2022 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 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Bruno Haible , 2005. - Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h, - gthr-win32.h. */ + Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-win32.h. */ #include /* Specification. */ -# define _GLTHREAD_THREAD_INLINE _GL_EXTERN_INLINE #include "glthread/thread.h" #include @@ -29,204 +27,190 @@ /* ========================================================================= */ -#if USE_POSIX_THREADS +#if USE_ISOC_THREADS -#include - -#if defined PTW32_VERSION || defined __MVS__ - -const gl_thread_t gl_null_thread /* = { .p = NULL } */; - -#endif - -#endif - -/* ========================================================================= */ - -#if USE_WINDOWS_THREADS - -#include - -/* -------------------------- gl_thread_t datatype -------------------------- */ +struct thrd_with_exitvalue +{ + thrd_t volatile tid; + void * volatile exitvalue; +}; -/* The Thread-Local Storage (TLS) key that allows to access each thread's - 'struct gl_thread_struct *' pointer. */ -static DWORD self_key = (DWORD)-1; +/* The Thread-Specific Storage (TSS) key that allows to access each thread's + 'struct thrd_with_exitvalue *' pointer. */ +static tss_t thrd_with_exitvalue_key; -/* Initializes self_key. This function must only be called once. */ +/* Initializes thrd_with_exitvalue_key. + This function must only be called once. */ static void -do_init_self_key (void) +do_init_thrd_with_exitvalue_key (void) { - self_key = TlsAlloc (); - /* If this fails, we're hosed. */ - if (self_key == (DWORD)-1) + if (tss_create (&thrd_with_exitvalue_key, NULL) != thrd_success) abort (); } -/* Initializes self_key. */ +/* Initializes thrd_with_exitvalue_key. */ static void -init_self_key (void) +init_thrd_with_exitvalue_key (void) { - gl_once_define(static, once) - gl_once (once, do_init_self_key); + static once_flag once = ONCE_FLAG_INIT; + call_once (&once, do_init_thrd_with_exitvalue_key); } -/* This structure contains information about a thread. - It is stored in TLS under key self_key. */ -struct gl_thread_struct -{ - /* Fields for managing the handle. */ - HANDLE volatile handle; - CRITICAL_SECTION handle_lock; - /* Fields for managing the exit value. */ - void * volatile result; - /* Fields for managing the thread start. */ - void * (*func) (void *); - void *arg; -}; +typedef union + { + struct thrd_with_exitvalue t; + struct + { + thrd_t tid; /* reserve memory for t.tid */ + void *(*mainfunc) (void *); + void *arg; + } a; + } + main_arg_t; -/* Return a real HANDLE object for the current thread. */ -static HANDLE -get_current_thread_handle (void) +static int +thrd_main_func (void *pmarg) { - HANDLE this_handle; + /* Unpack the object that combines mainfunc and arg. */ + main_arg_t *main_arg = (main_arg_t *) pmarg; + void *(*mainfunc) (void *) = main_arg->a.mainfunc; + void *arg = main_arg->a.arg; - /* GetCurrentThread() returns a pseudo-handle, i.e. only a symbolic - identifier, not a real handle. */ - if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), - GetCurrentProcess (), &this_handle, - 0, FALSE, DUPLICATE_SAME_ACCESS)) + if (tss_set (thrd_with_exitvalue_key, &main_arg->t) != thrd_success) abort (); - return this_handle; -} - -gl_thread_t -gl_thread_self_func (void) -{ - gl_thread_t thread; - - if (self_key == (DWORD)-1) - init_self_key (); - thread = TlsGetValue (self_key); - if (thread == NULL) - { - /* This happens only in threads that have not been created through - glthread_create(), such as the main thread. */ - for (;;) - { - thread = - (struct gl_thread_struct *) - malloc (sizeof (struct gl_thread_struct)); - if (thread != NULL) - break; - /* Memory allocation failed. There is not much we can do. Have to - busy-loop, waiting for the availability of memory. */ - Sleep (1); - } - - thread->handle = get_current_thread_handle (); - InitializeCriticalSection (&thread->handle_lock); - thread->result = NULL; /* just to be deterministic */ - TlsSetValue (self_key, thread); - } - return thread; -} -/* The main function of a freshly creating thread. It's a wrapper around - the FUNC and ARG arguments passed to glthread_create_func. */ -static unsigned int WINAPI -wrapper_func (void *varg) -{ - struct gl_thread_struct *thread = (struct gl_thread_struct *)varg; - - EnterCriticalSection (&thread->handle_lock); - /* Create a new handle for the thread only if the parent thread did not yet - fill in the handle. */ - if (thread->handle == NULL) - thread->handle = get_current_thread_handle (); - LeaveCriticalSection (&thread->handle_lock); - - if (self_key == (DWORD)-1) - init_self_key (); - TlsSetValue (self_key, thread); - - /* Run the thread. Store the exit value if the thread was not terminated - otherwise. */ - thread->result = thread->func (thread->arg); - return 0; + /* Execute mainfunc, with arg as argument. */ + { + void *exitvalue = mainfunc (arg); + /* Store the exitvalue, for use by glthread_join(). */ + main_arg->t.exitvalue = exitvalue; + return 0; + } } int -glthread_create_func (gl_thread_t *threadp, void * (*func) (void *), void *arg) +glthread_create (gl_thread_t *threadp, void *(*mainfunc) (void *), void *arg) { - struct gl_thread_struct *thread = - (struct gl_thread_struct *) malloc (sizeof (struct gl_thread_struct)); - if (thread == NULL) - return ENOMEM; - thread->handle = NULL; - InitializeCriticalSection (&thread->handle_lock); - thread->result = NULL; /* just to be deterministic */ - thread->func = func; - thread->arg = arg; - + init_thrd_with_exitvalue_key (); { - unsigned int thread_id; - HANDLE thread_handle; - - thread_handle = (HANDLE) - _beginthreadex (NULL, 100000, wrapper_func, thread, 0, &thread_id); - /* calls CreateThread with the same arguments */ - if (thread_handle == NULL) + /* 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 thrd_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 ENOMEM; + main_arg->a.mainfunc = mainfunc; + main_arg->a.arg = arg; + switch (thrd_create ((thrd_t *) &main_arg->t.tid, thrd_main_func, main_arg)) { - DeleteCriticalSection (&thread->handle_lock); - free (thread); + case thrd_success: + break; + case thrd_nomem: + free (main_arg); + return ENOMEM; + default: + free (main_arg); return EAGAIN; } - - EnterCriticalSection (&thread->handle_lock); - if (thread->handle == NULL) - thread->handle = thread_handle; - else - /* thread->handle was already set by the thread itself. */ - CloseHandle (thread_handle); - LeaveCriticalSection (&thread->handle_lock); - - *threadp = thread; + *threadp = &main_arg->t; return 0; } } +gl_thread_t +gl_thread_self (void) +{ + init_thrd_with_exitvalue_key (); + { + gl_thread_t thread = + (struct thrd_with_exitvalue *) tss_get (thrd_with_exitvalue_key); + if (thread == NULL) + { + /* This happens only in threads that have not been created through + glthread_create(), such as the main thread. */ + for (;;) + { + thread = + (struct thrd_with_exitvalue *) + malloc (sizeof (struct thrd_with_exitvalue)); + 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->exitvalue = NULL; /* just to be deterministic */ + if (tss_set (thrd_with_exitvalue_key, thread) != thrd_success) + abort (); + } + return thread; + } +} + int -glthread_join_func (gl_thread_t thread, void **retvalp) +glthread_join (gl_thread_t thread, void **return_value_ptr) { - if (thread == NULL) - return EINVAL; + /* On Solaris 11.4, thrd_join crashes when the second argument we pass is + NULL. */ + int dummy; if (thread == gl_thread_self ()) - return EDEADLK; - - if (WaitForSingleObject (thread->handle, INFINITE) == WAIT_FAILED) return EINVAL; - - if (retvalp != NULL) - *retvalp = thread->result; - - DeleteCriticalSection (&thread->handle_lock); - CloseHandle (thread->handle); + if (thrd_join (thread->tid, &dummy) != thrd_success) + return EINVAL; + if (return_value_ptr != NULL) + *return_value_ptr = thread->exitvalue; free (thread); - return 0; } -int -gl_thread_exit_func (void *retval) +_Noreturn void +gl_thread_exit (void *return_value) { gl_thread_t thread = gl_thread_self (); - thread->result = retval; - _endthreadex (0); /* calls ExitThread (0) */ - abort (); + thread->exitvalue = return_value; + thrd_exit (0); } #endif /* ========================================================================= */ + +#if USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS + +#include + +#if defined PTW32_VERSION || defined __MVS__ + +const gl_thread_t gl_null_thread /* = { .p = NULL } */; + +#endif + +#endif + +/* ========================================================================= */ + +#if USE_WINDOWS_THREADS + +#endif + +/* ========================================================================= */ + +gl_thread_t +gl_thread_create (void *(*func) (void *arg), void *arg) +{ + gl_thread_t thread; + int ret; + + ret = glthread_create (&thread, func, arg); + if (ret != 0) + abort (); + return thread; +} diff --git a/tests/glthread/thread.h b/tests/glthread/thread.h index 1e266bd..6d98f2d 100644 --- a/tests/glthread/thread.h +++ b/tests/glthread/thread.h @@ -1,22 +1,21 @@ /* Creating and controlling threads. - Copyright (C) 2005-2018 Free Software Foundation, Inc. + Copyright (C) 2005-2022 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 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Bruno Haible , 2005. - Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h, - gthr-win32.h. */ + Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-win32.h. */ /* This file contains primitives for creating and controlling threads. @@ -74,17 +73,53 @@ #include #include -#ifndef _GL_INLINE_HEADER_BEGIN - #error "Please include config.h first." +#if !defined c11_threads_in_use +# if HAVE_THREADS_H && USE_POSIX_THREADS_FROM_LIBC +# define c11_threads_in_use() 1 +# elif HAVE_THREADS_H && USE_POSIX_THREADS_WEAK +# include +# pragma weak thrd_exit +# define c11_threads_in_use() (thrd_exit != NULL) +# else +# define c11_threads_in_use() 0 +# endif #endif -_GL_INLINE_HEADER_BEGIN -#ifndef _GLTHREAD_THREAD_INLINE -# define _GLTHREAD_THREAD_INLINE _GL_INLINE + +/* ========================================================================= */ + +#if USE_ISOC_THREADS + +/* Use the ISO C threads library. */ + +# include + +# ifdef __cplusplus +extern "C" { +# endif + +/* -------------------------- gl_thread_t datatype -------------------------- */ + +typedef struct thrd_with_exitvalue *gl_thread_t; +extern int glthread_create (gl_thread_t *threadp, + void *(*func) (void *), void *arg); +# define glthread_sigmask(HOW, SET, OSET) \ + pthread_sigmask (HOW, SET, OSET) +extern int glthread_join (gl_thread_t thread, void **return_value_ptr); +extern gl_thread_t gl_thread_self (void); +# define gl_thread_self_pointer() \ + (void *) gl_thread_self () +extern _Noreturn void gl_thread_exit (void *return_value); +# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 + +# ifdef __cplusplus +} +# endif + #endif /* ========================================================================= */ -#if USE_POSIX_THREADS +#if USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS /* Use the POSIX threads library. */ @@ -133,8 +168,6 @@ extern int glthread_in_use (void); call to foo(...) in the same function. To avoid this, we test the address of a function in libpthread that we don't use. */ -# pragma weak pthread_create - # ifndef pthread_sigmask /* Do not declare rpl_pthread_sigmask weak. */ # pragma weak pthread_sigmask # endif @@ -150,7 +183,8 @@ extern int glthread_in_use (void); # if !PTHREAD_IN_USE_DETECTION_HARD # pragma weak pthread_mutexattr_gettype -# define pthread_in_use() (pthread_mutexattr_gettype != NULL) +# define pthread_in_use() \ + (pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) # endif # else @@ -192,12 +226,12 @@ extern const gl_thread_t gl_null_thread; extern const gl_thread_t gl_null_thread; # else # define gl_thread_self() \ - (pthread_in_use () ? pthread_self () : (pthread_t) NULL) + (pthread_in_use () ? pthread_self () : (pthread_t) 0) # define gl_thread_self_pointer() \ (pthread_in_use () ? (void *) pthread_self () : NULL) # endif # define gl_thread_exit(RETVAL) \ - (pthread_in_use () ? pthread_exit (RETVAL) : 0) + (void) (pthread_in_use () ? (pthread_exit (RETVAL), 0) : 0) # if HAVE_PTHREAD_ATFORK # define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) \ @@ -214,152 +248,33 @@ extern const gl_thread_t gl_null_thread; /* ========================================================================= */ -#if USE_PTH_THREADS - -/* Use the GNU Pth threads library. */ - -# include - -# ifdef __cplusplus -extern "C" { -# endif - -# if USE_PTH_THREADS_WEAK - -/* Use weak references to the GNU Pth threads library. */ - -# pragma weak pth_init -# pragma weak pth_spawn -# pragma weak pth_sigmask -# pragma weak pth_join -# pragma weak pth_self -# pragma weak pth_exit - -# pragma weak pth_cancel -# define pth_in_use() (pth_cancel != NULL) - -# else - -# define pth_in_use() 1 - -# endif -/* -------------------------- gl_thread_t datatype -------------------------- */ - -typedef pth_t gl_thread_t; -# define glthread_create(THREADP, FUNC, ARG) \ - (pth_in_use () ? (pth_init (), ((*(THREADP) = pth_spawn (NULL, FUNC, ARG)) ? 0 : errno)) : 0) -# define glthread_sigmask(HOW, SET, OSET) \ - (pth_in_use () ? (pth_init (), (pth_sigmask (HOW, SET, OSET) ? 0 : errno)) : 0) -# define glthread_join(THREAD, RETVALP) \ - (pth_in_use () ? (pth_init (), (pth_join (THREAD, RETVALP) ? 0 : errno)) : 0) -# define gl_thread_self() \ - (pth_in_use () ? (pth_init (), (void *) pth_self ()) : NULL) -# define gl_thread_self_pointer() \ - gl_thread_self () -# define gl_thread_exit(RETVAL) \ - (pth_in_use () ? (pth_init (), pth_exit (RETVAL)) : 0) -# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - -#if USE_SOLARIS_THREADS - -/* Use the old Solaris threads library. */ - -# include -# include - -# ifdef __cplusplus -extern "C" { -# endif - -# if USE_SOLARIS_THREADS_WEAK - -/* Use weak references to the old Solaris threads library. */ - -# pragma weak thr_create -# pragma weak thr_join -# pragma weak thr_self -# pragma weak thr_exit - -# pragma weak thr_suspend -# define thread_in_use() (thr_suspend != NULL) - -# else - -# define thread_in_use() 1 - -# endif - -/* -------------------------- gl_thread_t datatype -------------------------- */ - -typedef thread_t gl_thread_t; -# define glthread_create(THREADP, FUNC, ARG) \ - (thread_in_use () ? thr_create (NULL, 0, FUNC, ARG, 0, THREADP) : 0) -# define glthread_sigmask(HOW, SET, OSET) \ - (thread_in_use () ? sigprocmask (HOW, SET, OSET) : 0) -# define glthread_join(THREAD, RETVALP) \ - (thread_in_use () ? thr_join (THREAD, NULL, RETVALP) : 0) -# define gl_thread_self() \ - (thread_in_use () ? (void *) thr_self () : NULL) -# define gl_thread_self_pointer() \ - gl_thread_self () -# define gl_thread_exit(RETVAL) \ - (thread_in_use () ? thr_exit (RETVAL) : 0) -# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - #if USE_WINDOWS_THREADS # define WIN32_LEAN_AND_MEAN /* avoid including junk */ # include +# include "windows-thread.h" + # ifdef __cplusplus extern "C" { # endif /* -------------------------- gl_thread_t datatype -------------------------- */ -/* The gl_thread_t is a pointer to a structure in memory. - Why not the thread handle? If it were the thread handle, it would be hard - to implement gl_thread_self() (since GetCurrentThread () returns a pseudo- - handle, DuplicateHandle (GetCurrentThread ()) returns a handle that must be - closed afterwards, and there is no function for quickly retrieving a thread - handle from its id). - Why not the thread id? I tried it. It did not work: Sometimes ids appeared - that did not belong to running threads, and glthread_join failed with ESRCH. - */ -typedef struct gl_thread_struct *gl_thread_t; +typedef glwthread_thread_t gl_thread_t; # define glthread_create(THREADP, FUNC, ARG) \ - glthread_create_func (THREADP, FUNC, ARG) + glwthread_thread_create (THREADP, 0, FUNC, ARG) # define glthread_sigmask(HOW, SET, OSET) \ /* unsupported */ 0 # define glthread_join(THREAD, RETVALP) \ - glthread_join_func (THREAD, RETVALP) + glwthread_thread_join (THREAD, RETVALP) # define gl_thread_self() \ - gl_thread_self_func () + glwthread_thread_self () # define gl_thread_self_pointer() \ gl_thread_self () # define gl_thread_exit(RETVAL) \ - gl_thread_exit_func (RETVAL) + glwthread_thread_exit (RETVAL) # define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 -extern int glthread_create_func (gl_thread_t *threadp, void * (*func) (void *), void *arg); -extern int glthread_join_func (gl_thread_t thread, void **retvalp); -extern gl_thread_t gl_thread_self_func (void); -extern int gl_thread_exit_func (void *retval); # ifdef __cplusplus } @@ -369,7 +284,7 @@ extern int gl_thread_exit_func (void *retval); /* ========================================================================= */ -#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WINDOWS_THREADS) +#if !(USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS) /* Provide dummy implementation if threads are not supported. */ @@ -380,7 +295,7 @@ typedef int gl_thread_t; # define gl_thread_self() 0 # define gl_thread_self_pointer() \ ((void *) gl_thread_self ()) -# define gl_thread_exit(RETVAL) 0 +# define gl_thread_exit(RETVAL) (void)0 # define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 #endif @@ -393,17 +308,7 @@ typedef int gl_thread_t; extern "C" { #endif -_GLTHREAD_THREAD_INLINE gl_thread_t -gl_thread_create (void *(*func) (void *arg), void *arg) -{ - gl_thread_t thread; - int ret; - - ret = glthread_create (&thread, func, arg); - if (ret != 0) - abort (); - return thread; -} +extern gl_thread_t gl_thread_create (void *(*func) (void *arg), void *arg); #define gl_thread_sigmask(HOW, SET, OSET) \ do \ { \ @@ -430,6 +335,4 @@ gl_thread_create (void *(*func) (void *arg), void *arg) } #endif -_GL_INLINE_HEADER_END - #endif /* _GLTHREAD_THREAD_H */ diff --git a/tests/glthread/yield.h b/tests/glthread/yield.h index 4bb3ed4..f74267e 100644 --- a/tests/glthread/yield.h +++ b/tests/glthread/yield.h @@ -1,18 +1,18 @@ /* Yielding the processor to other threads and processes. - Copyright (C) 2005-2018 Free Software Foundation, Inc. + Copyright (C) 2005-2022 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 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* This file contains a primitive for yielding the processor to other threads. extern void gl_thread_yield (void); @@ -25,18 +25,18 @@ /* ========================================================================= */ -#if USE_POSIX_THREADS +#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS -/* Use the POSIX threads library. */ +/* Use the ISO C threads library. */ -# include +# include # ifdef __cplusplus extern "C" { # endif # define gl_thread_yield() \ - sched_yield () + thrd_yield () # ifdef __cplusplus } @@ -46,39 +46,18 @@ extern "C" { /* ========================================================================= */ -#if USE_PTH_THREADS - -/* Use the GNU Pth threads library. */ - -# include - -# ifdef __cplusplus -extern "C" { -# endif - -# define gl_thread_yield() \ - pth_yield (NULL) - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - -#if USE_SOLARIS_THREADS +#if USE_POSIX_THREADS -/* Use the old Solaris threads library. */ +/* Use the POSIX threads library. */ -# include +# include # ifdef __cplusplus extern "C" { # endif # define gl_thread_yield() \ - thr_yield () + sched_yield () # ifdef __cplusplus } @@ -108,7 +87,7 @@ extern "C" { /* ========================================================================= */ -#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WINDOWS_THREADS) +#if !(USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS) /* Provide dummy implementation if threads are not supported. */ -- cgit v1.2.3