[review] nptl: Add mutex-internal.h

Message ID gerrit.1573136666000.I30a22c3e3497805fd6e52994c5925897cffcfe13@gnutoolchain-gerrit.osci.io
State Superseded
Headers

Commit Message

Simon Marchi (Code Review) Nov. 7, 2019, 2:24 p.m. UTC
  Change URL: https://gnutoolchain-gerrit.osci.io/r/c/glibc/+/518
......................................................................

nptl: Add mutex-internal.h

The current way of defining the common mutex definition for POSIX and
C11 on pthreadtypes-arch.h (added by commit 06be6368da16104be5) is
not really the best options for newer ports.  It requires define some
misleading flags that should be always defined as 0
(__PTHREAD_COMPAT_PADDING_MID and __PTHREAD_COMPAT_PADDING_END), it
exposes options used solely for linuxthreads compat mode
(__PTHREAD_MUTEX_USE_UNION and __PTHREAD_MUTEX_NUSERS_AFTER_KIND), and
requires newer ports to explicit define them (adding more boilerplate
code).

This patch adds a new default __pthread_mutex_s definition meant to
be used by newer ports.  Its layout mimic the current usage on both
32 and 64 bits ports and it allows most ports use the generic
definition.  Only ports that use some arch-specific definition (such
as hardware lock-elision or linuxthread compat) requires specific
headers.

For 32 bits, the generic definitions mimics the other 32 bits ports
of using an union to define the fields uses on adaptive and robust
mutexes (thus not allowing both usage at same time) and by using a
single linked-list for robust mutexes.  Both decisions seemed to
follow what recent ports has done and make the resulting
pthread_mutex_t/mtx_t object smaller.

Also the static intialization macro for pthread_mutex_t is set to use
an arch defined on (__PTHREAD_MUTEX_INITIALIZER) which simplifies its
implementation.

Checked with a build on affected abis.

Change-Id: I30a22c3e3497805fd6e52994c5925897cffcfe13
---
M nptl/Makefile
M sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h
M sysdeps/alpha/nptl/bits/pthreadtypes-arch.h
M sysdeps/arm/nptl/bits/pthreadtypes-arch.h
M sysdeps/csky/nptl/bits/pthreadtypes-arch.h
A sysdeps/hppa/nptl/bits/mutex-internal.h
M sysdeps/hppa/nptl/bits/pthreadtypes-arch.h
M sysdeps/ia64/nptl/bits/pthreadtypes-arch.h
M sysdeps/m68k/nptl/bits/pthreadtypes-arch.h
M sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h
A sysdeps/mips/nptl/bits/mutex-internal.h
M sysdeps/mips/nptl/bits/pthreadtypes-arch.h
M sysdeps/nios2/nptl/bits/pthreadtypes-arch.h
A sysdeps/nptl/bits/mutex-internal.h
M sysdeps/nptl/bits/thread-shared-types.h
M sysdeps/nptl/pthread.h
A sysdeps/powerpc/nptl/bits/mutex-internal.h
M sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h
M sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
A sysdeps/s390/nptl/bits/mutex-internal.h
M sysdeps/s390/nptl/bits/pthreadtypes-arch.h
M sysdeps/sh/nptl/bits/pthreadtypes-arch.h
M sysdeps/sparc/nptl/bits/pthreadtypes-arch.h
M sysdeps/unix/sysv/linux/hppa/pthread.h
A sysdeps/x86/nptl/bits/mutex-internal.h
M sysdeps/x86/nptl/bits/pthreadtypes-arch.h
26 files changed, 427 insertions(+), 256 deletions(-)
  

Comments

Simon Marchi (Code Review) Nov. 7, 2019, 8:59 p.m. UTC | #1
Florian Weimer has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/glibc/+/518
......................................................................


Patch Set 1:

(1 comment)

I think this goes in the right direction, but I really dislike the header file name.

https://gnutoolchain-gerrit.osci.io/r/c/glibc/+/518/1/sysdeps/nptl/bits/mutex-internal.h 
File sysdeps/nptl/bits/mutex-internal.h:

https://gnutoolchain-gerrit.osci.io/r/c/glibc/+/518/1/sysdeps/nptl/bits/mutex-internal.h 
PS1: 

I don't think we should use mutex-internal.h as the name of an *installed* header. So far, we used “internal” headers for headers which cross subsystem boundaries, but which are still, well, internal to glibc.

Given that this is now essentially one of these per-type headers, maybe use our naming convention for them?
  
Simon Marchi (Code Review) Nov. 7, 2019, 9:01 p.m. UTC | #2
Florian Weimer has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/glibc/+/518
......................................................................


Patch Set 1: Code-Review-1
  
Simon Marchi (Code Review) Nov. 8, 2019, 3:55 p.m. UTC | #3
Adhemerval Zanella has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/glibc/+/518
......................................................................


Patch Set 1:

(1 comment)

https://gnutoolchain-gerrit.osci.io/r/c/glibc/+/518/1/sysdeps/nptl/bits/mutex-internal.h 
File sysdeps/nptl/bits/mutex-internal.h:

https://gnutoolchain-gerrit.osci.io/r/c/glibc/+/518/1/sysdeps/nptl/bits/mutex-internal.h 
PS1: 

> I don't think we should use mutex-internal.h as the name of an *installed* header. […]

Fair enough, I will change to struct_mutex.h.
  
Simon Marchi (Code Review) Nov. 14, 2019, 2:37 p.m. UTC | #4
Florian Weimer has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/glibc/+/518
......................................................................


Patch Set 2:

(11 comments)

| --- /dev/null
| +++ /COMMIT_MSG
| @@ -1,0 +11,29 @@ C11 on pthreadtypes-arch.h (added by commit 06be6368da16104be5) is
| +not really the best options for newer ports.  It requires define some
| +misleading flags that should be always defined as 0
| +(__PTHREAD_COMPAT_PADDING_MID and __PTHREAD_COMPAT_PADDING_END), it
| +exposes options used solely for linuxthreads compat mode
| +(__PTHREAD_MUTEX_USE_UNION and __PTHREAD_MUTEX_NUSERS_AFTER_KIND), and
| +requires newer ports to explicit define them (adding more boilerplate
| +code).
| +
| +This patch adds a new default __pthread_mutex_s definition meant to
| +be used by newer ports.  Its layout mimic the current usage on both

PS2, Line 20:

“mimics”

| +32 and 64 bits ports and it allows most ports use the generic

PS2, Line 21:

“most ports to use”

| +definition.  Only ports that use some arch-specific definition (such
| +as hardware lock-elision or linuxthread compat) requires specific

PS2, Line 23:

“linuxthreads”

| +headers.
| +
| +For 32 bits, the generic definitions mimics the other 32 bits ports

PS2, Line 26:

“For 32 bit, the generic definitions mimic the other 32-bit ports”
(I think)

| +of using an union to define the fields uses on adaptive and robust
| +mutexes (thus not allowing both usage at same time) and by using a
| +single linked-list for robust mutexes.  Both decisions seemed to
| +follow what recent ports has done and make the resulting

PS2, Line 30:

“have done”

| +pthread_mutex_t/mtx_t object smaller.
| +
| +Also the static intialization macro for pthread_mutex_t is set to use
| +an arch defined on (__PTHREAD_MUTEX_INITIALIZER) which simplifies its

PS2, Line 34:

Not sure what “an arch defined on” means in this context.

| +implementation.
| +
| +Checked with a build on affected abis.
| +
| +Change-Id: I30a22c3e3497805fd6e52994c5925897cffcfe13
| --- /dev/null
| +++ sysdeps/nptl/bits/struct_mutex.h
| @@ -1,0 +1,10 @@ 
| +/* Default internal mutex struct definitions.  Linux version.

PS2, Line 1:

Maybe “/* Default mutex implementation struct definitions”? As a bits/
header, this is not really internal.

This also affects the sysdeps overrides.

| +   Copyright (C) 2019 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,

 ...

| @@ -1,0 +41,20 @@ #endif
| +
| +     After a mutex has been initialized, the __kind of a mutex is usually not
| +     changed.  BUT it can be set to -1 in pthread_mutex_destroy or elision can
| +     be enabled.  This is done concurrently in the pthread_mutex_*lock
| +     functions by using the macro FORCE_ELISION. This macro is only defined
| +     for architectures which supports lock elision.
| +
| +     For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and
| +     PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already
| +     set type of a mutex.  Before a mutex is initialized, only
| +     PTHREAD_MUTEX_NO_ELISION_NP can be set with pthread_mutexattr_settype.

PS2, Line 51:

I don't understand the last comment (the reference to
pthread_mutexattr_settype).

| +
| +     After a mutex has been initialized, the functions pthread_mutex_*lock can
| +     enable elision - if the mutex-type and the machine supports it - by
| +     setting the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently.
| +     Afterwards the lock / unlock functions are using specific elision
| +     code-paths.  */
| +  int __kind;
| +#if __WORDSIZE != 64
| +  unsigned int __nusers;
| --- sysdeps/nptl/bits/thread-shared-types.h
| +++ sysdeps/nptl/bits/thread-shared-types.h
| @@ -160,11 +62,20 @@ #else
| -    __PTHREAD_SPINS_DATA;
| -    __pthread_slist_t __list;
| -  };
| -# define __PTHREAD_MUTEX_HAVE_PREV      0
| -#endif
| -  __PTHREAD_COMPAT_PADDING_END
| -};
| +
| +/* Arch-specific mutex definitions.  A generic implementation is provided
| +   by sysdeps/nptl/bits/struct_mutex.h.  If required, an architecture

PS2, Line 64:

I think it is inappropriate to refer to sysdeps paths in installed
headers because they are not meaningful after installation.

Maybe this information should go into Makefile, where bits/thread-
shared-types.h is added to headers?

| +   can override it by defining:
| +
| +   1. struct __pthread_mutex_s (used on both pthread_mutex_t and mtx_t
| +      definition).  It should contains at least the internal members
| +      defined in the generic version.

PS2, Line 69:

“used in the definition of pthread_mutex_t and mtx_t”?

| +
| +   2. __LOCK_ALIGNMENT for any extra attribute for internal lock used with
| +      atomic operations.

PS2, Line 72:

__LOCK_ALIGNMENT should probably removed (replaced by arch-specific
headers) because it makes the types ABI-incompatible if a non-GNU
compiler used (missing __attribute__ support).  So we really should
not encourage its use. But this is separate change.

| +
| +   3. The macro __PTHREAD_MUTEX_INITIALIZER used for static initialization.
| +      It should initialize the mutex internal flag.  */
| +
| +#include <bits/struct_mutex.h>
|  
|  
|  /* Common definition of pthread_cond_t. */
|
  
Joseph Myers Nov. 14, 2019, 8:43 p.m. UTC | #5
On Thu, 14 Nov 2019, Florian Weimer (Code Review) wrote:

> __LOCK_ALIGNMENT should probably removed (replaced by arch-specific
> headers) because it makes the types ABI-incompatible if a non-GNU
> compiler used (missing __attribute__ support).  So we really should
> not encourage its use. But this is separate change.

The list of compiler extensions required to use glibc headers 
(<https://sourceware.org/glibc/wiki/CCompilerFeatures>) is certainly 
incomplete.  Alignment attributes are used in installed headers on various 
architectures for a range of things beyond just pthreads headers.

It's possible it would be possible to use _Alignas / alignas in some cases 
with suitable language standard versions, subject to any issues with 
bounds on supported alignment with those keywords (see e.g. 
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89357>)

> -- 
> Gerrit-Project: glibc
> Gerrit-Branch: master
> Gerrit-Change-Id: I30a22c3e3497805fd6e52994c5925897cffcfe13
> Gerrit-Change-Number: 518
> Gerrit-PatchSet: 2
> Gerrit-Owner: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> Gerrit-Reviewer: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> Gerrit-Reviewer: Florian Weimer <fweimer@redhat.com>
> Gerrit-Comment-Date: Thu, 14 Nov 2019 14:37:04 +0000
> Gerrit-HasComments: Yes
> Gerrit-Has-Labels: No
> Gerrit-MessageType: comment
  
Simon Marchi (Code Review) Nov. 14, 2019, 8:44 p.m. UTC | #6
Joseph Myers has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/glibc/+/518
......................................................................


Patch Set 2:

On Thu, 14 Nov 2019, Florian Weimer (Code Review) wrote:

The list of compiler extensions required to use glibc headers 
(<https://sourceware.org/glibc/wiki/CCompilerFeatures>) is certainly 
incomplete.  Alignment attributes are used in installed headers on various 
architectures for a range of things beyond just pthreads headers.

It's possible it would be possible to use _Alignas / alignas in some cases 
with suitable language standard versions, subject to any issues with 
bounds on supported alignment with those keywords (see e.g. 
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89357>)
  
Simon Marchi (Code Review) Nov. 20, 2019, 2:49 p.m. UTC | #7
Adhemerval Zanella has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/glibc/+/518
......................................................................


Patch Set 2:

(11 comments)

| --- /dev/null
| +++ /COMMIT_MSG
| @@ -1,0 +11,29 @@ C11 on pthreadtypes-arch.h (added by commit 06be6368da16104be5) is
| +not really the best options for newer ports.  It requires define some
| +misleading flags that should be always defined as 0
| +(__PTHREAD_COMPAT_PADDING_MID and __PTHREAD_COMPAT_PADDING_END), it
| +exposes options used solely for linuxthreads compat mode
| +(__PTHREAD_MUTEX_USE_UNION and __PTHREAD_MUTEX_NUSERS_AFTER_KIND), and
| +requires newer ports to explicit define them (adding more boilerplate
| +code).
| +
| +This patch adds a new default __pthread_mutex_s definition meant to
| +be used by newer ports.  Its layout mimic the current usage on both

PS2, Line 20:

Done

| +32 and 64 bits ports and it allows most ports use the generic

PS2, Line 21:

Done

| +definition.  Only ports that use some arch-specific definition (such
| +as hardware lock-elision or linuxthread compat) requires specific

PS2, Line 23:

Done

| +headers.
| +
| +For 32 bits, the generic definitions mimics the other 32 bits ports

PS2, Line 26:

Done

| +of using an union to define the fields uses on adaptive and robust
| +mutexes (thus not allowing both usage at same time) and by using a
| +single linked-list for robust mutexes.  Both decisions seemed to
| +follow what recent ports has done and make the resulting

PS2, Line 30:

Done

| +pthread_mutex_t/mtx_t object smaller.
| +
| +Also the static intialization macro for pthread_mutex_t is set to use
| +an arch defined on (__PTHREAD_MUTEX_INITIALIZER) which simplifies its

PS2, Line 34:

I changed to:

Also the static intialization macro for pthread_mutex_t is set to use
a macro __PTHREAD_MUTEX_INITIALIZER where the architecture can
redefine
in its struct_mutex.h if it requires additional fields to be
initialized.

| +implementation.
| +
| +Checked with a build on affected abis.
| +
| +Change-Id: I30a22c3e3497805fd6e52994c5925897cffcfe13
| --- /dev/null
| +++ sysdeps/nptl/bits/struct_mutex.h
| @@ -1,0 +1,10 @@ 
| +/* Default internal mutex struct definitions.  Linux version.

PS2, Line 1:

Ack

| +   Copyright (C) 2019 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,

 ...

| @@ -1,0 +41,20 @@ #endif
| +
| +     After a mutex has been initialized, the __kind of a mutex is usually not
| +     changed.  BUT it can be set to -1 in pthread_mutex_destroy or elision can
| +     be enabled.  This is done concurrently in the pthread_mutex_*lock
| +     functions by using the macro FORCE_ELISION. This macro is only defined
| +     for architectures which supports lock elision.
| +
| +     For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and
| +     PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already
| +     set type of a mutex.  Before a mutex is initialized, only
| +     PTHREAD_MUTEX_NO_ELISION_NP can be set with pthread_mutexattr_settype.

PS2, Line 51:

These comments were copied from thread-shared-types.h and added
originally by 403b4feb22d. My understanding is the comment state that
PTHREAD_MUTEX_ELISION_NP can not be set internally by
pthread_mutexattr_settype, since it is done by pthread_mutex_*lock.

| +
| +     After a mutex has been initialized, the functions pthread_mutex_*lock can
| +     enable elision - if the mutex-type and the machine supports it - by
| +     setting the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently.
| +     Afterwards the lock / unlock functions are using specific elision
| +     code-paths.  */
| +  int __kind;
| +#if __WORDSIZE != 64
| +  unsigned int __nusers;
| --- sysdeps/nptl/bits/thread-shared-types.h
| +++ sysdeps/nptl/bits/thread-shared-types.h
| @@ -160,11 +62,20 @@ #else
| -    __PTHREAD_SPINS_DATA;
| -    __pthread_slist_t __list;
| -  };
| -# define __PTHREAD_MUTEX_HAVE_PREV      0
| -#endif
| -  __PTHREAD_COMPAT_PADDING_END
| -};
| +
| +/* Arch-specific mutex definitions.  A generic implementation is provided
| +   by sysdeps/nptl/bits/struct_mutex.h.  If required, an architecture

PS2, Line 64:

I don't think a comment on Makefile would be meaningful, I removed the
path and just refered as 'struct_mutex.h'.

| +   can override it by defining:
| +
| +   1. struct __pthread_mutex_s (used on both pthread_mutex_t and mtx_t
| +      definition).  It should contains at least the internal members
| +      defined in the generic version.

PS2, Line 69:

Ack

| +
| +   2. __LOCK_ALIGNMENT for any extra attribute for internal lock used with
| +      atomic operations.

PS2, Line 72:

I think we should move it to a separate header of its own since it
used on pthread_cond_t definition as well. I will refactor after this
patchset, along with Joseph suggestion to use _Alignas / alignas where
possible.

| +
| +   3. The macro __PTHREAD_MUTEX_INITIALIZER used for static initialization.
| +      It should initialize the mutex internal flag.  */
| +
| +#include <bits/struct_mutex.h>
|  
|  
|  /* Common definition of pthread_cond_t. */
|
  
Simon Marchi (Code Review) Nov. 22, 2019, 2:30 p.m. UTC | #8
Florian Weimer has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/glibc/+/518
......................................................................


Patch Set 3: Code-Review+2

(2 comments)

| --- /dev/null
| +++ sysdeps/nptl/bits/mutex-internal.h
PS1:

Done

| --- /dev/null
| +++ sysdeps/nptl/bits/struct_mutex.h
| @@ -1,0 +41,20 @@ #endif
| +
| +     After a mutex has been initialized, the __kind of a mutex is usually not
| +     changed.  BUT it can be set to -1 in pthread_mutex_destroy or elision can
| +     be enabled.  This is done concurrently in the pthread_mutex_*lock
| +     functions by using the macro FORCE_ELISION. This macro is only defined
| +     for architectures which supports lock elision.
| +
| +     For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and
| +     PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already
| +     set type of a mutex.  Before a mutex is initialized, only
| +     PTHREAD_MUTEX_NO_ELISION_NP can be set with pthread_mutexattr_settype.

PS2, Line 51:

Ack

| +
| +     After a mutex has been initialized, the functions pthread_mutex_*lock can
| +     enable elision - if the mutex-type and the machine supports it - by
| +     setting the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently.
| +     Afterwards the lock / unlock functions are using specific elision
| +     code-paths.  */
| +  int __kind;
| +#if __WORDSIZE != 64
| +  unsigned int __nusers;
  

Patch

diff --git a/nptl/Makefile b/nptl/Makefile
index f9aadfd..f7e3766 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -22,7 +22,8 @@ 
 
 include ../Makeconfig
 
-headers := pthread.h semaphore.h bits/semaphore.h threads.h
+headers := pthread.h semaphore.h bits/semaphore.h threads.h \
+	   bits/mutex-internal.h
 
 extra-libs := libpthread
 extra-libs-others := $(extra-libs)
diff --git a/sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h b/sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h
index 61c02e7..78abd69 100644
--- a/sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h
@@ -41,13 +41,6 @@ 
 #define __SIZEOF_PTHREAD_COND_T         48
 #define __SIZEOF_PTHREAD_RWLOCKATTR_T	8
 
-/* Definitions for internal mutex struct.  */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION	0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  0
-#define __PTHREAD_MUTEX_USE_UNION          0
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/alpha/nptl/bits/pthreadtypes-arch.h b/sysdeps/alpha/nptl/bits/pthreadtypes-arch.h
index f5b7d19..b832590 100644
--- a/sysdeps/alpha/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/alpha/nptl/bits/pthreadtypes-arch.h
@@ -29,13 +29,6 @@ 
 #define __SIZEOF_PTHREAD_BARRIER_T	32
 #define __SIZEOF_PTHREAD_BARRIERATTR_T	4
 
-/* Definitions for internal mutex struct.  */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION    0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  0
-#define __PTHREAD_MUTEX_USE_UNION          0
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/arm/nptl/bits/pthreadtypes-arch.h b/sysdeps/arm/nptl/bits/pthreadtypes-arch.h
index a2c550f..5ae7d0d 100644
--- a/sysdeps/arm/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/arm/nptl/bits/pthreadtypes-arch.h
@@ -30,13 +30,6 @@ 
 #define __SIZEOF_PTHREAD_BARRIER_T 20
 #define __SIZEOF_PTHREAD_BARRIERATTR_T 4
 
-/* Data structure for mutex handling. */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION    0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  1
-#define __PTHREAD_MUTEX_USE_UNION          1
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/csky/nptl/bits/pthreadtypes-arch.h b/sysdeps/csky/nptl/bits/pthreadtypes-arch.h
index c1656ae..6855157 100644
--- a/sysdeps/csky/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/csky/nptl/bits/pthreadtypes-arch.h
@@ -31,13 +31,6 @@ 
 #define __SIZEOF_PTHREAD_BARRIER_T		20
 #define __SIZEOF_PTHREAD_BARRIERATTR_T		4
 
-/* Data structure for mutex handling.  */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION		0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND	1
-#define __PTHREAD_MUTEX_USE_UNION		1
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/hppa/nptl/bits/mutex-internal.h b/sysdeps/hppa/nptl/bits/mutex-internal.h
new file mode 100644
index 0000000..0a30bee
--- /dev/null
+++ b/sysdeps/hppa/nptl/bits/mutex-internal.h
@@ -0,0 +1,54 @@ 
+/* HPPA internal mutex struct definitions.
+   Copyright (C) 2019 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_MUTEX_INTERNAL_H
+#define _THREAD_MUTEX_INTERNAL_H 1
+
+struct __pthread_mutex_s
+{
+  int __lock __LOCK_ALIGNMENT;
+  unsigned int __count;
+  int __owner;
+  /* KIND must stay at this position in the structure to maintain
+     binary compatibility with static initializers.  */
+  int __kind;
+  /* The old 4-word 16-byte aligned lock. This is initalized
+     to all ones by the Linuxthreads PTHREAD_MUTEX_INITIALIZER.
+     Unused in NPTL.  */
+  int __glibc_compat_padding[4];
+  /* In the old structure there are 4 words left due to alignment.
+     In NPTL two words are used.  */
+  unsigned int __nusers;
+  __extension__ union
+  {
+    int __spins;
+    __pthread_slist_t __list;
+  };
+  /* Two more words are left before the NPTL
+     pthread_mutex_t is larger than Linuxthreads.  */
+  int __glibc_reserved1;
+  int __glibc_reserved2;
+};
+
+#define __PTHREAD_MUTEX_LOCK_ELISION    0
+#define __PTHREAD_MUTEX_HAVE_PREV       0
+
+#define __PTHREAD_MUTEX_INITIALIZER(__kind) \
+  0, 0, 0, __kind, { 0, 0, 0, 0 }, 0, { 0 }, 0, 0
+
+#endif
diff --git a/sysdeps/hppa/nptl/bits/pthreadtypes-arch.h b/sysdeps/hppa/nptl/bits/pthreadtypes-arch.h
index 7c97b89..c11add1 100644
--- a/sysdeps/hppa/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/hppa/nptl/bits/pthreadtypes-arch.h
@@ -40,17 +40,6 @@ 
 #define __SIZEOF_PTHREAD_RWLOCK_T 64
 #define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
 
-/* The old 4-word 16-byte aligned lock. This is initalized
-   to all ones by the Linuxthreads PTHREAD_MUTEX_INITIALIZER.
-   Unused in NPTL.  */
-#define __PTHREAD_COMPAT_PADDING_MID  int __compat_padding[4];
-/* Two more words are left before the NPTL
-   pthread_mutex_t is larger than Linuxthreads.  */
-#define __PTHREAD_COMPAT_PADDING_END  int __reserved[2];
-#define __PTHREAD_MUTEX_LOCK_ELISION    0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  1
-#define __PTHREAD_MUTEX_USE_UNION          1
-
 #define __LOCK_ALIGNMENT __attribute__ ((__aligned__(16)))
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/ia64/nptl/bits/pthreadtypes-arch.h b/sysdeps/ia64/nptl/bits/pthreadtypes-arch.h
index 8eb1bd5..7a1fd3e 100644
--- a/sysdeps/ia64/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/ia64/nptl/bits/pthreadtypes-arch.h
@@ -29,13 +29,6 @@ 
 #define __SIZEOF_PTHREAD_BARRIER_T 32
 #define __SIZEOF_PTHREAD_BARRIERATTR_T 4
 
-/* Definitions for internal mutex struct.  */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION    0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  0
-#define __PTHREAD_MUTEX_USE_UNION          0
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/m68k/nptl/bits/pthreadtypes-arch.h b/sysdeps/m68k/nptl/bits/pthreadtypes-arch.h
index cefce56..0647c48 100644
--- a/sysdeps/m68k/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/m68k/nptl/bits/pthreadtypes-arch.h
@@ -31,13 +31,6 @@ 
 #define __SIZEOF_PTHREAD_BARRIER_T 20
 #define __SIZEOF_PTHREAD_BARRIERATTR_T 4
 
-/* Data structure for mutex handling. */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION    0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  1
-#define __PTHREAD_MUTEX_USE_UNION          1
-
 #define __LOCK_ALIGNMENT __attribute__ ((__aligned__ (4)))
 #define __ONCE_ALIGNMENT __attribute__ ((__aligned__ (4)))
 
diff --git a/sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h b/sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h
index 00b50df..21b090a 100644
--- a/sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h
@@ -31,13 +31,6 @@ 
 # define __SIZEOF_PTHREAD_BARRIER_T      20
 # define __SIZEOF_PTHREAD_BARRIERATTR_T   4
 
-/* Definitions for internal mutex struct.  */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION    0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  1
-#define __PTHREAD_MUTEX_USE_UNION          1
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/mips/nptl/bits/mutex-internal.h b/sysdeps/mips/nptl/bits/mutex-internal.h
new file mode 100644
index 0000000..9124b30
--- /dev/null
+++ b/sysdeps/mips/nptl/bits/mutex-internal.h
@@ -0,0 +1,58 @@ 
+/* MIPS internal mutex struct definitions.
+   Copyright (C) 2019 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_MUTEX_INTERNAL_H
+#define _THREAD_MUTEX_INTERNAL_H 1
+
+struct __pthread_mutex_s
+{
+  int __lock;
+  unsigned int __count;
+  int __owner;
+#if _MIPS_SIM == _ABI64
+  unsigned int __nusers;
+#endif
+  /* KIND must stay at this position in the structure to maintain
+     binary compatibility with static initializers.  */
+  int __kind;
+#if _MIPS_SIM == _ABI64
+  int __spins;
+  __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV      1
+#else
+  unsigned int __nusers;
+  __extension__ union
+  {
+    int __spins;
+    __pthread_slist_t __list;
+  };
+# define __PTHREAD_MUTEX_HAVE_PREV      0
+#endif
+};
+
+#define __PTHREAD_MUTEX_LOCK_ELISION    0
+
+#if _MIPS_SIM == _ABI64
+# define __PTHREAD_MUTEX_INITIALIZER(__kind) \
+  0, 0, 0, 0, __kind, 0, { 0, 0 }
+#else
+# define __PTHREAD_MUTEX_INITIALIZER(__kind) \
+  0, 0, 0, __kind, 0, { 0 }
+#endif
+
+#endif
diff --git a/sysdeps/mips/nptl/bits/pthreadtypes-arch.h b/sysdeps/mips/nptl/bits/pthreadtypes-arch.h
index 629cd72..5bcc90a 100644
--- a/sysdeps/mips/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/mips/nptl/bits/pthreadtypes-arch.h
@@ -38,13 +38,6 @@ 
 #define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
 #define __SIZEOF_PTHREAD_BARRIERATTR_T 4
 
-/* Data structure for mutex handling. */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION    0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  (_MIPS_SIM != _ABI64)
-#define __PTHREAD_MUTEX_USE_UNION          (_MIPS_SIM != _ABI64)
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/nios2/nptl/bits/pthreadtypes-arch.h b/sysdeps/nios2/nptl/bits/pthreadtypes-arch.h
index bba904b..7e71f72 100644
--- a/sysdeps/nios2/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/nios2/nptl/bits/pthreadtypes-arch.h
@@ -31,13 +31,6 @@ 
 #define __SIZEOF_PTHREAD_BARRIER_T 20
 #define __SIZEOF_PTHREAD_BARRIERATTR_T 4
 
-/* Data structure for mutex handling. */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION    0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  1
-#define __PTHREAD_MUTEX_USE_UNION          1
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/nptl/bits/mutex-internal.h b/sysdeps/nptl/bits/mutex-internal.h
new file mode 100644
index 0000000..c6100cb
--- /dev/null
+++ b/sysdeps/nptl/bits/mutex-internal.h
@@ -0,0 +1,85 @@ 
+/* Default internal mutex struct definitions.  Linux version.
+   Copyright (C) 2019 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_MUTEX_INTERNAL_H
+#define _THREAD_MUTEX_INTERNAL_H 1
+
+/* Generic struct for both POSIX and C11 mutexes.  New ports are expected
+   to use the default layout, however architecture can redefine it to
+   add arch-specific extension (such as lock-elision).  The struct have
+   a size of 32 bytes on LP32 and 40 bytes on LP64 architectures.  */
+
+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.
+
+     Concurrency notes:
+     The __kind of a mutex is initialized either by the static
+     PTHREAD_MUTEX_INITIALIZER or by a call to pthread_mutex_init.
+
+     After a mutex has been initialized, the __kind of a mutex is usually not
+     changed.  BUT it can be set to -1 in pthread_mutex_destroy or elision can
+     be enabled.  This is done concurrently in the pthread_mutex_*lock
+     functions by using the macro FORCE_ELISION. This macro is only defined
+     for architectures which supports lock elision.
+
+     For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and
+     PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already
+     set type of a mutex.  Before a mutex is initialized, only
+     PTHREAD_MUTEX_NO_ELISION_NP can be set with pthread_mutexattr_settype.
+
+     After a mutex has been initialized, the functions pthread_mutex_*lock can
+     enable elision - if the mutex-type and the machine supports it - by
+     setting the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently.
+     Afterwards the lock / unlock functions are using specific elision
+     code-paths.  */
+  int __kind;
+#if __WORDSIZE != 64
+  unsigned int __nusers;
+#endif
+#if __WORDSIZE == 64
+  int __spins;
+  __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV      1
+#else
+  __extension__ union
+  {
+    int __spins;
+    __pthread_slist_t __list;
+  };
+# define __PTHREAD_MUTEX_HAVE_PREV      0
+#endif
+};
+
+#define __PTHREAD_MUTEX_LOCK_ELISION    0
+#if __PTHREAD_MUTEX_HAVE_PREV == 1
+# define __PTHREAD_MUTEX_INITIALIZER(__kind) \
+  0, 0, 0, 0, __kind, 0, { 0, 0 }
+#else
+# define __PTHREAD_MUTEX_INITIALIZER(__kind) \
+  0, 0, 0, 0, __kind, { 0 }
+#endif
+
+#endif
diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h
index f7eb8d4..6bfaa79 100644
--- a/sysdeps/nptl/bits/thread-shared-types.h
+++ b/sysdeps/nptl/bits/thread-shared-types.h
@@ -32,36 +32,6 @@ 
    __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.
-   __PTHREAD_MUTEX_NUSERS_AFTER_KIND - control where to put __nusers.  The
-				       preferred value for new architectures
-				       is 0.
-   __PTHREAD_MUTEX_USE_UNION      - control whether internal __spins and
-				    __list will be place inside a union for
-				    linuxthreads compatibility.
-				    The preferred value for new architectures
-				    is 0.
-
-   For a new port the preferred values for the required defines are:
-
-   #define __PTHREAD_COMPAT_PADDING_MID
-   #define __PTHREAD_COMPAT_PADDING_END
-   #define __PTHREAD_MUTEX_LOCK_ELISION         0
-   #define __PTHREAD_MUTEX_NUSERS_AFTER_KIND    0
-   #define __PTHREAD_MUTEX_USE_UNION            0
-
-   __PTHREAD_MUTEX_LOCK_ELISION can be set to 1 if the hardware plans to
-   eventually support lock elision using transactional memory.
-
    The additional macro defines any constraint for the lock alignment
    inside the thread structures:
 
@@ -72,98 +42,46 @@ 
    __ONCE_ALIGNMENT - for pthread_once_t/once_flag definition.
 
    And finally the internal pthread_rwlock_t (struct __pthread_rwlock_arch_t)
-   must be defined.
- */
+   must be defined.  */
+
 #include <bits/pthreadtypes-arch.h>
 
+
 /* Common definition of pthread_mutex_t. */
 
-#if !__PTHREAD_MUTEX_USE_UNION
 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 !__PTHREAD_MUTEX_USE_UNION
-#  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
+/* Arch-specific mutex definitions.  A generic implementation is provided
+   by sysdeps/nptl/bits/mutex-internal.h.  If required, an architecture
+   can override it by defining:
 
-struct __pthread_mutex_s
-{
-  int __lock __LOCK_ALIGNMENT;
-  unsigned int __count;
-  int __owner;
-#if !__PTHREAD_MUTEX_NUSERS_AFTER_KIND
-  unsigned int __nusers;
-#endif
-  /* KIND must stay at this position in the structure to maintain
-     binary compatibility with static initializers.
+   1. struct __pthread_mutex_s (used on pthread_mutex_t definition).  It
+      should contain at least the internal members defined in the generic
+      version.
 
-     Concurrency notes:
-     The __kind of a mutex is initialized either by the static
-     PTHREAD_MUTEX_INITIALIZER or by a call to pthread_mutex_init.
+   2. __PTHREAD_MUTEX_HAVE_PREV to either 1 if __pthread_mutex_s defines
+      the double-linked list __pthread_internal_list, or 0 if it uses
+      the single-linked list __pthread_internal_slist.  They are used on
+      robust mutex implementation and the double-linked trades memory
+      usage for a faster insertion and removal.
 
-     After a mutex has been initialized, the __kind of a mutex is usually not
-     changed.  BUT it can be set to -1 in pthread_mutex_destroy or elision can
-     be enabled.  This is done concurrently in the pthread_mutex_*lock functions
-     by using the macro FORCE_ELISION. This macro is only defined for
-     architectures which supports lock elision.
+   3. __PTHREAD_MUTEX_LOCK_ELISION to either 1 if architecture supports
+      hardware lock elision and actually uses the __elision member or
+      0 otherwise.
 
-     For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and
-     PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already set
-     type of a mutex.
-     Before a mutex is initialized, only PTHREAD_MUTEX_NO_ELISION_NP can be set
-     with pthread_mutexattr_settype.
-     After a mutex has been initialized, the functions pthread_mutex_*lock can
-     enable elision - if the mutex-type and the machine supports it - by setting
-     the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently. Afterwards
-     the lock / unlock functions are using specific elision code-paths.  */
-  int __kind;
-  __PTHREAD_COMPAT_PADDING_MID
-#if __PTHREAD_MUTEX_NUSERS_AFTER_KIND
-  unsigned int __nusers;
-#endif
-#if !__PTHREAD_MUTEX_USE_UNION
-  __PTHREAD_SPINS_DATA;
-  __pthread_list_t __list;
-# define __PTHREAD_MUTEX_HAVE_PREV      1
-#else
-  __extension__ union
-  {
-    __PTHREAD_SPINS_DATA;
-    __pthread_slist_t __list;
-  };
-# define __PTHREAD_MUTEX_HAVE_PREV      0
-#endif
-  __PTHREAD_COMPAT_PADDING_END
-};
+   4. __PTHREAD_MUTEX_INITIALIZER macro used for static initialization.
+      It should initialize the mutex internal type.  */
+
+#include <bits/mutex-internal.h>
 
 
 /* Common definition of pthread_cond_t. */
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
index f2b21ac..e673e3f 100644
--- a/sysdeps/nptl/pthread.h
+++ b/sysdeps/nptl/pthread.h
@@ -83,30 +83,15 @@ 
 #endif
 
 
-#if __PTHREAD_MUTEX_HAVE_PREV
-# define PTHREAD_MUTEX_INITIALIZER \
-  { { 0, 0, 0, 0, 0, __PTHREAD_SPINS, { 0, 0 } } }
-# ifdef __USE_GNU
-#  define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, __PTHREAD_SPINS, { 0, 0 } } }
-#  define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, __PTHREAD_SPINS, { 0, 0 } } }
-#  define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, __PTHREAD_SPINS, { 0, 0 } } }
-
-# endif
-#else
-# define PTHREAD_MUTEX_INITIALIZER \
-  { { 0, 0, 0, 0, 0, { __PTHREAD_SPINS } } }
-# ifdef __USE_GNU
-#  define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { __PTHREAD_SPINS } } }
-#  define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { __PTHREAD_SPINS } } }
-#  define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { __PTHREAD_SPINS } } }
-
-# endif
+#define PTHREAD_MUTEX_INITIALIZER \
+ { {  __PTHREAD_MUTEX_INITIALIZER (PTHREAD_MUTEX_DEFAULT) } }
+#ifdef __USE_GNU
+# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
+ { {  __PTHREAD_MUTEX_INITIALIZER (PTHREAD_MUTEX_RECURSIVE_NP) } }
+# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
+ { {  __PTHREAD_MUTEX_INITIALIZER (PTHREAD_MUTEX_ERRORCHECK_NP) } }
+# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
+ { {  __PTHREAD_MUTEX_INITIALIZER (PTHREAD_MUTEX_ADAPTIVE_NP) } }
 #endif
 
 
diff --git a/sysdeps/powerpc/nptl/bits/mutex-internal.h b/sysdeps/powerpc/nptl/bits/mutex-internal.h
new file mode 100644
index 0000000..6695efe
--- /dev/null
+++ b/sysdeps/powerpc/nptl/bits/mutex-internal.h
@@ -0,0 +1,64 @@ 
+/* PowerPC internal mutex struct definitions.
+   Copyright (C) 2019 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_MUTEX_INTERNAL_H
+#define _THREAD_MUTEX_INTERNAL_H 1
+
+struct __pthread_mutex_s
+{
+  int __lock;
+  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;
+#if __WORDSIZE == 64
+  short __spins;
+  short __elision;
+  __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV      1
+#else
+  unsigned int __nusers;
+  __extension__ union
+  {
+    struct
+    {
+      short __espins;
+      short __elision;
+# define __spins __elision_data.__espins
+# define __elision __elision_data.__elision
+    } __elision_data;
+    __pthread_slist_t __list;
+  };
+# define __PTHREAD_MUTEX_HAVE_PREV      0
+#endif
+};
+#define __PTHREAD_MUTEX_LOCK_ELISION    1
+
+#if __WORDSIZE == 64
+# define __PTHREAD_MUTEX_INITIALIZER(__kind) \
+  0, 0, 0, 0, __kind, 0, 0, { 0, 0 }
+#else
+# define __PTHREAD_MUTEX_INITIALIZER(__kind) \
+  0, 0, 0, __kind, 0, { { 0, 0 } }
+#endif
+
+#endif
diff --git a/sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h b/sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h
index 9810aab..429d42d 100644
--- a/sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h
@@ -38,13 +38,6 @@ 
 #define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
 #define __SIZEOF_PTHREAD_BARRIERATTR_T 4
 
-/* Definitions for internal mutex struct.  */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION    1
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  (__WORDSIZE != 64)
-#define __PTHREAD_MUTEX_USE_UNION          (__WORDSIZE != 64)
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h b/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
index 77b60bf..31f46ec 100644
--- a/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
@@ -35,12 +35,6 @@ 
 # error "rv32i-based systems are not supported"
 #endif
 
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION		0
-#define __PTHREAD_MUTEX_USE_UNION	 	0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND	0
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/s390/nptl/bits/mutex-internal.h b/sysdeps/s390/nptl/bits/mutex-internal.h
new file mode 100644
index 0000000..79c732e
--- /dev/null
+++ b/sysdeps/s390/nptl/bits/mutex-internal.h
@@ -0,0 +1,65 @@ 
+/* S390 internal mutex struct definitions.
+   Copyright (C) 2019 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_MUTEX_INTERNAL_H
+#define _THREAD_MUTEX_INTERNAL_H 1
+
+struct __pthread_mutex_s
+{
+  int __lock;
+  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;
+#if __WORDSIZE == 64
+  short __spins;
+  short __elision;
+  __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV      1
+#else
+  unsigned int __nusers;
+  __extension__ union
+  {
+    struct
+    {
+      short __espins;
+      short __elision;
+    } _d;
+#  define __spins _d.__espins
+#  define __elision _d.__elision
+    __pthread_slist_t __list;
+  };
+# define __PTHREAD_MUTEX_HAVE_PREV      0
+#endif
+};
+
+#define __PTHREAD_MUTEX_LOCK_ELISION    1
+
+#if __WORDSIZE == 64
+# define __PTHREAD_MUTEX_INITIALIZER(__kind) \
+  0, 0, 0, 0, __kind, 0, 0, { 0, 0 }
+#else
+# define __PTHREAD_MUTEX_INITIALIZER(__kind) \
+  0, 0, 0, __kind, 0, { { 0, 0 } }
+#endif
+
+#endif
diff --git a/sysdeps/s390/nptl/bits/pthreadtypes-arch.h b/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
index 1cb1d72..5fd32ba 100644
--- a/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
@@ -37,13 +37,6 @@ 
 #define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
 #define __SIZEOF_PTHREAD_BARRIERATTR_T 4
 
-/* Definitions for internal mutex struct.  */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION    1
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  (__WORDSIZE != 64)
-#define __PTHREAD_MUTEX_USE_UNION          (__WORDSIZE != 64)
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/sh/nptl/bits/pthreadtypes-arch.h b/sysdeps/sh/nptl/bits/pthreadtypes-arch.h
index e7bbfe1..ec86113 100644
--- a/sysdeps/sh/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/sh/nptl/bits/pthreadtypes-arch.h
@@ -30,13 +30,6 @@ 
 #define __SIZEOF_PTHREAD_BARRIER_T 20
 #define __SIZEOF_PTHREAD_BARRIERATTR_T 4
 
-/* Definitions for internal mutex struct.  */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION    0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  1
-#define __PTHREAD_MUTEX_USE_UNION          1
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/sparc/nptl/bits/pthreadtypes-arch.h b/sysdeps/sparc/nptl/bits/pthreadtypes-arch.h
index 47093a5..4cda237 100644
--- a/sysdeps/sparc/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/sparc/nptl/bits/pthreadtypes-arch.h
@@ -39,13 +39,6 @@ 
 #define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
 #define __SIZEOF_PTHREAD_BARRIERATTR_T 4
 
-/* Definitions for internal mutex struct.  */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION    0
-#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  (__WORDSIZE != 64)
-#define __PTHREAD_MUTEX_USE_UNION          (__WORDSIZE != 64)
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
diff --git a/sysdeps/unix/sysv/linux/hppa/pthread.h b/sysdeps/unix/sysv/linux/hppa/pthread.h
index 300c187..3d1e7f3 100644
--- a/sysdeps/unix/sysv/linux/hppa/pthread.h
+++ b/sysdeps/unix/sysv/linux/hppa/pthread.h
@@ -83,17 +83,14 @@ 
 
 
 #define PTHREAD_MUTEX_INITIALIZER \
-  { { 0, 0, 0, 0, { 0, 0, 0, 0 }, 0, { __PTHREAD_SPINS }, { 0, 0 } } }
+ { {  __PTHREAD_MUTEX_INITIALIZER (PTHREAD_MUTEX_DEFAULT) } }
 #ifdef __USE_GNU
 # define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, { 0, 0, 0, 0 }, 0, \
-      { __PTHREAD_SPINS }, { 0, 0 } } }
+ { {  __PTHREAD_MUTEX_INITIALIZER (PTHREAD_MUTEX_RECURSIVE_NP) } }
 # define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, { 0, 0, 0, 0 }, 0, \
-      { __PTHREAD_SPINS }, { 0, 0 } } }
+ { {  __PTHREAD_MUTEX_INITIALIZER (PTHREAD_MUTEX_ERRORCHECK_NP) } }
 # define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, { 0, 0, 0, 0 }, 0, \
-      { __PTHREAD_SPINS }, { 0, 0 } } }
+ { {  __PTHREAD_MUTEX_INITIALIZER (PTHREAD_MUTEX_ADAPTIVE_NP) } }
 #endif
 
 
diff --git a/sysdeps/x86/nptl/bits/mutex-internal.h b/sysdeps/x86/nptl/bits/mutex-internal.h
new file mode 100644
index 0000000..376bc67
--- /dev/null
+++ b/sysdeps/x86/nptl/bits/mutex-internal.h
@@ -0,0 +1,64 @@ 
+/* x86 internal mutex struct definitions.
+   Copyright (C) 2019 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_MUTEX_INTERNAL_H
+#define _THREAD_MUTEX_INTERNAL_H 1
+
+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
+#else
+  unsigned int __nusers;
+  __extension__ union
+  {
+    struct
+    {
+      short __espins;
+      short __eelision;
+# define __spins __elision_data.__espins
+# define __elision __elision_data.__eelision
+    } __elision_data;
+    __pthread_slist_t __list;
+  };
+# define __PTHREAD_MUTEX_HAVE_PREV      0
+#endif
+};
+#define __PTHREAD_MUTEX_LOCK_ELISION    1
+
+#ifdef __x86_64__
+# define __PTHREAD_MUTEX_INITIALIZER(__kind) \
+  0, 0, 0, 0, __kind, 0, 0, { 0, 0 }
+#else
+# define __PTHREAD_MUTEX_INITIALIZER(__kind) \
+  0, 0, 0, __kind, 0, { { 0, 0 } }
+#endif
+
+#endif
diff --git a/sysdeps/x86/nptl/bits/pthreadtypes-arch.h b/sysdeps/x86/nptl/bits/pthreadtypes-arch.h
index 1f05ca0..668ec4a 100644
--- a/sysdeps/x86/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/x86/nptl/bits/pthreadtypes-arch.h
@@ -47,18 +47,6 @@ 
 #define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
 #define __SIZEOF_PTHREAD_BARRIERATTR_T 4
 
-/* Definitions for internal mutex struct.  */
-#define __PTHREAD_COMPAT_PADDING_MID
-#define __PTHREAD_COMPAT_PADDING_END
-#define __PTHREAD_MUTEX_LOCK_ELISION    1
-#ifdef __x86_64__
-# define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  0
-# define __PTHREAD_MUTEX_USE_UNION          0
-#else
-# define __PTHREAD_MUTEX_NUSERS_AFTER_KIND  1
-# define __PTHREAD_MUTEX_USE_UNION          1
-#endif
-
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT