Message ID | 1532526205-5708-1-git-send-email-adhemerval.zanella@linaro.org |
---|---|
State | Accepted |
Commit | 9faaf9385034ac71f308643de1afc91b5dd731aa |
Headers | show |
Series | Fix C11 conformance issues | expand |
Adhemerval Zanella, le mer. 25 juil. 2018 10:43:25 -0300, a ecrit: > It is expected due missing HTL ISO C threads support and both conformance > .out files indicates the reason ("#error "HTL does not implement ISO C > threads"). I thought the ISO C threads were just a layer on top of the POSIX threads, can't it be used on top of HTL too? I'm not saying we should aim for this in 2.28, just wondering. Samuel
On 07/25/2018 09:43 AM, Adhemerval Zanella wrote: > Remove conformace assumption of NPTL implementation for ISO C threads > and revert wrong libcrypt addition on linknamespace-libs-XPG4. > > The i686-gnu target now shows two new conformance failures: > > FAIL: conform/ISO11/threads.h/conform > FAIL: conform/ISO11/threads.h/linknamespace > > It is expected due missing HTL ISO C threads support and both conformance > .out files indicates the reason ("#error "HTL does not implement ISO C > threads"). > > Checked on i686-linux-gnu and i686-gnu. > > * include/threads.h: Move to ... > * sysdeps/nptl/threads.h: ... here. > * sysdeps/htl/threads.h: New file. > * conform/Makefile (linknamespace-libs-ISO11): Use > static-thread-library instead of linking libpthread. > (linknamespace-libs-XPG4): Revert wrong libcrypt.a addition. OK for 2.28. Reviewed-by: Carlos O'Donell <carlos@redhat.com> > --- > ChangeLog | 9 +++++++++ > conform/Makefile | 5 ++--- > sysdeps/htl/threads.h | 1 + > {include => sysdeps/nptl}/threads.h | 0 > 4 files changed, 12 insertions(+), 3 deletions(-) > create mode 100644 sysdeps/htl/threads.h > rename {include => sysdeps/nptl}/threads.h (100%) > > diff --git a/conform/Makefile b/conform/Makefile > index a0ab70e..d430931 100644 > --- a/conform/Makefile > +++ b/conform/Makefile > @@ -197,9 +197,8 @@ linknamespace-libs-xsi = $(linknamespace-libs-posix) > linknamespace-libs-ISO = $(linknamespace-libs-isoc) > linknamespace-libs-ISO99 = $(linknamespace-libs-isoc) > linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \ > - $(common-objpfx)nptl/libpthread.a > -linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \ > - $(common-objpfx)crypt/libcrypt.a > + $(static-thread-library) OK, uses static-thread-library. > +linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) OK, fixes libcrypt issue. > linknamespace-libs-XPG42 = $(linknamespace-libs-XPG4) > linknamespace-libs-POSIX = $(linknamespace-libs-thr) > linknamespace-libs-UNIX98 = $(linknamespace-libs-xsi) > diff --git a/sysdeps/htl/threads.h b/sysdeps/htl/threads.h > new file mode 100644 > index 0000000..3c04fbc > --- /dev/null > +++ b/sysdeps/htl/threads.h > @@ -0,0 +1 @@ > +#error "HTL does not implement ISO C threads" OK. > diff --git a/include/threads.h b/sysdeps/nptl/threads.h > similarity index 100% > rename from include/threads.h > rename to sysdeps/nptl/threads.h >
On 25/07/2018 10:51, Samuel Thibault wrote: > Adhemerval Zanella, le mer. 25 juil. 2018 10:43:25 -0300, a ecrit: >> It is expected due missing HTL ISO C threads support and both conformance >> .out files indicates the reason ("#error "HTL does not implement ISO C >> threads"). > > I thought the ISO C threads were just a layer on top of the POSIX > threads, can't it be used on top of HTL too? > > I'm not saying we should aim for this in 2.28, just wondering. > > Samuel > Currently implementation is based on POSIX internally, although it does not require to be (Florian has suggested we might use a more streamline implementation in the future). However you will need to correctly tie the HTL required types with ISO C threads without adding namespace or linkspace pollution. For NPTL we refactored the required information on pthreadtypes-arch.h, so to make threads.h generic HTL will need to provide a similar implementation (it also defines any internal structure alignment requirement, but afaiu HTL does not have any arch-specific constraint so far). I am not familiar with HTL internals, but ISO C required some NPTL internal adjustments: - the function pointer of the ISO C thread thrd_start start function has a different signature of pthread_create (int (*thrd_start_t) (void*) for ISO C and void *(*start_routine) (void *) for POSIX). - thrd_sleep call the syscall directly to avoid to handle the expected C11 states. It would require to add new nanosleep wrapper with expected behaviour. - thrd_yield also call the syscall directly, but adding a wrapper would be easier since there is no need to handle the return code. However I think it quite feasible for 2.29 to add ISO C threads Hurd/HTL support.
On Wed, 25 Jul 2018, Adhemerval Zanella wrote: > Checked on i686-linux-gnu and i686-gnu. > > * include/threads.h: Move to ... > * sysdeps/nptl/threads.h: ... here. > * sysdeps/htl/threads.h: New file. To confirm: nptl/threads.h, not the wrapper you're moving, still gets correctly installed as threads.h after this patch, while it remains the case that no threads.h is installed for Hurd? I think you need two separate versions of stdc-predef.h as well, so that Hurd gets a version that defines __STDC_NO_THREADS__. Then once there is a C11 threads implementation for HTL, we can move back to just having a single version of stdc-predef.h. (There should also be a single version of threads.h in that case, and we should aim to move towards a single pthread.h shared between NPTL and HTL as well.) -- Joseph S. Myers joseph@codesourcery.com
On Wed, 25 Jul 2018, Adhemerval Zanella wrote: > I am not familiar with HTL internals, but ISO C required some NPTL > internal adjustments: - The C11 threads functions call __pthread_* internally, so all those __pthread_* names needed to exist and, where they called POSIX functions internally, they needed to be made to call __* names for those functions where that wasn't previously necessary for POSIX namespace reasons. -- Joseph S. Myers joseph@codesourcery.com
On Wed, 25 Jul 2018, Joseph Myers wrote: > On Wed, 25 Jul 2018, Adhemerval Zanella wrote: > > > Checked on i686-linux-gnu and i686-gnu. > > > > * include/threads.h: Move to ... > > * sysdeps/nptl/threads.h: ... here. > > * sysdeps/htl/threads.h: New file. > > To confirm: nptl/threads.h, not the wrapper you're moving, still gets > correctly installed as threads.h after this patch, while it remains the > case that no threads.h is installed for Hurd? (The normal convention for a wrapper not in include would be for it to be in sysdeps/nptl/include/ rather than directly in sysdeps/nptl/.) -- Joseph S. Myers joseph@codesourcery.com
On Wed, 25 Jul 2018, Joseph Myers wrote: > On Wed, 25 Jul 2018, Adhemerval Zanella wrote: > > > Checked on i686-linux-gnu and i686-gnu. > > > > * include/threads.h: Move to ... > > * sysdeps/nptl/threads.h: ... here. > > * sysdeps/htl/threads.h: New file. > > To confirm: nptl/threads.h, not the wrapper you're moving, still gets > correctly installed as threads.h after this patch, while it remains the > case that no threads.h is installed for Hurd? I tested a build as of commit 08ac6bed146c0546d63163ac0d42c9a35880412d. This patch has resulted in the wrong threads.h being installed, i.e. usr/include/threads.h is now the wrapper that just does #include <nptl/threads.h>, which obviously won't work for an installed header. I think you need to put the real threads.h header in sysdeps/nptl/, not the wrapper (with a view to the Hurd work moving both the header, and the C11 threads implementation and tests, to sysdeps/pthread/ or some such shared location). -- Joseph S. Myers joseph@codesourcery.com
On 07/25/2018 03:43 PM, Adhemerval Zanella wrote: > linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \ > - $(common-objpfx)nptl/libpthread.a > -linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \ > - $(common-objpfx)crypt/libcrypt.a > + $(static-thread-library) I've just realized this: Linking with the static thread library obscures linknamespace issues in libc.a for symbols which are also defined in libpthread.a. So this change is a bit questionable. Thanks, Florian
On Wed, 25 Jul 2018, Florian Weimer wrote: > On 07/25/2018 03:43 PM, Adhemerval Zanella wrote: > > linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \ > > - $(common-objpfx)nptl/libpthread.a > > -linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \ > > - $(common-objpfx)crypt/libcrypt.a > > + $(static-thread-library) > > I've just realized this: > > Linking with the static thread library obscures linknamespace issues in libc.a > for symbols which are also defined in libpthread.a. So this change is a bit > questionable. The linknamespace code looks at every definition of a strong undefined symbol being resolved, not just the definition in a particular library. -- Joseph S. Myers joseph@codesourcery.com
On 07/25/2018 07:18 PM, Joseph Myers wrote: > On Wed, 25 Jul 2018, Florian Weimer wrote: > >> On 07/25/2018 03:43 PM, Adhemerval Zanella wrote: >>> linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \ >>> - $(common-objpfx)nptl/libpthread.a >>> -linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \ >>> - $(common-objpfx)crypt/libcrypt.a >>> + $(static-thread-library) >> >> I've just realized this: >> >> Linking with the static thread library obscures linknamespace issues in libc.a >> for symbols which are also defined in libpthread.a. So this change is a bit >> questionable. > > The linknamespace code looks at every definition of a strong undefined > symbol being resolved, not just the definition in a particular library. So there is not a problem after all? What seems to be a problem is that libpthread.a must now be C11-clean for its C11 symbols (which is currently not the case on Hurd). But fixing that is probably not a bad idea anyway. Florian
On Wed, 25 Jul 2018, Florian Weimer wrote: > On 07/25/2018 07:18 PM, Joseph Myers wrote: > > On Wed, 25 Jul 2018, Florian Weimer wrote: > > > > > On 07/25/2018 03:43 PM, Adhemerval Zanella wrote: > > > > linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \ > > > > - $(common-objpfx)nptl/libpthread.a > > > > -linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \ > > > > - $(common-objpfx)crypt/libcrypt.a > > > > + $(static-thread-library) > > > > > > I've just realized this: > > > > > > Linking with the static thread library obscures linknamespace issues in > > > libc.a > > > for symbols which are also defined in libpthread.a. So this change is a > > > bit > > > questionable. > > > > The linknamespace code looks at every definition of a strong undefined > > symbol being resolved, not just the definition in a particular library. > > So there is not a problem after all? I don't think there's any problem with that part of the patch. > What seems to be a problem is that libpthread.a must now be C11-clean for its > C11 symbols (which is currently not the case on Hurd). But fixing that is > probably not a bad idea anyway. Yes, if libpthread is used to provide some C11 symbols, it needs to be C11-clean for all the C11 symbols it provides (including those also present in libc). -- Joseph S. Myers joseph@codesourcery.com
On 25/07/2018 12:40, Joseph Myers wrote: > On Wed, 25 Jul 2018, Adhemerval Zanella wrote: > >> Checked on i686-linux-gnu and i686-gnu. >> >> * include/threads.h: Move to ... >> * sysdeps/nptl/threads.h: ... here. >> * sysdeps/htl/threads.h: New file. > > To confirm: nptl/threads.h, not the wrapper you're moving, still gets > correctly installed as threads.h after this patch, while it remains the > case that no threads.h is installed for Hurd? > > I think you need two separate versions of stdc-predef.h as well, so that > Hurd gets a version that defines __STDC_NO_THREADS__. Then once there is > a C11 threads implementation for HTL, we can move back to just having a > single version of stdc-predef.h. (There should also be a single version > of threads.h in that case, and we should aim to move towards a single > pthread.h shared between NPTL and HTL as well.) > The patch below should fix it and the hurd specific stdc-predef.h with __STDC_NO_THREADS__ defined. I would like to avoid duplicating a file contents, but the other possible alternative which I can think of would add a platform specific file (empty for nptl case and defining __STDC_NO_THREADS__ for htl) with the drawback of adding another include on every compilation (due extra include). I think we can live with a hurd specific stdc-predef.h for now. --- [PATCH] Fix ISO C threads installed header and HURD assumption Checked on both i686-linux-gnu and i686-gnu that both threads.h and stdc-predef.h are the expected ones. * nptl/threads.h: Move to ... * sysdeps/nptl/threads.h: ... here. * sysdeps/hurd/stdc-predef.h: New file. --- ChangeLog | 6 ++ nptl/threads.h | 207 -------------------------------------------- sysdeps/hurd/stdc-predef.h | 63 ++++++++++++++ sysdeps/nptl/threads.h | 208 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 276 insertions(+), 208 deletions(-) delete mode 100644 nptl/threads.h create mode 100644 sysdeps/hurd/stdc-predef.h diff --git a/nptl/threads.h b/nptl/threads.h deleted file mode 100644 index 9800f93..0000000 --- a/nptl/threads.h +++ /dev/null @@ -1,207 +0,0 @@ -/* ISO C11 Standard: 7.26 - Thread support library <threads.h>. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library 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. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _THREADS_H -#define _THREADS_H 1 - -#include <features.h> -#include <time.h> - -__BEGIN_DECLS - -#include <bits/pthreadtypes-arch.h> -#include <bits/types/struct_timespec.h> - -#ifndef __cplusplus -# define thread_local _Thread_local -#endif - -#define TSS_DTOR_ITERATIONS 4 -typedef unsigned int tss_t; -typedef void (*tss_dtor_t) (void*); - -typedef unsigned long int thrd_t; -typedef int (*thrd_start_t) (void*); - -/* Exit and error codes. */ -enum -{ - thrd_success = 0, - thrd_busy = 1, - thrd_error = 2, - thrd_nomem = 3, - thrd_timedout = 4 -}; - -/* Mutex types. */ -enum -{ - mtx_plain = 0, - mtx_recursive = 1, - mtx_timed = 2 -}; - -typedef struct -{ - int __data __ONCE_ALIGNMENT; -} once_flag; -#define ONCE_FLAG_INIT { 0 } - -typedef union -{ - char __size[__SIZEOF_PTHREAD_MUTEX_T]; - long int __align __LOCK_ALIGNMENT; -} mtx_t; - -typedef union -{ - char __size[__SIZEOF_PTHREAD_COND_T]; - __extension__ long long int __align __LOCK_ALIGNMENT; -} cnd_t; - -/* Threads functions. */ - -/* Create a new thread executing the function __FUNC. Arguments for __FUNC - are passed through __ARG. If succesful, __THR is set to new thread - identifier. */ -extern int thrd_create (thrd_t *__thr, thrd_start_t __func, void *__arg); - -/* Check if __LHS and __RHS point to the same thread. */ -extern int thrd_equal (thrd_t __lhs, thrd_t __rhs); - -/* Return current thread identifier. */ -extern thrd_t thrd_current (void); - -/* Block current thread execution for at least the time pointed by - __TIME_POINT. The current thread may resume if receives a signal. In - that case, if __REMAINING is not NULL, the remaining time is stored in - the object pointed by it. */ -extern int thrd_sleep (const struct timespec *__time_point, - struct timespec *__remaining); - -/* Terminate current thread execution, cleaning up any thread local - storage and freeing resources. Returns the value specified in __RES. */ -extern void thrd_exit (int __res) __attribute__ ((__noreturn__)); - -/* Detach the thread identified by __THR from the current environment - (it does not allow join or wait for it). */ -extern int thrd_detach (thrd_t __thr); - -/* Block current thread until execution of __THR is complete. In case that - __RES is not NULL, will store the return value of __THR when exiting. */ -extern int thrd_join (thrd_t __thr, int *__res); - -/* Stop current thread execution and call the scheduler to decide which - thread should execute next. The current thread may be selected by the - scheduler to keep running. */ -extern void thrd_yield (void); - -#ifdef __USE_EXTERN_INLINES -/* Optimizations. */ -__extern_inline int -thrd_equal (thrd_t __thread1, thrd_t __thread2) -{ - return __thread1 == __thread2; -} -#endif - - -/* Mutex functions. */ - -/* Creates a new mutex object with type __TYPE. If successful the new - object is pointed by __MUTEX. */ -extern int mtx_init (mtx_t *__mutex, int __type); - -/* Block the current thread until the mutex pointed to by __MUTEX is - unlocked. In that case current thread will not be blocked. */ -extern int mtx_lock (mtx_t *__mutex); - -/* Block the current thread until the mutex pointed by __MUTEX is unlocked - or time pointed by __TIME_POINT is reached. In case the mutex is unlock, - the current thread will not be blocked. */ -extern int mtx_timedlock (mtx_t *__restrict __mutex, - const struct timespec *__restrict __time_point); - -/* Try to lock the mutex pointed by __MUTEX without blocking. If the mutex - is free the current threads takes control of it, otherwise it returns - immediately. */ -extern int mtx_trylock (mtx_t *__mutex); - -/* Unlock the mutex pointed by __MUTEX. It may potentially awake other - threads waiting on this mutex. */ -extern int mtx_unlock (mtx_t *__mutex); - -/* Destroy the mutex object pointed by __MUTEX. */ -extern void mtx_destroy (mtx_t *__mutex); - - -/* Call function __FUNC exactly once, even if invoked from several threads. - All calls must be made with the same __FLAGS object. */ -extern void call_once (once_flag *__flag, void (*__func)(void)); - - -/* Condition variable functions. */ - -/* Initialize new condition variable pointed by __COND. */ -extern int cnd_init (cnd_t *__cond); - -/* Unblock one thread that currently waits on condition variable pointed - by __COND. */ -extern int cnd_signal (cnd_t *__cond); - -/* Unblock all threads currently waiting on condition variable pointed by - __COND. */ -extern int cnd_broadcast (cnd_t *__cond); - -/* Block current thread on the condition variable pointed by __COND. */ -extern int cnd_wait (cnd_t *__cond, mtx_t *__mutex); - -/* Block current thread on the condition variable until condition variable - pointed by __COND is signaled or time pointed by __TIME_POINT is - reached. */ -extern int cnd_timedwait (cnd_t *__restrict __cond, - mtx_t *__restrict __mutex, - const struct timespec *__restrict __time_point); - -/* Destroy condition variable pointed by __cond and free all of its - resources. */ -extern void cnd_destroy (cnd_t *__COND); - - -/* Thread specific storage functions. */ - -/* Create new thread-specific storage key and stores it in the object pointed - by __TSS_ID. If __DESTRUCTOR is not NULL, the function will be called when - the thread terminates. */ -extern int tss_create (tss_t *__tss_id, tss_dtor_t __destructor); - -/* Return the value held in thread-specific storage for the current thread - identified by __TSS_ID. */ -extern void *tss_get (tss_t __tss_id); - -/* Sets the value of the thread-specific storage identified by __TSS_ID for - the current thread to __VAL. */ -extern int tss_set (tss_t __tss_id, void *__val); - -/* Destroys the thread-specific storage identified by __TSS_ID. The - destructor is not called until thrd_exit is called. */ -extern void tss_delete (tss_t __tss_id); - -__END_DECLS - -#endif /* _THREADS_H */ diff --git a/sysdeps/hurd/stdc-predef.h b/sysdeps/hurd/stdc-predef.h new file mode 100644 index 0000000..4c11188 --- /dev/null +++ b/sysdeps/hurd/stdc-predef.h @@ -0,0 +1,63 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library 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. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _STDC_PREDEF_H +#define _STDC_PREDEF_H 1 + +/* This header is separate from features.h so that the compiler can + include it implicitly at the start of every compilation. It must + not itself include <features.h> or any other header that includes + <features.h> because the implicit include comes before any feature + test macros that may be defined in a source file before it first + explicitly includes a system header. GCC knows the name of this + header in order to preinclude it. */ + +/* glibc's intent is to support the IEC 559 math functionality, real + and complex. If the GCC (4.9 and later) predefined macros + specifying compiler intent are available, use them to determine + whether the overall intent is to support these features; otherwise, + presume an older compiler has intent to support these features and + define these macros by default. */ + +#ifdef __GCC_IEC_559 +# if __GCC_IEC_559 > 0 +# define __STDC_IEC_559__ 1 +# endif +#else +# define __STDC_IEC_559__ 1 +#endif + +#ifdef __GCC_IEC_559_COMPLEX +# if __GCC_IEC_559_COMPLEX > 0 +# define __STDC_IEC_559_COMPLEX__ 1 +# endif +#else +# define __STDC_IEC_559_COMPLEX__ 1 +#endif + +/* wchar_t uses Unicode 10.0.0. Version 10.0 of the Unicode Standard is + synchronized with ISO/IEC 10646:2017, fifth edition, plus + the following additions from Amendment 1 to the fifth edition: + - 56 emoji characters + - 285 hentaigana + - 3 additional Zanabazar Square characters */ +#define __STDC_ISO_10646__ 201706L + +/* We do not support C11 <threads.h>. */ +#define __STDC_NO_THREADS__ 1 + +#endif diff --git a/sysdeps/nptl/threads.h b/sysdeps/nptl/threads.h index 1090612..9800f93 100644 --- a/sysdeps/nptl/threads.h +++ b/sysdeps/nptl/threads.h @@ -1 +1,207 @@ -#include <nptl/threads.h> +/* ISO C11 Standard: 7.26 - Thread support library <threads.h>. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library 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. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _THREADS_H +#define _THREADS_H 1 + +#include <features.h> +#include <time.h> + +__BEGIN_DECLS + +#include <bits/pthreadtypes-arch.h> +#include <bits/types/struct_timespec.h> + +#ifndef __cplusplus +# define thread_local _Thread_local +#endif + +#define TSS_DTOR_ITERATIONS 4 +typedef unsigned int tss_t; +typedef void (*tss_dtor_t) (void*); + +typedef unsigned long int thrd_t; +typedef int (*thrd_start_t) (void*); + +/* Exit and error codes. */ +enum +{ + thrd_success = 0, + thrd_busy = 1, + thrd_error = 2, + thrd_nomem = 3, + thrd_timedout = 4 +}; + +/* Mutex types. */ +enum +{ + mtx_plain = 0, + mtx_recursive = 1, + mtx_timed = 2 +}; + +typedef struct +{ + int __data __ONCE_ALIGNMENT; +} once_flag; +#define ONCE_FLAG_INIT { 0 } + +typedef union +{ + char __size[__SIZEOF_PTHREAD_MUTEX_T]; + long int __align __LOCK_ALIGNMENT; +} mtx_t; + +typedef union +{ + char __size[__SIZEOF_PTHREAD_COND_T]; + __extension__ long long int __align __LOCK_ALIGNMENT; +} cnd_t; + +/* Threads functions. */ + +/* Create a new thread executing the function __FUNC. Arguments for __FUNC + are passed through __ARG. If succesful, __THR is set to new thread + identifier. */ +extern int thrd_create (thrd_t *__thr, thrd_start_t __func, void *__arg); + +/* Check if __LHS and __RHS point to the same thread. */ +extern int thrd_equal (thrd_t __lhs, thrd_t __rhs); + +/* Return current thread identifier. */ +extern thrd_t thrd_current (void); + +/* Block current thread execution for at least the time pointed by + __TIME_POINT. The current thread may resume if receives a signal. In + that case, if __REMAINING is not NULL, the remaining time is stored in + the object pointed by it. */ +extern int thrd_sleep (const struct timespec *__time_point, + struct timespec *__remaining); + +/* Terminate current thread execution, cleaning up any thread local + storage and freeing resources. Returns the value specified in __RES. */ +extern void thrd_exit (int __res) __attribute__ ((__noreturn__)); + +/* Detach the thread identified by __THR from the current environment + (it does not allow join or wait for it). */ +extern int thrd_detach (thrd_t __thr); + +/* Block current thread until execution of __THR is complete. In case that + __RES is not NULL, will store the return value of __THR when exiting. */ +extern int thrd_join (thrd_t __thr, int *__res); + +/* Stop current thread execution and call the scheduler to decide which + thread should execute next. The current thread may be selected by the + scheduler to keep running. */ +extern void thrd_yield (void); + +#ifdef __USE_EXTERN_INLINES +/* Optimizations. */ +__extern_inline int +thrd_equal (thrd_t __thread1, thrd_t __thread2) +{ + return __thread1 == __thread2; +} +#endif + + +/* Mutex functions. */ + +/* Creates a new mutex object with type __TYPE. If successful the new + object is pointed by __MUTEX. */ +extern int mtx_init (mtx_t *__mutex, int __type); + +/* Block the current thread until the mutex pointed to by __MUTEX is + unlocked. In that case current thread will not be blocked. */ +extern int mtx_lock (mtx_t *__mutex); + +/* Block the current thread until the mutex pointed by __MUTEX is unlocked + or time pointed by __TIME_POINT is reached. In case the mutex is unlock, + the current thread will not be blocked. */ +extern int mtx_timedlock (mtx_t *__restrict __mutex, + const struct timespec *__restrict __time_point); + +/* Try to lock the mutex pointed by __MUTEX without blocking. If the mutex + is free the current threads takes control of it, otherwise it returns + immediately. */ +extern int mtx_trylock (mtx_t *__mutex); + +/* Unlock the mutex pointed by __MUTEX. It may potentially awake other + threads waiting on this mutex. */ +extern int mtx_unlock (mtx_t *__mutex); + +/* Destroy the mutex object pointed by __MUTEX. */ +extern void mtx_destroy (mtx_t *__mutex); + + +/* Call function __FUNC exactly once, even if invoked from several threads. + All calls must be made with the same __FLAGS object. */ +extern void call_once (once_flag *__flag, void (*__func)(void)); + + +/* Condition variable functions. */ + +/* Initialize new condition variable pointed by __COND. */ +extern int cnd_init (cnd_t *__cond); + +/* Unblock one thread that currently waits on condition variable pointed + by __COND. */ +extern int cnd_signal (cnd_t *__cond); + +/* Unblock all threads currently waiting on condition variable pointed by + __COND. */ +extern int cnd_broadcast (cnd_t *__cond); + +/* Block current thread on the condition variable pointed by __COND. */ +extern int cnd_wait (cnd_t *__cond, mtx_t *__mutex); + +/* Block current thread on the condition variable until condition variable + pointed by __COND is signaled or time pointed by __TIME_POINT is + reached. */ +extern int cnd_timedwait (cnd_t *__restrict __cond, + mtx_t *__restrict __mutex, + const struct timespec *__restrict __time_point); + +/* Destroy condition variable pointed by __cond and free all of its + resources. */ +extern void cnd_destroy (cnd_t *__COND); + + +/* Thread specific storage functions. */ + +/* Create new thread-specific storage key and stores it in the object pointed + by __TSS_ID. If __DESTRUCTOR is not NULL, the function will be called when + the thread terminates. */ +extern int tss_create (tss_t *__tss_id, tss_dtor_t __destructor); + +/* Return the value held in thread-specific storage for the current thread + identified by __TSS_ID. */ +extern void *tss_get (tss_t __tss_id); + +/* Sets the value of the thread-specific storage identified by __TSS_ID for + the current thread to __VAL. */ +extern int tss_set (tss_t __tss_id, void *__val); + +/* Destroys the thread-specific storage identified by __TSS_ID. The + destructor is not called until thrd_exit is called. */ +extern void tss_delete (tss_t __tss_id); + +__END_DECLS + +#endif /* _THREADS_H */
On 25/07/2018 12:42, Joseph Myers wrote: > On Wed, 25 Jul 2018, Adhemerval Zanella wrote: > >> I am not familiar with HTL internals, but ISO C required some NPTL >> internal adjustments: > > - The C11 threads functions call __pthread_* internally, so all those > __pthread_* names needed to exist and, where they called POSIX functions > internally, they needed to be made to call __* names for those functions > where that wasn't previously necessary for POSIX namespace reasons. > So summarize and assuming the fix for the stdc-predef.h for HURD [1], ISO C threads support for HTL would require: - Add the required __pthread_* alias called from C11 threads and also fix any internal possible linkspace name issue by calling libpthread __* names. - Correctly tie the HTL required types with ISO C threads without adding namespace or linkspace pollution by adding a platform pthreadtypes-arch.h implementation (not sure if it would require arch-specific ones since HURD since to support only i686). - Check if HTL requires some handling of the function pointer mismatch between ISO C thread thrd_start start and pthread_create. - Add a wrapper to nanosleep to return syscall return code directly to use on thrd_sleep. - Call __sched_yield in thrd_yield. - Remove hurd specific stdc-predef.h and htl threads.h and make threads.h the generic one. [1] https://sourceware.org/ml/libc-alpha/2018-07/msg00835.html
On 07/25/2018 07:47 PM, Joseph Myers wrote: >> What seems to be a problem is that libpthread.a must now be C11-clean for its >> C11 symbols (which is currently not the case on Hurd). But fixing that is >> probably not a bad idea anyway. > > Yes, if libpthread is used to provide some C11 symbols, it needs to be > C11-clean for all the C11 symbols it provides (including those also > present in libc). So I think we need something like this. It resolves the new linknamespace failures for me. Thanks, Florian Subject: [PATCH] htl: Use weak aliases for public symbols To: libc-alpha@sourceware.org Strong definitions of flockfile, funlockfile, ftrylockfile can conflict with application symbols when linking statically. 2018-07-25 Florian Weimer <fweimer@redhat.com> * htl/lockfile.c (flockfile, funlockfile, ftrylockfile): Use weak aliases for symbols not in the implementation namespace. diff --git a/htl/lockfile.c b/htl/lockfile.c index 7828d47dae..1d0ab88b13 100644 --- a/htl/lockfile.c +++ b/htl/lockfile.c @@ -53,8 +53,8 @@ int _IO_ftrylockfile (FILE *) __attribute__ ((alias ("_cthreads_ftrylockfile"))); void flockfile (FILE *) - __attribute__ ((alias ("_cthreads_flockfile"))); + __attribute__ ((weak, alias ("_cthreads_flockfile"))); void funlockfile (FILE *) - __attribute__ ((alias ("_cthreads_funlockfile"))); + __attribute__ ((weak, alias ("_cthreads_funlockfile"))); int ftrylockfile (FILE *) - __attribute__ ((alias ("_cthreads_ftrylockfile"))); + __attribute__ ((weak, alias ("_cthreads_ftrylockfile")));
On Wed, 25 Jul 2018, Adhemerval Zanella wrote: > The patch below should fix it and the hurd specific stdc-predef.h with > __STDC_NO_THREADS__ defined. I would like to avoid duplicating a file > contents, but the other possible alternative which I can think of would > add a platform specific file (empty for nptl case and defining > __STDC_NO_THREADS__ for htl) with the drawback of adding another > include on every compilation (due extra include). I think we can > live with a hurd specific stdc-predef.h for now. This patch is OK. The handling of precompiled headers in GCC is very fragile with regard to implicitly preincluded files and if stdc-predef.h were to include another header, there would be a significant chance of this breaking PCH. -- Joseph S. Myers joseph@codesourcery.com
On Wed, 25 Jul 2018, Adhemerval Zanella wrote: > So summarize and assuming the fix for the stdc-predef.h for HURD [1], > ISO C threads support for HTL would require: > > - Add the required __pthread_* alias called from C11 threads and > also fix any internal possible linkspace name issue by calling > libpthread __* names. > > - Correctly tie the HTL required types with ISO C threads without > adding namespace or linkspace pollution by adding a platform > pthreadtypes-arch.h implementation (not sure if it would require > arch-specific ones since HURD since to support only i686). > > - Check if HTL requires some handling of the function pointer > mismatch between ISO C thread thrd_start start and pthread_create. > > - Add a wrapper to nanosleep to return syscall return code directly > to use on thrd_sleep. > > - Call __sched_yield in thrd_yield. > > - Remove hurd specific stdc-predef.h and htl threads.h and make > threads.h the generic one. - Move all the relevant implementation files and tests and associated makefile logic out of nptl/ into a shared directory such as sysdeps/pthread/ so that they get built for Hurd as well. -- Joseph S. Myers joseph@codesourcery.com
On 25/07/2018 17:20, Joseph Myers wrote: > On Wed, 25 Jul 2018, Adhemerval Zanella wrote: > >> So summarize and assuming the fix for the stdc-predef.h for HURD [1], >> ISO C threads support for HTL would require: >> >> - Add the required __pthread_* alias called from C11 threads and >> also fix any internal possible linkspace name issue by calling >> libpthread __* names. >> >> - Correctly tie the HTL required types with ISO C threads without >> adding namespace or linkspace pollution by adding a platform >> pthreadtypes-arch.h implementation (not sure if it would require >> arch-specific ones since HURD since to support only i686). >> >> - Check if HTL requires some handling of the function pointer >> mismatch between ISO C thread thrd_start start and pthread_create. >> >> - Add a wrapper to nanosleep to return syscall return code directly >> to use on thrd_sleep. >> >> - Call __sched_yield in thrd_yield. >> >> - Remove hurd specific stdc-predef.h and htl threads.h and make >> threads.h the generic one. > > - Move all the relevant implementation files and tests and associated > makefile logic out of nptl/ into a shared directory such as > sysdeps/pthread/ so that they get built for Hurd as well. > Right, I will try to spend some cycles for 2.29.
On 07/25/2018 04:03 PM, Florian Weimer wrote: > Strong definitions of flockfile, funlockfile, ftrylockfile can conflict > with application symbols when linking statically. This looks OK to me for 2.28. Reviewed-by: Carlos O'Donell <carlos@redhat.com> > 2018-07-25 Florian Weimer <fweimer@redhat.com> > > * htl/lockfile.c (flockfile, funlockfile, ftrylockfile): Use weak > aliases for symbols not in the implementation namespace. > > diff --git a/htl/lockfile.c b/htl/lockfile.c > index 7828d47dae..1d0ab88b13 100644 > --- a/htl/lockfile.c > +++ b/htl/lockfile.c > @@ -53,8 +53,8 @@ int _IO_ftrylockfile (FILE *) > __attribute__ ((alias ("_cthreads_ftrylockfile"))); > > void flockfile (FILE *) > - __attribute__ ((alias ("_cthreads_flockfile"))); > + __attribute__ ((weak, alias ("_cthreads_flockfile"))); > void funlockfile (FILE *) > - __attribute__ ((alias ("_cthreads_funlockfile"))); > + __attribute__ ((weak, alias ("_cthreads_funlockfile"))); > int ftrylockfile (FILE *) > - __attribute__ ((alias ("_cthreads_ftrylockfile"))); > + __attribute__ ((weak, alias ("_cthreads_ftrylockfile"))); OK. c.
On 07/25/2018 02:28 PM, Adhemerval Zanella wrote: > [PATCH] Fix ISO C threads installed header and HURD assumption > > Checked on both i686-linux-gnu and i686-gnu that both threads.h > and stdc-predef.h are the expected ones. > > * nptl/threads.h: Move to ... > * sysdeps/nptl/threads.h: ... here. > * sysdeps/hurd/stdc-predef.h: New file. This is OK for 2.28. It is just movement of the normal threads.h to nptl (not generic anymore), and the new stdc-predef.h for hurd. With the other fixes that you and Joseph discussed coming in 2.29 or later. Reviewed-by: Carlos O'Donell <carlos@redhat.com> > --- > ChangeLog | 6 ++ > nptl/threads.h | 207 -------------------------------------------- > sysdeps/hurd/stdc-predef.h | 63 ++++++++++++++ > sysdeps/nptl/threads.h | 208 ++++++++++++++++++++++++++++++++++++++++++++- > 4 files changed, 276 insertions(+), 208 deletions(-) > delete mode 100644 nptl/threads.h > create mode 100644 sysdeps/hurd/stdc-predef.h > > diff --git a/nptl/threads.h b/nptl/threads.h > deleted file mode 100644 > index 9800f93..0000000 > --- a/nptl/threads.h > +++ /dev/null > @@ -1,207 +0,0 @@ > -/* ISO C11 Standard: 7.26 - Thread support library <threads.h>. > - Copyright (C) 2018 Free Software Foundation, Inc. > - This file is part of the GNU C Library. > - > - The GNU C Library 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. > - > - The GNU C Library 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 > - Lesser General Public License for more details. > - > - You should have received a copy of the GNU Lesser General Public > - License along with the GNU C Library; if not, see > - <http://www.gnu.org/licenses/>. */ > - > -#ifndef _THREADS_H > -#define _THREADS_H 1 > - > -#include <features.h> > -#include <time.h> > - > -__BEGIN_DECLS > - > -#include <bits/pthreadtypes-arch.h> > -#include <bits/types/struct_timespec.h> > - > -#ifndef __cplusplus > -# define thread_local _Thread_local > -#endif > - > -#define TSS_DTOR_ITERATIONS 4 > -typedef unsigned int tss_t; > -typedef void (*tss_dtor_t) (void*); > - > -typedef unsigned long int thrd_t; > -typedef int (*thrd_start_t) (void*); > - > -/* Exit and error codes. */ > -enum > -{ > - thrd_success = 0, > - thrd_busy = 1, > - thrd_error = 2, > - thrd_nomem = 3, > - thrd_timedout = 4 > -}; > - > -/* Mutex types. */ > -enum > -{ > - mtx_plain = 0, > - mtx_recursive = 1, > - mtx_timed = 2 > -}; > - > -typedef struct > -{ > - int __data __ONCE_ALIGNMENT; > -} once_flag; > -#define ONCE_FLAG_INIT { 0 } > - > -typedef union > -{ > - char __size[__SIZEOF_PTHREAD_MUTEX_T]; > - long int __align __LOCK_ALIGNMENT; > -} mtx_t; > - > -typedef union > -{ > - char __size[__SIZEOF_PTHREAD_COND_T]; > - __extension__ long long int __align __LOCK_ALIGNMENT; > -} cnd_t; > - > -/* Threads functions. */ > - > -/* Create a new thread executing the function __FUNC. Arguments for __FUNC > - are passed through __ARG. If succesful, __THR is set to new thread > - identifier. */ > -extern int thrd_create (thrd_t *__thr, thrd_start_t __func, void *__arg); > - > -/* Check if __LHS and __RHS point to the same thread. */ > -extern int thrd_equal (thrd_t __lhs, thrd_t __rhs); > - > -/* Return current thread identifier. */ > -extern thrd_t thrd_current (void); > - > -/* Block current thread execution for at least the time pointed by > - __TIME_POINT. The current thread may resume if receives a signal. In > - that case, if __REMAINING is not NULL, the remaining time is stored in > - the object pointed by it. */ > -extern int thrd_sleep (const struct timespec *__time_point, > - struct timespec *__remaining); > - > -/* Terminate current thread execution, cleaning up any thread local > - storage and freeing resources. Returns the value specified in __RES. */ > -extern void thrd_exit (int __res) __attribute__ ((__noreturn__)); > - > -/* Detach the thread identified by __THR from the current environment > - (it does not allow join or wait for it). */ > -extern int thrd_detach (thrd_t __thr); > - > -/* Block current thread until execution of __THR is complete. In case that > - __RES is not NULL, will store the return value of __THR when exiting. */ > -extern int thrd_join (thrd_t __thr, int *__res); > - > -/* Stop current thread execution and call the scheduler to decide which > - thread should execute next. The current thread may be selected by the > - scheduler to keep running. */ > -extern void thrd_yield (void); > - > -#ifdef __USE_EXTERN_INLINES > -/* Optimizations. */ > -__extern_inline int > -thrd_equal (thrd_t __thread1, thrd_t __thread2) > -{ > - return __thread1 == __thread2; > -} > -#endif > - > - > -/* Mutex functions. */ > - > -/* Creates a new mutex object with type __TYPE. If successful the new > - object is pointed by __MUTEX. */ > -extern int mtx_init (mtx_t *__mutex, int __type); > - > -/* Block the current thread until the mutex pointed to by __MUTEX is > - unlocked. In that case current thread will not be blocked. */ > -extern int mtx_lock (mtx_t *__mutex); > - > -/* Block the current thread until the mutex pointed by __MUTEX is unlocked > - or time pointed by __TIME_POINT is reached. In case the mutex is unlock, > - the current thread will not be blocked. */ > -extern int mtx_timedlock (mtx_t *__restrict __mutex, > - const struct timespec *__restrict __time_point); > - > -/* Try to lock the mutex pointed by __MUTEX without blocking. If the mutex > - is free the current threads takes control of it, otherwise it returns > - immediately. */ > -extern int mtx_trylock (mtx_t *__mutex); > - > -/* Unlock the mutex pointed by __MUTEX. It may potentially awake other > - threads waiting on this mutex. */ > -extern int mtx_unlock (mtx_t *__mutex); > - > -/* Destroy the mutex object pointed by __MUTEX. */ > -extern void mtx_destroy (mtx_t *__mutex); > - > - > -/* Call function __FUNC exactly once, even if invoked from several threads. > - All calls must be made with the same __FLAGS object. */ > -extern void call_once (once_flag *__flag, void (*__func)(void)); > - > - > -/* Condition variable functions. */ > - > -/* Initialize new condition variable pointed by __COND. */ > -extern int cnd_init (cnd_t *__cond); > - > -/* Unblock one thread that currently waits on condition variable pointed > - by __COND. */ > -extern int cnd_signal (cnd_t *__cond); > - > -/* Unblock all threads currently waiting on condition variable pointed by > - __COND. */ > -extern int cnd_broadcast (cnd_t *__cond); > - > -/* Block current thread on the condition variable pointed by __COND. */ > -extern int cnd_wait (cnd_t *__cond, mtx_t *__mutex); > - > -/* Block current thread on the condition variable until condition variable > - pointed by __COND is signaled or time pointed by __TIME_POINT is > - reached. */ > -extern int cnd_timedwait (cnd_t *__restrict __cond, > - mtx_t *__restrict __mutex, > - const struct timespec *__restrict __time_point); > - > -/* Destroy condition variable pointed by __cond and free all of its > - resources. */ > -extern void cnd_destroy (cnd_t *__COND); > - > - > -/* Thread specific storage functions. */ > - > -/* Create new thread-specific storage key and stores it in the object pointed > - by __TSS_ID. If __DESTRUCTOR is not NULL, the function will be called when > - the thread terminates. */ > -extern int tss_create (tss_t *__tss_id, tss_dtor_t __destructor); > - > -/* Return the value held in thread-specific storage for the current thread > - identified by __TSS_ID. */ > -extern void *tss_get (tss_t __tss_id); > - > -/* Sets the value of the thread-specific storage identified by __TSS_ID for > - the current thread to __VAL. */ > -extern int tss_set (tss_t __tss_id, void *__val); > - > -/* Destroys the thread-specific storage identified by __TSS_ID. The > - destructor is not called until thrd_exit is called. */ > -extern void tss_delete (tss_t __tss_id); > - > -__END_DECLS > - > -#endif /* _THREADS_H */ > diff --git a/sysdeps/hurd/stdc-predef.h b/sysdeps/hurd/stdc-predef.h > new file mode 100644 > index 0000000..4c11188 > --- /dev/null > +++ b/sysdeps/hurd/stdc-predef.h > @@ -0,0 +1,63 @@ > +/* Copyright (C) 2018 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library 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. > + > + The GNU C Library 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 > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <http://www.gnu.org/licenses/>. */ > + > +#ifndef _STDC_PREDEF_H > +#define _STDC_PREDEF_H 1 > + > +/* This header is separate from features.h so that the compiler can > + include it implicitly at the start of every compilation. It must > + not itself include <features.h> or any other header that includes > + <features.h> because the implicit include comes before any feature > + test macros that may be defined in a source file before it first > + explicitly includes a system header. GCC knows the name of this > + header in order to preinclude it. */ > + > +/* glibc's intent is to support the IEC 559 math functionality, real > + and complex. If the GCC (4.9 and later) predefined macros > + specifying compiler intent are available, use them to determine > + whether the overall intent is to support these features; otherwise, > + presume an older compiler has intent to support these features and > + define these macros by default. */ > + > +#ifdef __GCC_IEC_559 > +# if __GCC_IEC_559 > 0 > +# define __STDC_IEC_559__ 1 > +# endif > +#else > +# define __STDC_IEC_559__ 1 > +#endif > + > +#ifdef __GCC_IEC_559_COMPLEX > +# if __GCC_IEC_559_COMPLEX > 0 > +# define __STDC_IEC_559_COMPLEX__ 1 > +# endif > +#else > +# define __STDC_IEC_559_COMPLEX__ 1 > +#endif > + > +/* wchar_t uses Unicode 10.0.0. Version 10.0 of the Unicode Standard is > + synchronized with ISO/IEC 10646:2017, fifth edition, plus > + the following additions from Amendment 1 to the fifth edition: > + - 56 emoji characters > + - 285 hentaigana > + - 3 additional Zanabazar Square characters */ > +#define __STDC_ISO_10646__ 201706L > + > +/* We do not support C11 <threads.h>. */ > +#define __STDC_NO_THREADS__ 1 > + > +#endif > diff --git a/sysdeps/nptl/threads.h b/sysdeps/nptl/threads.h > index 1090612..9800f93 100644 > --- a/sysdeps/nptl/threads.h > +++ b/sysdeps/nptl/threads.h > @@ -1 +1,207 @@ > -#include <nptl/threads.h> > +/* ISO C11 Standard: 7.26 - Thread support library <threads.h>. > + Copyright (C) 2018 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library 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. > + > + The GNU C Library 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 > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <http://www.gnu.org/licenses/>. */ > + > +#ifndef _THREADS_H > +#define _THREADS_H 1 > + > +#include <features.h> > +#include <time.h> > + > +__BEGIN_DECLS > + > +#include <bits/pthreadtypes-arch.h> > +#include <bits/types/struct_timespec.h> > + > +#ifndef __cplusplus > +# define thread_local _Thread_local > +#endif > + > +#define TSS_DTOR_ITERATIONS 4 > +typedef unsigned int tss_t; > +typedef void (*tss_dtor_t) (void*); > + > +typedef unsigned long int thrd_t; > +typedef int (*thrd_start_t) (void*); > + > +/* Exit and error codes. */ > +enum > +{ > + thrd_success = 0, > + thrd_busy = 1, > + thrd_error = 2, > + thrd_nomem = 3, > + thrd_timedout = 4 > +}; > + > +/* Mutex types. */ > +enum > +{ > + mtx_plain = 0, > + mtx_recursive = 1, > + mtx_timed = 2 > +}; > + > +typedef struct > +{ > + int __data __ONCE_ALIGNMENT; > +} once_flag; > +#define ONCE_FLAG_INIT { 0 } > + > +typedef union > +{ > + char __size[__SIZEOF_PTHREAD_MUTEX_T]; > + long int __align __LOCK_ALIGNMENT; > +} mtx_t; > + > +typedef union > +{ > + char __size[__SIZEOF_PTHREAD_COND_T]; > + __extension__ long long int __align __LOCK_ALIGNMENT; > +} cnd_t; > + > +/* Threads functions. */ > + > +/* Create a new thread executing the function __FUNC. Arguments for __FUNC > + are passed through __ARG. If succesful, __THR is set to new thread > + identifier. */ > +extern int thrd_create (thrd_t *__thr, thrd_start_t __func, void *__arg); > + > +/* Check if __LHS and __RHS point to the same thread. */ > +extern int thrd_equal (thrd_t __lhs, thrd_t __rhs); > + > +/* Return current thread identifier. */ > +extern thrd_t thrd_current (void); > + > +/* Block current thread execution for at least the time pointed by > + __TIME_POINT. The current thread may resume if receives a signal. In > + that case, if __REMAINING is not NULL, the remaining time is stored in > + the object pointed by it. */ > +extern int thrd_sleep (const struct timespec *__time_point, > + struct timespec *__remaining); > + > +/* Terminate current thread execution, cleaning up any thread local > + storage and freeing resources. Returns the value specified in __RES. */ > +extern void thrd_exit (int __res) __attribute__ ((__noreturn__)); > + > +/* Detach the thread identified by __THR from the current environment > + (it does not allow join or wait for it). */ > +extern int thrd_detach (thrd_t __thr); > + > +/* Block current thread until execution of __THR is complete. In case that > + __RES is not NULL, will store the return value of __THR when exiting. */ > +extern int thrd_join (thrd_t __thr, int *__res); > + > +/* Stop current thread execution and call the scheduler to decide which > + thread should execute next. The current thread may be selected by the > + scheduler to keep running. */ > +extern void thrd_yield (void); > + > +#ifdef __USE_EXTERN_INLINES > +/* Optimizations. */ > +__extern_inline int > +thrd_equal (thrd_t __thread1, thrd_t __thread2) > +{ > + return __thread1 == __thread2; > +} > +#endif > + > + > +/* Mutex functions. */ > + > +/* Creates a new mutex object with type __TYPE. If successful the new > + object is pointed by __MUTEX. */ > +extern int mtx_init (mtx_t *__mutex, int __type); > + > +/* Block the current thread until the mutex pointed to by __MUTEX is > + unlocked. In that case current thread will not be blocked. */ > +extern int mtx_lock (mtx_t *__mutex); > + > +/* Block the current thread until the mutex pointed by __MUTEX is unlocked > + or time pointed by __TIME_POINT is reached. In case the mutex is unlock, > + the current thread will not be blocked. */ > +extern int mtx_timedlock (mtx_t *__restrict __mutex, > + const struct timespec *__restrict __time_point); > + > +/* Try to lock the mutex pointed by __MUTEX without blocking. If the mutex > + is free the current threads takes control of it, otherwise it returns > + immediately. */ > +extern int mtx_trylock (mtx_t *__mutex); > + > +/* Unlock the mutex pointed by __MUTEX. It may potentially awake other > + threads waiting on this mutex. */ > +extern int mtx_unlock (mtx_t *__mutex); > + > +/* Destroy the mutex object pointed by __MUTEX. */ > +extern void mtx_destroy (mtx_t *__mutex); > + > + > +/* Call function __FUNC exactly once, even if invoked from several threads. > + All calls must be made with the same __FLAGS object. */ > +extern void call_once (once_flag *__flag, void (*__func)(void)); > + > + > +/* Condition variable functions. */ > + > +/* Initialize new condition variable pointed by __COND. */ > +extern int cnd_init (cnd_t *__cond); > + > +/* Unblock one thread that currently waits on condition variable pointed > + by __COND. */ > +extern int cnd_signal (cnd_t *__cond); > + > +/* Unblock all threads currently waiting on condition variable pointed by > + __COND. */ > +extern int cnd_broadcast (cnd_t *__cond); > + > +/* Block current thread on the condition variable pointed by __COND. */ > +extern int cnd_wait (cnd_t *__cond, mtx_t *__mutex); > + > +/* Block current thread on the condition variable until condition variable > + pointed by __COND is signaled or time pointed by __TIME_POINT is > + reached. */ > +extern int cnd_timedwait (cnd_t *__restrict __cond, > + mtx_t *__restrict __mutex, > + const struct timespec *__restrict __time_point); > + > +/* Destroy condition variable pointed by __cond and free all of its > + resources. */ > +extern void cnd_destroy (cnd_t *__COND); > + > + > +/* Thread specific storage functions. */ > + > +/* Create new thread-specific storage key and stores it in the object pointed > + by __TSS_ID. If __DESTRUCTOR is not NULL, the function will be called when > + the thread terminates. */ > +extern int tss_create (tss_t *__tss_id, tss_dtor_t __destructor); > + > +/* Return the value held in thread-specific storage for the current thread > + identified by __TSS_ID. */ > +extern void *tss_get (tss_t __tss_id); > + > +/* Sets the value of the thread-specific storage identified by __TSS_ID for > + the current thread to __VAL. */ > +extern int tss_set (tss_t __tss_id, void *__val); > + > +/* Destroys the thread-specific storage identified by __TSS_ID. The > + destructor is not called until thrd_exit is called. */ > +extern void tss_delete (tss_t __tss_id); > + > +__END_DECLS > + > +#endif /* _THREADS_H */ >
diff --git a/conform/Makefile b/conform/Makefile index a0ab70e..d430931 100644 --- a/conform/Makefile +++ b/conform/Makefile @@ -197,9 +197,8 @@ linknamespace-libs-xsi = $(linknamespace-libs-posix) linknamespace-libs-ISO = $(linknamespace-libs-isoc) linknamespace-libs-ISO99 = $(linknamespace-libs-isoc) linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \ - $(common-objpfx)nptl/libpthread.a -linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \ - $(common-objpfx)crypt/libcrypt.a + $(static-thread-library) +linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) linknamespace-libs-XPG42 = $(linknamespace-libs-XPG4) linknamespace-libs-POSIX = $(linknamespace-libs-thr) linknamespace-libs-UNIX98 = $(linknamespace-libs-xsi) diff --git a/sysdeps/htl/threads.h b/sysdeps/htl/threads.h new file mode 100644 index 0000000..3c04fbc --- /dev/null +++ b/sysdeps/htl/threads.h @@ -0,0 +1 @@ +#error "HTL does not implement ISO C threads" diff --git a/include/threads.h b/sysdeps/nptl/threads.h similarity index 100% rename from include/threads.h rename to sysdeps/nptl/threads.h