This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH 2/2] Move shared pthread definitions to common headers
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Adhemerval Zanella <adhemerval dot zanella at linaro dot org>
- Cc: Torvald Riegel <triegel at redhat dot com>, libc-alpha at sourceware dot org
- Date: Sun, 15 Oct 2017 06:52:06 -0700
- Subject: Re: [PATCH 2/2] Move shared pthread definitions to common headers
- Authentication-results: sourceware.org; auth=none
- References: <1491232114-7588-1-git-send-email-adhemerval.zanella@linaro.org> <1491232114-7588-2-git-send-email-adhemerval.zanella@linaro.org> <1492515142.5374.231.camel@redhat.com> <67d7c6d7-ed22-46a2-5032-4687eaef4b2a@linaro.org> <40185542-25a0-ca7a-655e-2672308a07be@linaro.org>
On Tue, May 09, 2017 at 12:10:28PM -0300, Adhemerval Zanella wrote:
> On 18/04/2017 10:08, Adhemerval Zanella wrote:
> > Thanks for the review.
> >
> > On 18/04/2017 08:32, Torvald Riegel wrote:
> >> On Mon, 2017-04-03 at 12:08 -0300, Adhemerval Zanella wrote:
> >>> This patch removes all the replicated pthread definition accross the
> >>> architectures and consolidates it on shared headers. The new
> >>> organization is as follow:
> >>>
> >>> * Architecture specific definition (such as pthread types sizes) are
> >>> place in the new pthreadtypes-arch.h header in arch specific path.
> >>>
> >>> * All shared structure definition are moved to a common NPTL header
> >>> at sysdeps/nptl/bits/pthreadtypes.h (with now includes the arch
> >>> specific one for internal definitions).
> >>>
> >>> * Also, for C11 future thread support, both mutex and conditional
> >>> definition are placed in a common header at
> >>> sysdeps/nptl/bits/thread-shared-types.h.
> >>>
> >>> It is also a refactor patch without expected functional changes.
> >>> 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, 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 with the changes below.
> >>
>
> This is the patch I intend to push, I just finishing up the build on multiple
> architecture to grab any missing issue. I fixed the wording you pointed out
> in previous review.
>
> >
> > For this consolidation I replicated current architecture code that uses
> > lock elision (they differ only in the internal struct's name and all use
> > the macro for accessing the fields).
> >
> > Another option would to move the elision field definition at each
> > architecture specific header (pthreadtypes-arch.h), so it can guarantee
> > any alignment or other constraint. I do not have a preference here, so
> > if you would prefer this approach I can change the patch.
>
> I decided to use my definition which uses the macros '__spins' and '__elision',
> since they are already being used in architecture that support lock elision.
> My view is with current constraint and architecture duplication of definitions
> it simplifies a bit the mutex definition. I think in the future, if
> architecture internal definition code differentiate more (such as for
> pthread_rwlock_t definition) we can move them to the new arch specific
> headers.
>
> >>> +/* Common definition of pthread_cond_t. */
> >>> +
> >>> +struct __pthread_cond_s
> >>> +{
> >>> + __extension__ union
> >>> + {
> >>> + __extension__ unsigned long long int __wseq;
> >>> + struct
> >>> + {
> >>> + unsigned int __low;
> >>> + unsigned int __high;
> >>> + } __wseq32;
> >>> + };
> >>> + __extension__ union
> >>> + {
> >>> + __extension__ unsigned long long int __g1_start;
> >>> + struct
> >>> + {
> >>> + unsigned int __low;
> >>> + unsigned int __high;
> >>> + } __g1_start32;
> >>> + };
> >>> + unsigned int __g_refs[2] __PTHREAD_LOCK_ALIGNMENT;
> >>
> >> If __PTHREAD_LOCK_ALIGNMENT is not just for locks, but more generally
> >> captures alignment requirements for futex words, I think it should be
> >> named differently, and there should be a comment somewhere explaining
> >> it's use. This is probably also the case for the other macros that this
> >> file uses (though perhaps the __SIZEOF_PTHREAD_* macros are
> >> self-explainatory). A stub pthreadtypes-arch.h may be a way to do it,
> >> though I'm not sure this works as well in this case as it works in the
> >> case of futex-internal.h.
> >
> > I think we can use pthreadtypes-arch.h, the idea is exactly to grab all
> > the arch specific constraint and it should be an installed header.
> > Otherwise we will need to create another installed header to have this
> > definition and I am not sure if this is worth.
> >
> > In any way, I will change the macro name to __LOCK_ALIGNMENT and I will
> > add comments on sysdeps/nptl/bits/thread-shared-types.h explaining the
> > requires defines the arch-specific header should have (__LOCK_ALIGNMENT,
> > __PTHREAD_COMPAT_PADDING_MID, __PTHREAD_COMPAT_PADDING_END, and
> > __PTHREAD_MUTEX_LOCK_ELISION).
>
> I have added two new macros, __LOCK_ALIGNMENT and __ONCE_ALIGNMENT, to
> grasp this idea and replicate their usage in the patch.
>
> ---
>
> This patch removes all the replicated pthread definition accross the
> architectures and consolidates it on shared headers. The new
> organization is as follow:
>
> * Architecture specific definition (such as pthread types sizes) are
> place in the new pthreadtypes-arch.h header in arch specific path.
>
> * All shared structure definition are moved to a common NPTL header
> at sysdeps/nptl/bits/pthreadtypes.h (with now includes the arch
> specific one for internal definitions).
>
> * Also, for C11 future thread support, both mutex and condition
> definition are placed in a common header at
> sysdeps/nptl/bits/thread-shared-types.h.
>
> It is also a refactor patch without expected functional changes.
> 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, 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).
>
> * posix/Makefile (headers): Add pthreadtypes-arch.h and
> thread-shared-types.h.
> * sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h: New file: arch
> specific thread definition.
> * sysdeps/alpha/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/arm/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/hppa/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/ia64/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/m68k/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/mips/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/nios2/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/s390/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/sh/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/sparc/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/tile/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/x86/nptl/bits/pthreadtypes-arch.h: Likewise.
> * sysdeps/nptl/bits/thread-shared-types.h: New file: shared
> thread definition between POSIX and C11.
> * sysdeps/aarch64/nptl/bits/pthreadtypes.h.: Remove file.
> * sysdeps/alpha/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/arm/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/hppa/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/m68k/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/microblaze/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/mips/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/nios2/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/ia64/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/powerpc/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/s390/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/sh/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/sparc/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/tile/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/x86/nptl/bits/pthreadtypes.h: Likewise.
> * sysdeps/nptl/bits/pthreadtypes.h: New file: common thread
> definitions shared across all architectures.
...
> diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h
> new file mode 100644
> index 0000000..ea8747a
> --- /dev/null
> +++ b/sysdeps/nptl/bits/thread-shared-types.h
> @@ -0,0 +1,156 @@
> +/* Common threading primitives definitions for both POSIX and C11.
> + Copyright (C) 2017 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 _THREAD_SHARED_TYPES_H
> +#define _THREAD_SHARED_TYPES_H 1
> +
> +/* Arch-specific definitions. Each architecture must define the following
> + macros to define the expected sizes of pthread data types:
> +
> + __SIZEOF_PTHREAD_ATTR_T - size of pthread_attr_t.
> + __SIZEOF_PTHREAD_MUTEX_T - size of pthread_mutex_t.
> + __SIZEOF_PTHREAD_MUTEXATTR_T - size of pthread_mutexattr_t.
> + __SIZEOF_PTHREAD_COND_T - size of pthread_cond_t.
> + __SIZEOF_PTHREAD_CONDATTR_T - size of pthread_condattr_t.
> + __SIZEOF_PTHREAD_RWLOCK_T - size of pthread_rwlock_t.
> + __SIZEOF_PTHREAD_RWLOCKATTR_T - size of pthread_rwlockattr_t.
> + __SIZEOF_PTHREAD_BARRIER_T - size of pthread_barrier_t.
> + __SIZEOF_PTHREAD_BARRIERATTR_T - size of pthread_barrierattr_t.
> +
> + Also, the following macros must be define for internal pthread_mutex_t
> + struct definitions (struct __pthread_mutex_s):
> +
> + __PTHREAD_COMPAT_PADDING_MID - any additional members after 'kind'
> + and before '__spin' (for 64 bits) or
> + '__nusers' (for 32 bits).
> + __PTHREAD_COMPAT_PADDING_END - any additional members at the end of
> + the internal structure.
> + __PTHREAD_MUTEX_LOCK_ELISION - 1 if the architecture supports lock
> + elision or 0 otherwise.
> +
> + The additional macro defines any constraint for the lock alignment
> + inside the thread structures:
> +
> + __LOCK_ALIGNMENT - for internal lock/futex usage.
> +
> + Same idea but for the once locking primitive:
> +
> + __ONCE_ALIGNMENT - for pthread_once_t/once_flag definition.
> +
> + And finally the internal pthread_rwlock_t (struct __pthread_rwlock_arch_t)
> + must be defined.
> + */
> +#include <bits/pthreadtypes-arch.h>
> +
> +/* Common definition of pthread_mutex_t. */
> +
> +#if __WORDSIZE == 64
> +typedef struct __pthread_internal_list
> +{
> + struct __pthread_internal_list *__prev;
> + struct __pthread_internal_list *__next;
> +} __pthread_list_t;
> +#else
> +typedef struct __pthread_internal_slist
> +{
> + struct __pthread_internal_slist *__next;
> +} __pthread_slist_t;
> +#endif
> +
> +/* Lock elision support. */
> +#if __PTHREAD_MUTEX_LOCK_ELISION
> +# if __WORDSIZE == 64
> +# define __PTHREAD_SPINS_DATA \
> + short __spins; \
> + short __elision;
> +# define __PTHREAD_SPINS 0, 0
> +# else
> +# define __PTHREAD_SPINS_DATA \
> + struct \
> + { \
> + short __espins; \
> + short __eelision; \
> + } __elision_data
> +# define __PTHREAD_SPINS { 0, 0 }
> +# define __spins __elision_data.__espins
> +# define __elision __elision_data.__eelision
> +# endif
> +#else
> +# define __PTHREAD_SPINS_DATA int __spins
> +/* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
> +# define __PTHREAD_SPINS 0
> +#endif
> +
> +struct __pthread_mutex_s
> +{
> + int __lock __LOCK_ALIGNMENT;
> + unsigned int __count;
> + int __owner;
> +#if __WORDSIZE == 64
> + unsigned int __nusers;
> +#endif
> + /* KIND must stay at this position in the structure to maintain
> + binary compatibility with static initializers. */
> + int __kind;
> + __PTHREAD_COMPAT_PADDING_MID;
> +#if __WORDSIZE == 64
> + __PTHREAD_SPINS_DATA;
> + __pthread_list_t __list;
> +# define __PTHREAD_MUTEX_HAVE_PREV 1
> +#else
> + unsigned int __nusers;
> + __extension__ union
> + {
> + __PTHREAD_SPINS_DATA;
> + __pthread_slist_t __list;
> + }
> +#endif
> + __PTHREAD_COMPAT_PADDING_END;
> +};
> +
> +
...
> diff --git a/sysdeps/x86/nptl/bits/pthreadtypes.h b/sysdeps/x86/nptl/bits/pthreadtypes.h
> deleted file mode 100644
> index c3055ca..0000000
> --- a/sysdeps/x86/nptl/bits/pthreadtypes.h
> +++ /dev/null
> @@ -1,271 +0,0 @@
> -/* Copyright (C) 2002-2017 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 _BITS_PTHREADTYPES_H
> -#define _BITS_PTHREADTYPES_H 1
> -
> -#include <bits/wordsize.h>
> -
> -#ifdef __x86_64__
> -# if __WORDSIZE == 64
> -# define __SIZEOF_PTHREAD_ATTR_T 56
> -# define __SIZEOF_PTHREAD_MUTEX_T 40
> -# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
> -# define __SIZEOF_PTHREAD_COND_T 48
> -# define __SIZEOF_PTHREAD_CONDATTR_T 4
> -# define __SIZEOF_PTHREAD_RWLOCK_T 56
> -# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
> -# define __SIZEOF_PTHREAD_BARRIER_T 32
> -# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
> -# else
> -# define __SIZEOF_PTHREAD_ATTR_T 32
> -# define __SIZEOF_PTHREAD_MUTEX_T 32
> -# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
> -# define __SIZEOF_PTHREAD_COND_T 48
> -# define __SIZEOF_PTHREAD_CONDATTR_T 4
> -# define __SIZEOF_PTHREAD_RWLOCK_T 44
> -# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
> -# define __SIZEOF_PTHREAD_BARRIER_T 20
> -# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
> -# endif
> -#else
> -# define __SIZEOF_PTHREAD_ATTR_T 36
> -# define __SIZEOF_PTHREAD_MUTEX_T 24
> -# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
> -# define __SIZEOF_PTHREAD_COND_T 48
> -# define __SIZEOF_PTHREAD_CONDATTR_T 4
> -# define __SIZEOF_PTHREAD_RWLOCK_T 32
> -# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
> -# define __SIZEOF_PTHREAD_BARRIER_T 20
> -# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
> -#endif
> -
> -
> -/* Thread identifiers. The structure of the attribute type is not
> - exposed on purpose. */
> -typedef unsigned long int pthread_t;
> -
> -
> -union pthread_attr_t
> -{
> - char __size[__SIZEOF_PTHREAD_ATTR_T];
> - long int __align;
> -};
> -#ifndef __have_pthread_attr_t
> -typedef union pthread_attr_t pthread_attr_t;
> -# define __have_pthread_attr_t 1
> -#endif
> -
> -
> -#ifdef __x86_64__
> -typedef struct __pthread_internal_list
> -{
> - struct __pthread_internal_list *__prev;
> - struct __pthread_internal_list *__next;
> -} __pthread_list_t;
> -#else
> -typedef struct __pthread_internal_slist
> -{
> - struct __pthread_internal_slist *__next;
> -} __pthread_slist_t;
> -#endif
> -
> -
> -/* Data structures for mutex handling. The structure of the attribute
> - type is not exposed on purpose. */
> -typedef union
> -{
> - struct __pthread_mutex_s
> - {
> - int __lock;
> - unsigned int __count;
> - int __owner;
> -#ifdef __x86_64__
> - unsigned int __nusers;
> -#endif
> - /* KIND must stay at this position in the structure to maintain
> - binary compatibility with static initializers. */
> - int __kind;
> -#ifdef __x86_64__
> - short __spins;
> - short __elision;
> - __pthread_list_t __list;
> -# define __PTHREAD_MUTEX_HAVE_PREV 1
> -/* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
> -# define __PTHREAD_SPINS 0, 0
> -#else
> - unsigned int __nusers;
> - __extension__ union
> - {
> - struct
> - {
> - short __espins;
> - short __elision;
> -# define __spins __elision_data.__espins
> -# define __elision __elision_data.__elision
> -# define __PTHREAD_SPINS { 0, 0 }
> - } __elision_data;
> - __pthread_slist_t __list;
> - };
> -#endif
> - } __data;
> - char __size[__SIZEOF_PTHREAD_MUTEX_T];
> - long int __align;
> -} pthread_mutex_t;
> -
> -typedef union
> -{
> - char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
> - int __align;
> -} pthread_mutexattr_t;
> -
> -
> -/* Data structure for conditional variable handling. The structure of
> - the attribute type is not exposed on purpose. */
> -typedef union
> -{
> - struct
> - {
> - __extension__ union
> - {
> - __extension__ unsigned long long int __wseq;
> - struct {
> - unsigned int __low;
> - unsigned int __high;
> - } __wseq32;
> - };
> - __extension__ union
> - {
> - __extension__ unsigned long long int __g1_start;
> - struct {
> - unsigned int __low;
> - unsigned int __high;
> - } __g1_start32;
> - };
> - unsigned int __g_refs[2];
> - unsigned int __g_size[2];
> - unsigned int __g1_orig_size;
> - unsigned int __wrefs;
> - unsigned int __g_signals[2];
> - } __data;
> - char __size[__SIZEOF_PTHREAD_COND_T];
> - __extension__ long long int __align;
> -} pthread_cond_t;
> -
> -typedef union
> -{
> - char __size[__SIZEOF_PTHREAD_CONDATTR_T];
> - int __align;
> -} pthread_condattr_t;
> -
> -
> -/* Keys for thread-specific data */
> -typedef unsigned int pthread_key_t;
> -
> -
> -/* Once-only execution */
> -typedef int pthread_once_t;
> -
> -
> -#if defined __USE_UNIX98 || defined __USE_XOPEN2K
> -/* Data structure for read-write lock variable handling. The
> - structure of the attribute type is not exposed on purpose. */
> -typedef union
> -{
> -# ifdef __x86_64__
> - struct
> - {
> - unsigned int __readers;
> - unsigned int __writers;
> - unsigned int __wrphase_futex;
> - unsigned int __writers_futex;
> - unsigned int __pad3;
> - unsigned int __pad4;
> - int __cur_writer;
> - int __shared;
> - signed char __rwelision;
> -# ifdef __ILP32__
> - unsigned char __pad1[3];
> -# define __PTHREAD_RWLOCK_ELISION_EXTRA 0, { 0, 0, 0 }
> -# else
> - unsigned char __pad1[7];
> -# define __PTHREAD_RWLOCK_ELISION_EXTRA 0, { 0, 0, 0, 0, 0, 0, 0 }
> -# endif
> - unsigned long int __pad2;
> - /* FLAGS must stay at this position in the structure to maintain
> - binary compatibility. */
> - unsigned int __flags;
> -# define __PTHREAD_RWLOCK_INT_FLAGS_SHARED 1
> - } __data;
> -# else
> - struct
> - {
> - unsigned int __readers;
> - unsigned int __writers;
> - unsigned int __wrphase_futex;
> - unsigned int __writers_futex;
> - unsigned int __pad3;
> - unsigned int __pad4;
> - /* FLAGS must stay at this position in the structure to maintain
> - binary compatibility. */
> - unsigned char __flags;
> - unsigned char __shared;
> - signed char __rwelision;
> -# define __PTHREAD_RWLOCK_ELISION_EXTRA 0
> - unsigned char __pad2;
> - int __cur_writer;
> - } __data;
> -# endif
> - char __size[__SIZEOF_PTHREAD_RWLOCK_T];
> - long int __align;
> -} pthread_rwlock_t;
> -
> -typedef union
> -{
> - char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
> - long int __align;
> -} pthread_rwlockattr_t;
> -#endif
> -
> -
> -#ifdef __USE_XOPEN2K
> -/* POSIX spinlock data type. */
> -typedef volatile int pthread_spinlock_t;
> -
> -
> -/* POSIX barriers data type. The structure of the type is
> - deliberately not exposed. */
> -typedef union
> -{
> - char __size[__SIZEOF_PTHREAD_BARRIER_T];
> - long int __align;
> -} pthread_barrier_t;
> -
> -typedef union
> -{
> - char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
> - int __align;
> -} pthread_barrierattr_t;
> -#endif
> -
> -
> -#ifndef __x86_64__
> -/* Extra attributes for the cleanup functions. */
> -# define __cleanup_fct_attribute __attribute__ ((__regparm__ (1)))
> -#endif
> -
> -#endif /* bits/pthreadtypes.h */
> --
This changed __PTHREAD_MUTEX_HAVE_PREV for x32.
H.J.