Message ID | 1517591084-11347-3-git-send-email-adhemerval.zanella@linaro.org |
---|---|
State | New |
Headers | show |
Series | Add support for ISO C threads.h | expand |
On 02/02/2018 06:04 PM, Adhemerval Zanella wrote: > This patch adds the mtx_* definitions from C11 threads (ISO/IEC 9899:2011), > more specifically mtx_init, mtx_destroy, mtx_lock, mtx_timedlock, mtx_trylock, > mtx_unlock, and required types. > > Mostly of the definitions are composed based on POSIX conterparts, and mtx_t > is also based on internal pthread fields, but with a distinct internal layout > to avoid possible issues with code interchange (such as trying to pass POSIX > structure on C11 functions and to avoid inclusion of pthread.h). The idea > is to make possible to share POSIX internal implementations for mostly of > the code (and making adjustment only when required). Should we check for the supported mutex types and error out if the type does not match? The interface does not support the full range of error codes required by robust mutexes, for example—EOWNERDEAD is missing. Thanks, Florian
On 06/07/2018 09:51, Florian Weimer wrote: > On 02/02/2018 06:04 PM, Adhemerval Zanella wrote: >> This patch adds the mtx_* definitions from C11 threads (ISO/IEC 9899:2011), >> more specifically mtx_init, mtx_destroy, mtx_lock, mtx_timedlock, mtx_trylock, >> mtx_unlock, and required types. >> >> Mostly of the definitions are composed based on POSIX conterparts, and mtx_t >> is also based on internal pthread fields, but with a distinct internal layout >> to avoid possible issues with code interchange (such as trying to pass POSIX >> structure on C11 functions and to avoid inclusion of pthread.h). The idea >> is to make possible to share POSIX internal implementations for mostly of >> the code (and making adjustment only when required). > > Should we check for the supported mutex types and error out if the type does not match? The interface does not support the full range of error codes required by robust mutexes, for example—EOWNERDEAD is missing. > I am not sure if adding extra tests will yield any gain, specially on mutex operations which users would expect optimized fast paths. I really think we should handle as undefined behaviour if uses try to use pthread_t objects with c11 threads function (in similar manner it is undefined behaviour if uses messes with internal pthread_mutex_t objects data directly).
On 07/10/2018 02:35 PM, Adhemerval Zanella wrote: > > > On 06/07/2018 09:51, Florian Weimer wrote: >> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote: >>> This patch adds the mtx_* definitions from C11 threads (ISO/IEC 9899:2011), >>> more specifically mtx_init, mtx_destroy, mtx_lock, mtx_timedlock, mtx_trylock, >>> mtx_unlock, and required types. >>> >>> Mostly of the definitions are composed based on POSIX conterparts, and mtx_t >>> is also based on internal pthread fields, but with a distinct internal layout >>> to avoid possible issues with code interchange (such as trying to pass POSIX >>> structure on C11 functions and to avoid inclusion of pthread.h). The idea >>> is to make possible to share POSIX internal implementations for mostly of >>> the code (and making adjustment only when required). >> >> Should we check for the supported mutex types and error out if the type does not match? The interface does not support the full range of error codes required by robust mutexes, for example—EOWNERDEAD is missing. >> > > I am not sure if adding extra tests will yield any gain, specially on mutex > operations which users would expect optimized fast paths. I really think > we should handle as undefined behaviour if uses try to use pthread_t objects > with c11 threads function (in similar manner it is undefined behaviour if > uses messes with internal pthread_mutex_t objects data directly). Some people might be tempted to use the C11 interfaces to avoid the (formal) namespace violations of the POSIX functions, but still stick to the underlying POSIX objects for type compatibility on other interfaces. But I think we can clearly document that they shouldn't do this. I'm concerned about this because in the future, we might compile the implementations to remove checks that are not needed for the C11 implementations. Thanks, Florian
On 12/07/2018 15:39, Florian Weimer wrote: > On 07/10/2018 02:35 PM, Adhemerval Zanella wrote: >> >> >> On 06/07/2018 09:51, Florian Weimer wrote: >>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote: >>>> This patch adds the mtx_* definitions from C11 threads (ISO/IEC 9899:2011), >>>> more specifically mtx_init, mtx_destroy, mtx_lock, mtx_timedlock, mtx_trylock, >>>> mtx_unlock, and required types. >>>> >>>> Mostly of the definitions are composed based on POSIX conterparts, and mtx_t >>>> is also based on internal pthread fields, but with a distinct internal layout >>>> to avoid possible issues with code interchange (such as trying to pass POSIX >>>> structure on C11 functions and to avoid inclusion of pthread.h). The idea >>>> is to make possible to share POSIX internal implementations for mostly of >>>> the code (and making adjustment only when required). >>> >>> Should we check for the supported mutex types and error out if the type does not match? The interface does not support the full range of error codes required by robust mutexes, for example—EOWNERDEAD is missing. >>> >> >> I am not sure if adding extra tests will yield any gain, specially on mutex >> operations which users would expect optimized fast paths. I really think >> we should handle as undefined behaviour if uses try to use pthread_t objects >> with c11 threads function (in similar manner it is undefined behaviour if >> uses messes with internal pthread_mutex_t objects data directly). > > Some people might be tempted to use the C11 interfaces to avoid the (formal) namespace violations of the POSIX functions, but still stick to the underlying POSIX objects for type compatibility on other interfaces. > > But I think we can clearly document that they shouldn't do this. Even if developers try to do this, it will be implementation specific (in a sense an implementation may provide different underlying types for POSIX and C11 thread objects). I really think we should explicit this is a non-supported scenario. > > I'm concerned about this because in the future, we might compile the implementations to remove checks that are not needed for the C11 implementations. Why kind of scenario do you have in mind? Maybe use a more streamlined internal implementation for C11 threads?
On 07/12/2018 10:30 PM, Adhemerval Zanella wrote: >> I'm concerned about this because in the future, we might compile the implementations to remove checks that are not needed for the C11 implementations. > > Why kind of scenario do you have in mind? Maybe use a more streamlined > internal implementation for C11 threads? Yes, the polymorphic mutex types must have *some* overhead (think of speculatively executing the wrong atomics), and less polymorphism should improve performance. Thanks, Florian
On 12/07/2018 17:38, Florian Weimer wrote: > On 07/12/2018 10:30 PM, Adhemerval Zanella wrote: > >>> I'm concerned about this because in the future, we might compile the implementations to remove checks that are not needed for the C11 implementations. >> >> Why kind of scenario do you have in mind? Maybe use a more streamlined >> internal implementation for C11 threads? > > Yes, the polymorphic mutex types must have *some* overhead (think of speculatively executing the wrong atomics), and less polymorphism should improve performance. I think it would quite feasible in next releases to refactor the mutex code into C11 required operation and POSIX one and optimize C11 implementation with a simpler internal one. The bulk of the work is disentangle the mutex code (I started to check on this sometime ago, but got sidetracked).
On 07/13/2018 03:08 PM, Adhemerval Zanella wrote: > > > On 12/07/2018 17:38, Florian Weimer wrote: >> On 07/12/2018 10:30 PM, Adhemerval Zanella wrote: >> >>>> I'm concerned about this because in the future, we might compile the implementations to remove checks that are not needed for the C11 implementations. >>> >>> Why kind of scenario do you have in mind? Maybe use a more streamlined >>> internal implementation for C11 threads? >> >> Yes, the polymorphic mutex types must have *some* overhead (think of speculatively executing the wrong atomics), and less polymorphism should improve performance. > > I think it would quite feasible in next releases to refactor the mutex > code into C11 required operation and POSIX one and optimize C11 > implementation with a simpler internal one. The bulk of the work is > disentangle the mutex code (I started to check on this sometime ago, > but got sidetracked). Sure, we can delay this work somewhat, but I'd like to backport the optimization into 2.28 once we have it, to discourage such invalid uses. Thanks, Florian
Updated patch from Carlos suggestion. Changes from previous version: - Remove an extra mtx_destroy on nptl/Versions. - Adjusted the wording on cnd_init static asserts. - Add bugzilla entry and adjusted glibc version on CL. --- This patch adds the cnd_* definitions from C11 threads (ISO/IEC 9899:2011), more specifically cnd_broadcast, cnd_destroy, cnd_init, cnd_signal, cnd_timedwait, cnd_wait, and required types. Mostly of the definitions are composed based on POSIX conterparts, and cnd_t is also based on internal pthreads fields, but with distinct internal layout to avoid possible issues with code interchange (such as trying to pass POSIX structure on C11 functions and to avoid inclusion of pthread.h). The idea is to make it possible to share POSIX internal implementation for mostly of the code making adjust where only required. Checked with a build for all major ABI (aarch64-linux-gnu, alpha-linux-gnu, arm-linux-gnueabi, i386-linux-gnu, ia64-linux-gnu, m68k-linux-gnu, microblaze-linux-gnu [1], mips{64}-linux-gnu, nios2-linux-gnu, powerpc{64le}-linux-gnu, s390{x}-linux-gnu, sparc{64}-linux-gnu, tile{pro,gx}-linux-gnu, and x86_64-linux-gnu). Also ran a full check on aarch64-linux-gnu, x86_64-linux-gnu, i686-linux-gnu, arm-linux-gnueabhf, and powerpc64le-linux-gnu. [BZ #14092] * conform/data/threads.h-data (cnd_t): New type. (cnd_init): New function. (cnd_signal): Likewise. (cnd_broadcast): Likewise. (cnd_wait): Likewise. (cnd_timedwait): Likewise. (cnd_destroy): Likewise. * nptl/Makefile (libpthread-routines): Add cnd_broadcast, cnd_destroy, cnd_init, cnd_signal, cnd_timedwait, and cnd_wait object. * nptl/Versions (libpthread) [GLIBC_2.28]: Likewise. * nptl/cnd_broadcast.c: New file. * nptl/cnd_destroy.c: Likewise. * nptl/cnd_init.c: Likewise. * nptl/cnd_signal.c: Likewise. * nptl/cnd_timedwait.c: Likewise. * nptl/cnd_wait.c: Likewise. * sysdeps/nptl/threads.h (cnd_t): New type. (cnd_init): New prototype. (cnd_signa): Likewise. (cnd_broadcast): Likewise. (cnd_wait): Likewise. (cnd_timedwait): Likewise. (cnd_destroy): Likewise. --- ChangeLog | 26 ++++++++++++++++++++++++++ conform/data/threads.h-data | 8 ++++++++ nptl/Makefile | 3 ++- nptl/Versions | 3 ++- nptl/cnd_broadcast.c | 26 ++++++++++++++++++++++++++ nptl/cnd_destroy.c | 26 ++++++++++++++++++++++++++ nptl/cnd_init.c | 33 +++++++++++++++++++++++++++++++++ nptl/cnd_signal.c | 26 ++++++++++++++++++++++++++ nptl/cnd_timedwait.c | 29 +++++++++++++++++++++++++++++ nptl/cnd_wait.c | 27 +++++++++++++++++++++++++++ nptl/threads.h | 34 ++++++++++++++++++++++++++++++++++ 11 files changed, 239 insertions(+), 2 deletions(-) create mode 100644 nptl/cnd_broadcast.c create mode 100644 nptl/cnd_destroy.c create mode 100644 nptl/cnd_init.c create mode 100644 nptl/cnd_signal.c create mode 100644 nptl/cnd_timedwait.c create mode 100644 nptl/cnd_wait.c diff --git a/ChangeLog b/ChangeLog index 1b1d79e..f92f25a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,32 @@ 2018-07-21 Adhemerval Zanella <adhemerval.zanella@linaro.org> [BZ #14092] + * conform/data/threads.h-data (cnd_t): New type. + (cnd_init): New function. + (cnd_signal): Likewise. + (cnd_broadcast): Likewise. + (cnd_wait): Likewise. + (cnd_timedwait): Likewise. + (cnd_destroy): Likewise. + * nptl/Makefile (libpthread-routines): Add cnd_broadcast, + cnd_destroy, cnd_init, cnd_signal, cnd_timedwait, and cnd_wait + object. + * nptl/Versions (libpthread) [GLIBC_2.28]: Likewise. + * nptl/cnd_broadcast.c: New file. + * nptl/cnd_destroy.c: Likewise. + * nptl/cnd_init.c: Likewise. + * nptl/cnd_signal.c: Likewise. + * nptl/cnd_timedwait.c: Likewise. + * nptl/cnd_wait.c: Likewise. + * sysdeps/nptl/threads.h (cnd_t): New type. + (cnd_init): New prototype. + (cnd_signa): Likewise. + (cnd_broadcast): Likewise. + (cnd_wait): Likewise. + (cnd_timedwait): Likewise. + (cnd_destroy): Likewise. + + [BZ #14092] * conform/data/threads.h-data (ONCE_FLAG_INIT): New macro. (once_flag): New type. (call_once): New function. diff --git a/conform/data/threads.h-data b/conform/data/threads.h-data index 70b2fe0..d7c562e 100644 --- a/conform/data/threads.h-data +++ b/conform/data/threads.h-data @@ -16,6 +16,7 @@ type thrd_t type thrd_start_t type mtx_t type once_flag +type cnd_t function int thrd_create (thrd_t*, thrd_start_t, void*) function int thrd_equal (thrd_t, thrd_t) @@ -35,6 +36,13 @@ function void mtx_destroy (mtx_t*) function void call_once (once_flag*, void (*)(void)) +function int cnd_init (cnd_t*) +function int cnd_signal (cnd_t*) +function int cnd_broadcast (cnd_t*) +function int cnd_wait (cnd_t*, mtx_t*) +function int cnd_timedwait (cnd_t*, mtx_t*, const struct timespec*) +function void cnd_destroy (cnd_t*) + #include "time.h-data" #endif diff --git a/nptl/Makefile b/nptl/Makefile index d55d24b..0864aee 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -143,7 +143,8 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \ pthread_setattr_default_np pthread_getattr_default_np \ thrd_create thrd_detach thrd_exit thrd_join \ mtx_destroy mtx_init mtx_lock mtx_timedlock \ - mtx_trylock mtx_unlock call_once + mtx_trylock mtx_unlock call_once cnd_broadcast \ + cnd_destroy cnd_init cnd_signal cnd_timedwait cnd_wait # pthread_setuid pthread_seteuid pthread_setreuid \ # pthread_setresuid \ # pthread_setgid pthread_setegid pthread_setregid \ diff --git a/nptl/Versions b/nptl/Versions index 0fdba18..9c38d67 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -273,7 +273,8 @@ libpthread { GLIBC_2.28 { thrd_create; thrd_detach; thrd_exit; thrd_join; mtx_init; mtx_lock; mtx_timedlock; mtx_trylock; mtx_unlock; mtx_destroy; - call_once; + call_once; cnd_broadcast; cnd_destroy; cnd_init; cnd_signal; + cnd_timedwait; cnd_wait; } GLIBC_PRIVATE { diff --git a/nptl/cnd_broadcast.c b/nptl/cnd_broadcast.c new file mode 100644 index 0000000..889f88e --- /dev/null +++ b/nptl/cnd_broadcast.c @@ -0,0 +1,26 @@ +/* C11 thread conditional broadcast implementation. + 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/>. */ + +#include "thrd_priv.h" + +int +cnd_broadcast (cnd_t *cond) +{ + int err_code = __pthread_cond_broadcast ((pthread_cond_t*) cond); + return thrd_err_map (err_code); +} diff --git a/nptl/cnd_destroy.c b/nptl/cnd_destroy.c new file mode 100644 index 0000000..37df9e9 --- /dev/null +++ b/nptl/cnd_destroy.c @@ -0,0 +1,26 @@ +/* C11 threads conditional destroy implementation. + 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/>. */ + +#include "thrd_priv.h" +#include "pthreadP.h" + +void +cnd_destroy (cnd_t *cond) +{ + __pthread_cond_destroy ((pthread_cond_t *) cond); +} diff --git a/nptl/cnd_init.c b/nptl/cnd_init.c new file mode 100644 index 0000000..13f0f80 --- /dev/null +++ b/nptl/cnd_init.c @@ -0,0 +1,33 @@ +/* C11 thread conditional initialization implementation. + 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/>. */ + +#include <stdalign.h> + +#include "thrd_priv.h" + +int +cnd_init (cnd_t *cond) +{ + _Static_assert (sizeof (cnd_t) == sizeof (pthread_cond_t), + "(sizeof (cnd_t) != sizeof (pthread_cond_t)"); + _Static_assert (alignof (cnd_t) == alignof (pthread_cond_t), + "alignof (cnd_t) != alignof (pthread_cond_t)"); + + int err_code = __pthread_cond_init ((pthread_cond_t *)cond, NULL); + return thrd_err_map (err_code); +} diff --git a/nptl/cnd_signal.c b/nptl/cnd_signal.c new file mode 100644 index 0000000..8ae650b --- /dev/null +++ b/nptl/cnd_signal.c @@ -0,0 +1,26 @@ +/* C11 threads conditional signal implementation. + 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/>. */ + +#include "thrd_priv.h" + +int +cnd_signal (cnd_t *cond) +{ + int err_code = __pthread_cond_signal ((pthread_cond_t *) cond); + return thrd_err_map (err_code); +} diff --git a/nptl/cnd_timedwait.c b/nptl/cnd_timedwait.c new file mode 100644 index 0000000..75358fe --- /dev/null +++ b/nptl/cnd_timedwait.c @@ -0,0 +1,29 @@ +/* C11 threads conditional timed wait implementation. + 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/>. */ + +#include "thrd_priv.h" + +int +cnd_timedwait (cnd_t *restrict cond, mtx_t *restrict mutex, + const struct timespec* restrict time_point) +{ + int err_code = __pthread_cond_timedwait ((pthread_cond_t *) cond, + (pthread_mutex_t *) mutex, + time_point); + return thrd_err_map (err_code); +} diff --git a/nptl/cnd_wait.c b/nptl/cnd_wait.c new file mode 100644 index 0000000..727d9bb --- /dev/null +++ b/nptl/cnd_wait.c @@ -0,0 +1,27 @@ +/* C11 threads conditional wait implementaiton. + 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/>. */ + +#include "thrd_priv.h" + +int +cnd_wait (cnd_t *cond, mtx_t *mutex) +{ + int err_code = __pthread_cond_wait ((pthread_cond_t *) cond, + (pthread_mutex_t *) mutex); + return thrd_err_map (err_code); +} diff --git a/nptl/threads.h b/nptl/threads.h index 32f7cf8..e46b1b7 100644 --- a/nptl/threads.h +++ b/nptl/threads.h @@ -60,6 +60,12 @@ typedef union 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 @@ -140,6 +146,34 @@ extern void mtx_destroy (mtx_t *__mutex); 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); + __END_DECLS #endif /* _THREADS_H */ -- 2.7.4
On 07/24/2018 08:04 AM, Adhemerval Zanella wrote: > Updated patch from Carlos suggestion. Changes from previous version: > > - Remove an extra mtx_destroy on nptl/Versions. > - Adjusted the wording on cnd_init static asserts. > - Add bugzilla entry and adjusted glibc version on CL. > > --- > > This patch adds the cnd_* definitions from C11 threads (ISO/IEC 9899:2011), > more specifically cnd_broadcast, cnd_destroy, cnd_init, cnd_signal, > cnd_timedwait, cnd_wait, and required types. > OK. I confirm going through the standard and I see: cnd_t, cnd_broadcast, cnd_destroy, cnd_init, cnd_signal, cnd_timedwait, and cnd_wait as the only condvar functions in use. The rest of the usage requires the mutex support which has already been reviewed. > Mostly of the definitions are composed based on POSIX conterparts, and > cnd_t is also based on internal pthreads fields, but with distinct internal > layout to avoid possible issues with code interchange (such as trying to pass > POSIX structure on C11 functions and to avoid inclusion of pthread.h). The > idea is to make it possible to share POSIX internal implementation for mostly > of the code making adjust where only required. OK. > Checked with a build for all major ABI (aarch64-linux-gnu, alpha-linux-gnu, > arm-linux-gnueabi, i386-linux-gnu, ia64-linux-gnu, m68k-linux-gnu, > microblaze-linux-gnu [1], mips{64}-linux-gnu, nios2-linux-gnu, > powerpc{64le}-linux-gnu, s390{x}-linux-gnu, sparc{64}-linux-gnu, > tile{pro,gx}-linux-gnu, and x86_64-linux-gnu). OK. > Also ran a full check on aarch64-linux-gnu, x86_64-linux-gnu, i686-linux-gnu, > arm-linux-gnueabhf, and powerpc64le-linux-gnu. > > [BZ #14092] > * conform/data/threads.h-data (cnd_t): New type. > (cnd_init): New function. > (cnd_signal): Likewise. > (cnd_broadcast): Likewise. > (cnd_wait): Likewise. > (cnd_timedwait): Likewise. > (cnd_destroy): Likewise. > * nptl/Makefile (libpthread-routines): Add cnd_broadcast, > cnd_destroy, cnd_init, cnd_signal, cnd_timedwait, and cnd_wait > object. > * nptl/Versions (libpthread) [GLIBC_2.28]: Likewise. > * nptl/cnd_broadcast.c: New file. > * nptl/cnd_destroy.c: Likewise. > * nptl/cnd_init.c: Likewise. > * nptl/cnd_signal.c: Likewise. > * nptl/cnd_timedwait.c: Likewise. > * nptl/cnd_wait.c: Likewise. > * sysdeps/nptl/threads.h (cnd_t): New type. > (cnd_init): New prototype. > (cnd_signa): Likewise. > (cnd_broadcast): Likewise. > (cnd_wait): Likewise. > (cnd_timedwait): Likewise. > (cnd_destroy): Likewise. This looks good to me. Reviewed-by: Carlos O'Donell <carlos@redhat.com> > --- > ChangeLog | 26 ++++++++++++++++++++++++++ > conform/data/threads.h-data | 8 ++++++++ > nptl/Makefile | 3 ++- > nptl/Versions | 3 ++- > nptl/cnd_broadcast.c | 26 ++++++++++++++++++++++++++ > nptl/cnd_destroy.c | 26 ++++++++++++++++++++++++++ > nptl/cnd_init.c | 33 +++++++++++++++++++++++++++++++++ > nptl/cnd_signal.c | 26 ++++++++++++++++++++++++++ > nptl/cnd_timedwait.c | 29 +++++++++++++++++++++++++++++ > nptl/cnd_wait.c | 27 +++++++++++++++++++++++++++ > nptl/threads.h | 34 ++++++++++++++++++++++++++++++++++ > 11 files changed, 239 insertions(+), 2 deletions(-) > create mode 100644 nptl/cnd_broadcast.c > create mode 100644 nptl/cnd_destroy.c > create mode 100644 nptl/cnd_init.c > create mode 100644 nptl/cnd_signal.c > create mode 100644 nptl/cnd_timedwait.c > create mode 100644 nptl/cnd_wait.c This looks good to me. It looks good to me for 2.28. Reviewed-by: Carlos O'Donell <carlos@redhat.com> > diff --git a/ChangeLog b/ChangeLog > index 1b1d79e..f92f25a 100644 > --- a/ChangeLog > +++ b/ChangeLog > @@ -1,6 +1,32 @@ > 2018-07-21 Adhemerval Zanella <adhemerval.zanella@linaro.org> > > [BZ #14092] > + * conform/data/threads.h-data (cnd_t): New type. > + (cnd_init): New function. > + (cnd_signal): Likewise. > + (cnd_broadcast): Likewise. > + (cnd_wait): Likewise. > + (cnd_timedwait): Likewise. > + (cnd_destroy): Likewise. > + * nptl/Makefile (libpthread-routines): Add cnd_broadcast, > + cnd_destroy, cnd_init, cnd_signal, cnd_timedwait, and cnd_wait > + object. > + * nptl/Versions (libpthread) [GLIBC_2.28]: Likewise. > + * nptl/cnd_broadcast.c: New file. > + * nptl/cnd_destroy.c: Likewise. > + * nptl/cnd_init.c: Likewise. > + * nptl/cnd_signal.c: Likewise. > + * nptl/cnd_timedwait.c: Likewise. > + * nptl/cnd_wait.c: Likewise. > + * sysdeps/nptl/threads.h (cnd_t): New type. > + (cnd_init): New prototype. > + (cnd_signa): Likewise. > + (cnd_broadcast): Likewise. > + (cnd_wait): Likewise. > + (cnd_timedwait): Likewise. > + (cnd_destroy): Likewise. > + OK. > + [BZ #14092] > * conform/data/threads.h-data (ONCE_FLAG_INIT): New macro. > (once_flag): New type. > (call_once): New function. > diff --git a/conform/data/threads.h-data b/conform/data/threads.h-data > index 70b2fe0..d7c562e 100644 > --- a/conform/data/threads.h-data > +++ b/conform/data/threads.h-data > @@ -16,6 +16,7 @@ type thrd_t > type thrd_start_t > type mtx_t > type once_flag > +type cnd_t > > function int thrd_create (thrd_t*, thrd_start_t, void*) > function int thrd_equal (thrd_t, thrd_t) > @@ -35,6 +36,13 @@ function void mtx_destroy (mtx_t*) > > function void call_once (once_flag*, void (*)(void)) > > +function int cnd_init (cnd_t*) OK. > +function int cnd_signal (cnd_t*) OK. > +function int cnd_broadcast (cnd_t*) OK. > +function int cnd_wait (cnd_t*, mtx_t*) OK. > +function int cnd_timedwait (cnd_t*, mtx_t*, const struct timespec*) OK. > +function void cnd_destroy (cnd_t*) OK. > + > #include "time.h-data" > > #endif > diff --git a/nptl/Makefile b/nptl/Makefile > index d55d24b..0864aee 100644 > --- a/nptl/Makefile > +++ b/nptl/Makefile > @@ -143,7 +143,8 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \ > pthread_setattr_default_np pthread_getattr_default_np \ > thrd_create thrd_detach thrd_exit thrd_join \ > mtx_destroy mtx_init mtx_lock mtx_timedlock \ > - mtx_trylock mtx_unlock call_once > + mtx_trylock mtx_unlock call_once cnd_broadcast \ > + cnd_destroy cnd_init cnd_signal cnd_timedwait cnd_wait OK. 6 interfaces. > # pthread_setuid pthread_seteuid pthread_setreuid \ > # pthread_setresuid \ > # pthread_setgid pthread_setegid pthread_setregid \ > diff --git a/nptl/Versions b/nptl/Versions > index 0fdba18..9c38d67 100644 > --- a/nptl/Versions > +++ b/nptl/Versions > @@ -273,7 +273,8 @@ libpthread { > GLIBC_2.28 { > thrd_create; thrd_detach; thrd_exit; thrd_join; > mtx_init; mtx_lock; mtx_timedlock; mtx_trylock; mtx_unlock; mtx_destroy; > - call_once; > + call_once; cnd_broadcast; cnd_destroy; cnd_init; cnd_signal; > + cnd_timedwait; cnd_wait; OK. 6. > } > > GLIBC_PRIVATE { > diff --git a/nptl/cnd_broadcast.c b/nptl/cnd_broadcast.c > new file mode 100644 > index 0000000..889f88e > --- /dev/null > +++ b/nptl/cnd_broadcast.c > @@ -0,0 +1,26 @@ > +/* C11 thread conditional broadcast implementation. > + 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/>. */ > + > +#include "thrd_priv.h" > + > +int > +cnd_broadcast (cnd_t *cond) > +{ > + int err_code = __pthread_cond_broadcast ((pthread_cond_t*) cond); > + return thrd_err_map (err_code); > +} OK. > diff --git a/nptl/cnd_destroy.c b/nptl/cnd_destroy.c > new file mode 100644 > index 0000000..37df9e9 > --- /dev/null > +++ b/nptl/cnd_destroy.c > @@ -0,0 +1,26 @@ > +/* C11 threads conditional destroy implementation. > + 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/>. */ > + > +#include "thrd_priv.h" > +#include "pthreadP.h" > + > +void > +cnd_destroy (cnd_t *cond) > +{ > + __pthread_cond_destroy ((pthread_cond_t *) cond); > +} OK. > diff --git a/nptl/cnd_init.c b/nptl/cnd_init.c > new file mode 100644 > index 0000000..13f0f80 > --- /dev/null > +++ b/nptl/cnd_init.c > @@ -0,0 +1,33 @@ > +/* C11 thread conditional initialization implementation. > + 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/>. */ > + > +#include <stdalign.h> > + > +#include "thrd_priv.h" > + > +int > +cnd_init (cnd_t *cond) > +{ > + _Static_assert (sizeof (cnd_t) == sizeof (pthread_cond_t), > + "(sizeof (cnd_t) != sizeof (pthread_cond_t)"); > + _Static_assert (alignof (cnd_t) == alignof (pthread_cond_t), > + "alignof (cnd_t) != alignof (pthread_cond_t)"); OK. > + > + int err_code = __pthread_cond_init ((pthread_cond_t *)cond, NULL); > + return thrd_err_map (err_code); OK. > +} > diff --git a/nptl/cnd_signal.c b/nptl/cnd_signal.c > new file mode 100644 > index 0000000..8ae650b > --- /dev/null > +++ b/nptl/cnd_signal.c > @@ -0,0 +1,26 @@ > +/* C11 threads conditional signal implementation. > + 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/>. */ > + > +#include "thrd_priv.h" > + > +int > +cnd_signal (cnd_t *cond) > +{ > + int err_code = __pthread_cond_signal ((pthread_cond_t *) cond); > + return thrd_err_map (err_code); > +} OK. > diff --git a/nptl/cnd_timedwait.c b/nptl/cnd_timedwait.c > new file mode 100644 > index 0000000..75358fe > --- /dev/null > +++ b/nptl/cnd_timedwait.c > @@ -0,0 +1,29 @@ > +/* C11 threads conditional timed wait implementation. > + 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/>. */ > + > +#include "thrd_priv.h" > + > +int > +cnd_timedwait (cnd_t *restrict cond, mtx_t *restrict mutex, > + const struct timespec* restrict time_point) > +{ > + int err_code = __pthread_cond_timedwait ((pthread_cond_t *) cond, > + (pthread_mutex_t *) mutex, > + time_point); > + return thrd_err_map (err_code); OK. > +} > diff --git a/nptl/cnd_wait.c b/nptl/cnd_wait.c > new file mode 100644 > index 0000000..727d9bb > --- /dev/null > +++ b/nptl/cnd_wait.c > @@ -0,0 +1,27 @@ > +/* C11 threads conditional wait implementaiton. > + 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/>. */ > + > +#include "thrd_priv.h" > + > +int > +cnd_wait (cnd_t *cond, mtx_t *mutex) > +{ > + int err_code = __pthread_cond_wait ((pthread_cond_t *) cond, > + (pthread_mutex_t *) mutex); > + return thrd_err_map (err_code); OK. > +} > diff --git a/nptl/threads.h b/nptl/threads.h > index 32f7cf8..e46b1b7 100644 > --- a/nptl/threads.h > +++ b/nptl/threads.h > @@ -60,6 +60,12 @@ typedef union > long int __align __LOCK_ALIGNMENT; > } mtx_t; > > +typedef union > +{ > + char __size[__SIZEOF_PTHREAD_COND_T]; > + __extension__ long long int __align __LOCK_ALIGNMENT; > +} cnd_t; OK. > + > /* Threads functions. */ > > /* Create a new thread executing the function __FUNC. Arguments for __FUNC > @@ -140,6 +146,34 @@ extern void mtx_destroy (mtx_t *__mutex); > 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); OK. > + > __END_DECLS > > #endif /* _THREADS_H */ > Cheers, Carlos.
diff --git a/conform/data/threads.h-data b/conform/data/threads.h-data index bc2d857..bb5ca75 100644 --- a/conform/data/threads.h-data +++ b/conform/data/threads.h-data @@ -6,8 +6,13 @@ constant thrd_error constant thrd_nomem constant thrd_timedout +constant mtx_plain +constant mtx_recursive +constant mtx_timed + type thrd_t type thrd_start_t +type mtx_t function int thrd_create (thrd_t*, thrd_start_t, void*) function int thrd_equal (thrd_t, thrd_t) @@ -18,6 +23,13 @@ function int thrd_detach (thrd_t) function int thrd_join (thrd_t, int*) function void thrd_yield (void) +function int mtx_init (mtx_t*, int) +function int mtx_lock (mtx_t*) +function int mtx_timedlock (mtx_t*, const struct timespec*) +function int mtx_trylock (mtx_t*) +function int mtx_unlock (mtx_t*) +function void mtx_destroy (mtx_t*) + #include "time.h-data" #endif diff --git a/nptl/Makefile b/nptl/Makefile index a853c46..1b8a6a8 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -141,7 +141,9 @@ libpthread-routines = nptl-init vars events version pt-interp \ pthread_setname pthread_getname \ pthread_setattr_default_np pthread_getattr_default_np \ thrd_create thrd_current thrd_detach thrd_equal \ - thrd_exit thrd_join thrd_sleep thrd_yield + thrd_exit thrd_join thrd_sleep thrd_yield \ + mtx_destroy mtx_init mtx_lock mtx_timedlock \ + mtx_trylock mtx_unlock # pthread_setuid pthread_seteuid pthread_setreuid \ # pthread_setresuid \ # pthread_setgid pthread_setegid pthread_setregid \ diff --git a/nptl/Versions b/nptl/Versions index 4905c84..a1969e3 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -268,7 +268,8 @@ libpthread { # C11 thread symbols. GLIBC_2.28 { thrd_create; thrd_current; thrd_detach; thrd_equal; thrd_exit; thrd_join; - thrd_sleep; thrd_yield; + thrd_sleep; thrd_yield; mtx_init; mtx_lock; mtx_timedlock; mtx_trylock; + mtx_unlock; mtx_destroy; } GLIBC_PRIVATE { diff --git a/nptl/mtx_destroy.c b/nptl/mtx_destroy.c new file mode 100644 index 0000000..15bc022 --- /dev/null +++ b/nptl/mtx_destroy.c @@ -0,0 +1,26 @@ +/* C11 threads mutex destroy implementation. + 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/>. */ + +#include "thrd_priv.h" +#include "pthreadP.h" + +void +mtx_destroy (mtx_t *mutex) +{ + __pthread_mutex_destroy ((pthread_mutex_t *) mutex); +} diff --git a/nptl/mtx_init.c b/nptl/mtx_init.c new file mode 100644 index 0000000..594dbf3 --- /dev/null +++ b/nptl/mtx_init.c @@ -0,0 +1,52 @@ +/* C11 threads mutex initialization implementation. + 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/>. */ + +#include <stdalign.h> + +#include "thrd_priv.h" + +int +mtx_init (mtx_t *mutex, int type) +{ + _Static_assert (sizeof (mtx_t) == sizeof (pthread_mutex_t), "mtx_t size"); + _Static_assert (alignof (mtx_t) == alignof (pthread_mutex_t), + "mtx_t alignment"); + + pthread_mutexattr_t attr; + + __pthread_mutexattr_init (&attr); + + /* Another possible solution would be to set the flags directly in + mutex object. */ + switch (type) + { + case mtx_plain | mtx_recursive: + case mtx_timed | mtx_recursive: + __pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); + break; + case mtx_plain: + case mtx_timed: /* No difference between both in standard */ + default: + __pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_NORMAL); + break; + } + + int err_code = __pthread_mutex_init ((pthread_mutex_t *) mutex, &attr); + /* pthread_mutexattr_destroy implementation is a noop. */ + return thrd_err_map (err_code); +} diff --git a/nptl/mtx_lock.c b/nptl/mtx_lock.c new file mode 100644 index 0000000..9b3e6cd --- /dev/null +++ b/nptl/mtx_lock.c @@ -0,0 +1,26 @@ +/* C11 threads mutex lock implementation. + 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/>. */ + +#include "thrd_priv.h" + +int +mtx_lock (mtx_t *mutex) +{ + int err_code = __pthread_mutex_lock ((pthread_mutex_t *) mutex); + return thrd_err_map (err_code); +} diff --git a/nptl/mtx_timedlock.c b/nptl/mtx_timedlock.c new file mode 100644 index 0000000..0972622 --- /dev/null +++ b/nptl/mtx_timedlock.c @@ -0,0 +1,28 @@ +/* C11 threads mutex timed lock implementation. + 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/>. */ + +#include "thrd_priv.h" + +int +mtx_timedlock (mtx_t *restrict mutex, + const struct timespec *restrict time_point) +{ + int err_code = __pthread_mutex_timedlock ((pthread_mutex_t *)mutex, + time_point); + return thrd_err_map (err_code); +} diff --git a/nptl/mtx_trylock.c b/nptl/mtx_trylock.c new file mode 100644 index 0000000..f9b6a69 --- /dev/null +++ b/nptl/mtx_trylock.c @@ -0,0 +1,26 @@ +/* C11 threads mutex try lock implementation. + 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/>. */ + +#include "thrd_priv.h" + +int +mtx_trylock (mtx_t *mutex) +{ + int err_code = __pthread_mutex_trylock ((pthread_mutex_t *) mutex); + return thrd_err_map (err_code); +} diff --git a/nptl/mtx_unlock.c b/nptl/mtx_unlock.c new file mode 100644 index 0000000..07f68f6 --- /dev/null +++ b/nptl/mtx_unlock.c @@ -0,0 +1,26 @@ +/* C11 threads mutex unlock implementation. + 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/>. */ + +#include "thrd_priv.h" + +int +mtx_unlock (mtx_t *mutex) +{ + int err_code = __pthread_mutex_unlock ((pthread_mutex_t *) mutex); + return thrd_err_map (err_code); +} diff --git a/sysdeps/nptl/threads.h b/sysdeps/nptl/threads.h index 6adcac4..42d9b5c 100644 --- a/sysdeps/nptl/threads.h +++ b/sysdeps/nptl/threads.h @@ -24,6 +24,7 @@ __BEGIN_DECLS +#include <bits/pthreadtypes-arch.h> #include <bits/types/struct_timespec.h> typedef unsigned long int thrd_t; @@ -39,6 +40,20 @@ enum thrd_timedout = 4 }; +/* Mutex types. */ +enum +{ + mtx_plain = 0, + mtx_recursive = 1, + mtx_timed = 2 +}; + +typedef union +{ + char __size[__SIZEOF_PTHREAD_MUTEX_T]; + long int __align __LOCK_ALIGNMENT; +} mtx_t; + /* Threads functions. */ /* Create a new thread executing the function __FUNC. Arguments for __FUNC @@ -85,6 +100,35 @@ thrd_equal (thrd_t __thread1, thrd_t __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); + __END_DECLS #endif /* _THREADS_H */