[4/7] nptl: Add rwlock-internal.h
diff mbox series

Message ID 20191106175001.12182-4-adhemerval.zanella@linaro.org
State New
Headers show
Series
  • [1/7] nptl: Add tests for internal pthread_rwlock_t offsets
Related show

Commit Message

Adhemerval Zanella Nov. 6, 2019, 5:49 p.m. UTC
This patch adds a new generic __pthread_rwlock_arch_t definition meant
to be used by new ports.  Its layout mimic the current usage on some
64 bits ports and it allows some ports use the generic definition.
The arch __pthread_rwlock_arch_t definition is moved from
pthreadtypes-arch.h to another arch-specific header (rwlock-internal.h).

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

The default pthread_rwlock_t layout differs from current ports with:

  1. Internal layout is the same for 32 bits and 64 bits.

  2. Internal flag is an unsigned short so it should not required
     additional padding to align for word boundary (if it is the case
     for the ABI).

Checked with a build on affected abis.
---
 nptl/Makefile                                 |  2 +-
 sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h | 15 ----
 sysdeps/aarch64/nptl/bits/rwlock-internal.h   | 41 +++++++++++
 sysdeps/alpha/nptl/bits/pthreadtypes-arch.h   | 17 -----
 sysdeps/alpha/nptl/bits/rwlock-internal.h     | 43 +++++++++++
 sysdeps/arm/nptl/bits/pthreadtypes-arch.h     | 26 -------
 sysdeps/csky/nptl/bits/pthreadtypes-arch.h    | 26 +------
 sysdeps/hppa/nptl/bits/pthreadtypes-arch.h    | 32 ---------
 sysdeps/hppa/nptl/bits/rwlock-internal.h      | 58 +++++++++++++++
 sysdeps/ia64/nptl/bits/pthreadtypes-arch.h    | 19 -----
 sysdeps/ia64/nptl/bits/rwlock-internal.h      | 43 +++++++++++
 sysdeps/m68k/nptl/bits/pthreadtypes-arch.h    | 17 -----
 .../microblaze/nptl/bits/pthreadtypes-arch.h  | 26 -------
 sysdeps/mips/nptl/bits/pthreadtypes-arch.h    | 36 ----------
 sysdeps/mips/nptl/bits/rwlock-internal.h      | 71 +++++++++++++++++++
 sysdeps/nios2/nptl/bits/pthreadtypes-arch.h   | 26 -------
 sysdeps/nptl/bits/rwlock-internal.h           | 62 ++++++++++++++++
 sysdeps/nptl/bits/thread-shared-types.h       | 18 +++--
 sysdeps/nptl/pthread.h                        | 27 +------
 sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h | 27 -------
 sysdeps/powerpc/nptl/bits/rwlock-internal.h   | 61 ++++++++++++++++
 sysdeps/riscv/nptl/bits/pthreadtypes-arch.h   | 19 -----
 sysdeps/riscv/nptl/bits/rwlock-internal.h     | 45 ++++++++++++
 sysdeps/s390/nptl/bits/pthreadtypes-arch.h    | 27 -------
 sysdeps/s390/nptl/bits/rwlock-internal.h      | 58 +++++++++++++++
 sysdeps/sh/nptl/bits/pthreadtypes-arch.h      | 26 -------
 sysdeps/sparc/nptl/bits/pthreadtypes-arch.h   | 27 -------
 sysdeps/sparc/nptl/bits/rwlock-internal.h     | 58 +++++++++++++++
 sysdeps/unix/sysv/linux/hppa/pthread.h        | 14 +---
 sysdeps/x86/nptl/bits/pthreadtypes-arch.h     | 28 --------
 sysdeps/x86/nptl/bits/rwlock-internal.h       | 65 +++++++++++++++++
 31 files changed, 626 insertions(+), 434 deletions(-)
 create mode 100644 sysdeps/aarch64/nptl/bits/rwlock-internal.h
 create mode 100644 sysdeps/alpha/nptl/bits/rwlock-internal.h
 create mode 100644 sysdeps/hppa/nptl/bits/rwlock-internal.h
 create mode 100644 sysdeps/ia64/nptl/bits/rwlock-internal.h
 create mode 100644 sysdeps/mips/nptl/bits/rwlock-internal.h
 create mode 100644 sysdeps/nptl/bits/rwlock-internal.h
 create mode 100644 sysdeps/powerpc/nptl/bits/rwlock-internal.h
 create mode 100644 sysdeps/riscv/nptl/bits/rwlock-internal.h
 create mode 100644 sysdeps/s390/nptl/bits/rwlock-internal.h
 create mode 100644 sysdeps/sparc/nptl/bits/rwlock-internal.h
 create mode 100644 sysdeps/x86/nptl/bits/rwlock-internal.h

Patch
diff mbox series

diff --git a/nptl/Makefile b/nptl/Makefile
index f7e3766e3c..240f35802f 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -23,7 +23,7 @@  subdir	:= nptl
 include ../Makeconfig
 
 headers := pthread.h semaphore.h bits/semaphore.h threads.h \
-	   bits/mutex-internal.h
+	   bits/mutex-internal.h bits/rwlock-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 78abd6960b..33c7928bf2 100644
--- a/sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h
@@ -44,19 +44,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-struct __pthread_rwlock_arch_t
-{
-  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;
-  unsigned long int __pad1;
-  unsigned long int __pad2;
-  unsigned int __flags;
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/aarch64/nptl/bits/rwlock-internal.h b/sysdeps/aarch64/nptl/bits/rwlock-internal.h
new file mode 100644
index 0000000000..c5ea2b2469
--- /dev/null
+++ b/sysdeps/aarch64/nptl/bits/rwlock-internal.h
@@ -0,0 +1,41 @@ 
+/* AArch64 internal rwlock 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 _RWLOCK_INTERNAL_H
+#define _RWLOCK_INTERNAL_H
+
+struct __pthread_rwlock_arch_t
+{
+  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;
+  unsigned long int __pad1;
+  unsigned long int __pad2;
+  unsigned int __flags;
+};
+
+#define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags
+
+#endif
diff --git a/sysdeps/alpha/nptl/bits/pthreadtypes-arch.h b/sysdeps/alpha/nptl/bits/pthreadtypes-arch.h
index b832590d82..09692ab4aa 100644
--- a/sysdeps/alpha/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/alpha/nptl/bits/pthreadtypes-arch.h
@@ -32,21 +32,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-struct __pthread_rwlock_arch_t
-{
-  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;
-  unsigned long int __pad1;
-  unsigned long int __pad2;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned int __flags;
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/alpha/nptl/bits/rwlock-internal.h b/sysdeps/alpha/nptl/bits/rwlock-internal.h
new file mode 100644
index 0000000000..32e18a4a4e
--- /dev/null
+++ b/sysdeps/alpha/nptl/bits/rwlock-internal.h
@@ -0,0 +1,43 @@ 
+/* Alpha internal rwlock 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 _RWLOCK_INTERNAL_H
+#define _RWLOCK_INTERNAL_H
+
+struct __pthread_rwlock_arch_t
+{
+  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;
+  unsigned long int __pad1;
+  unsigned long int __pad2;
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned int __flags;
+};
+
+#define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags
+
+#endif
diff --git a/sysdeps/arm/nptl/bits/pthreadtypes-arch.h b/sysdeps/arm/nptl/bits/pthreadtypes-arch.h
index 5ae7d0d721..339956cfa2 100644
--- a/sysdeps/arm/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/arm/nptl/bits/pthreadtypes-arch.h
@@ -33,30 +33,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-struct __pthread_rwlock_arch_t
-{
-  unsigned int __readers;
-  unsigned int __writers;
-  unsigned int __wrphase_futex;
-  unsigned int __writers_futex;
-  unsigned int __pad3;
-  unsigned int __pad4;
-#if __BYTE_ORDER == __BIG_ENDIAN
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __shared;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-#else
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-  unsigned char __shared;
-  unsigned char __pad1;
-  unsigned char __pad2;
-#endif
-  int __cur_writer;
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/csky/nptl/bits/pthreadtypes-arch.h b/sysdeps/csky/nptl/bits/pthreadtypes-arch.h
index 685515724f..4bcc8d7d5b 100644
--- a/sysdeps/csky/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/csky/nptl/bits/pthreadtypes-arch.h
@@ -34,28 +34,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-/* Paddings in this structure are not strictly necessary on C-SKY.
-   They are left for extensibility as most other architecture do so.  */
-struct __pthread_rwlock_arch_t
-{
-  unsigned int __readers;
-  unsigned int __writers;
-  unsigned int __wrphase_futex;
-  unsigned int __writers_futex;
-  unsigned int __pad3;
-  unsigned int __pad4;
-#if __BYTE_ORDER == __BIG_ENDIAN
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __shared;
-  unsigned char __flags;
-#else
-  unsigned char __flags;
-  unsigned char __shared;
-  unsigned char __pad1;
-  unsigned char __pad2;
-#endif
-  int __cur_writer;
-};
-
-#endif
+#endif /* bits/pthreadtypes.h */
diff --git a/sysdeps/hppa/nptl/bits/pthreadtypes-arch.h b/sysdeps/hppa/nptl/bits/pthreadtypes-arch.h
index c11add1af8..58e077cb4e 100644
--- a/sysdeps/hppa/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/hppa/nptl/bits/pthreadtypes-arch.h
@@ -43,36 +43,4 @@ 
 #define __LOCK_ALIGNMENT __attribute__ ((__aligned__(16)))
 #define __ONCE_ALIGNMENT
 
-struct __pthread_rwlock_arch_t
-{
-  /* In the old Linuxthreads pthread_rwlock_t, this is the
-     start of the 4-word 16-byte aligned lock structure. The
-     next four words are all set to 1 by the Linuxthreads
-     PTHREAD_RWLOCK_INITIALIZER. We ignore them in NPTL.  */
-  int __compat_padding[4] __attribute__ ((__aligned__(16)));
-  unsigned int __readers;
-  unsigned int __writers;
-  unsigned int __wrphase_futex;
-  unsigned int __writers_futex;
-  unsigned int __pad3;
-  unsigned int __pad4;
-  int __cur_writer;
-  /* An unused word, reserved for future use. It was added
-     to maintain the location of the flags from the Linuxthreads
-     layout of this structure.  */
-  int __reserved1;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __pad2;
-  unsigned char __pad1;
-  unsigned char __shared;
-  unsigned char __flags;
-  /* The NPTL pthread_rwlock_t is 4 words smaller than the
-     Linuxthreads version. One word is in the middle of the
-     structure, the other three are at the end.  */
-  int __reserved2;
-  int __reserved3;
-  int __reserved4;
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/hppa/nptl/bits/rwlock-internal.h b/sysdeps/hppa/nptl/bits/rwlock-internal.h
new file mode 100644
index 0000000000..5370c7c3bb
--- /dev/null
+++ b/sysdeps/hppa/nptl/bits/rwlock-internal.h
@@ -0,0 +1,58 @@ 
+/* HPPA  internal rwlock 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 _RWLOCK_INTERNAL_H
+#define _RWLOCK_INTERNAL_H
+
+struct __pthread_rwlock_arch_t
+{
+  /* In the old Linuxthreads pthread_rwlock_t, this is the
+     start of the 4-word 16-byte aligned lock structure. The
+     next four words are all set to 1 by the Linuxthreads
+     PTHREAD_RWLOCK_INITIALIZER. We ignore them in NPTL.  */
+  int __compat_padding[4] __attribute__ ((__aligned__(16)));
+  unsigned int __readers;
+  unsigned int __writers;
+  unsigned int __wrphase_futex;
+  unsigned int __writers_futex;
+  unsigned int __pad3;
+  unsigned int __pad4;
+  int __cur_writer;
+  /* An unused word, reserved for future use. It was added
+     to maintain the location of the flags from the Linuxthreads
+     layout of this structure.  */
+  int __reserved1;
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned char __pad2;
+  unsigned char __pad1;
+  unsigned char __shared;
+  unsigned char __flags;
+  /* The NPTL pthread_rwlock_t is 4 words smaller than the
+     Linuxthreads version. One word is in the middle of the
+     structure, the other three are at the end.  */
+  int __reserved2;
+  int __reserved3;
+  int __reserved4;
+};
+
+#define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags, 0, 0, 0
+
+#endif
diff --git a/sysdeps/ia64/nptl/bits/pthreadtypes-arch.h b/sysdeps/ia64/nptl/bits/pthreadtypes-arch.h
index 7a1fd3ed28..e3b8175ea0 100644
--- a/sysdeps/ia64/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/ia64/nptl/bits/pthreadtypes-arch.h
@@ -32,23 +32,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-/* Data structure for reader-write lock variable handling.  The
-   structure of the attribute type is not exposed on purpose.  */
-struct __pthread_rwlock_arch_t
-{
-  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;
-  unsigned long int __pad1;
-  unsigned long int __pad2;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned int __flags;
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/ia64/nptl/bits/rwlock-internal.h b/sysdeps/ia64/nptl/bits/rwlock-internal.h
new file mode 100644
index 0000000000..de991c8dd4
--- /dev/null
+++ b/sysdeps/ia64/nptl/bits/rwlock-internal.h
@@ -0,0 +1,43 @@ 
+/* IA64 internal rwlock 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 _RWLOCK_INTERNAL_H
+#define _RWLOCK_INTERNAL_H
+
+struct __pthread_rwlock_arch_t
+{
+  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;
+  unsigned long int __pad1;
+  unsigned long int __pad2;
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned int __flags;
+};
+
+#define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags
+
+#endif
diff --git a/sysdeps/m68k/nptl/bits/pthreadtypes-arch.h b/sysdeps/m68k/nptl/bits/pthreadtypes-arch.h
index 0647c48b5a..fe3ac611f8 100644
--- a/sysdeps/m68k/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/m68k/nptl/bits/pthreadtypes-arch.h
@@ -34,21 +34,4 @@ 
 #define __LOCK_ALIGNMENT __attribute__ ((__aligned__ (4)))
 #define __ONCE_ALIGNMENT __attribute__ ((__aligned__ (4)))
 
-struct __pthread_rwlock_arch_t
-{
-  unsigned int __readers  __attribute__ ((__aligned__ (4)));
-  unsigned int __writers;
-  unsigned int __wrphase_futex;
-  unsigned int __writers_futex;
-  unsigned int __pad3;
-  unsigned int __pad4;
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __shared;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-  int __cur_writer;
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h b/sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h
index 21b090aaf6..ed2852a018 100644
--- a/sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h
@@ -34,30 +34,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-struct __pthread_rwlock_arch_t
-{
-  unsigned int __readers;
-  unsigned int __writers;
-  unsigned int __wrphase_futex;
-  unsigned int __writers_futex;
-  unsigned int __pad3;
-  unsigned int __pad4;
-#  if __BYTE_ORDER == __BIG_ENDIAN
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __shared;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-#  else
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-  unsigned char __shared;
-  unsigned char __pad1;
-  unsigned char __pad2;
-#  endif
-  int __cur_writer;
-};
-
 #endif	/* bits/pthreadtypes.h.  */
diff --git a/sysdeps/mips/nptl/bits/pthreadtypes-arch.h b/sysdeps/mips/nptl/bits/pthreadtypes-arch.h
index 5bcc90a7fe..f0f9133df4 100644
--- a/sysdeps/mips/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/mips/nptl/bits/pthreadtypes-arch.h
@@ -41,40 +41,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-struct __pthread_rwlock_arch_t
-{
-  unsigned int __readers;
-  unsigned int __writers;
-  unsigned int __wrphase_futex;
-  unsigned int __writers_futex;
-  unsigned int __pad3;
-  unsigned int __pad4;
-#if _MIPS_SIM == _ABI64
-  int __cur_writer;
-  int __shared;
-  unsigned long int __pad1;
-  unsigned long int __pad2;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned int __flags;
-# else
-# if __BYTE_ORDER == __BIG_ENDIAN
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __shared;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-# else
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-  unsigned char __shared;
-  unsigned char __pad1;
-  unsigned char __pad2;
-# endif
-  int __cur_writer;
-#endif
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/mips/nptl/bits/rwlock-internal.h b/sysdeps/mips/nptl/bits/rwlock-internal.h
new file mode 100644
index 0000000000..93bf7cd442
--- /dev/null
+++ b/sysdeps/mips/nptl/bits/rwlock-internal.h
@@ -0,0 +1,71 @@ 
+/* MIPS internal rwlock 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 _RWLOCK_INTERNAL_H
+#define _RWLOCK_INTERNAL_H
+
+struct __pthread_rwlock_arch_t
+{
+  unsigned int __readers;
+  unsigned int __writers;
+  unsigned int __wrphase_futex;
+  unsigned int __writers_futex;
+  unsigned int __pad3;
+  unsigned int __pad4;
+#if _MIPS_SIM == _ABI64
+  int __cur_writer;
+  int __shared;
+  unsigned long int __pad1;
+  unsigned long int __pad2;
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned int __flags;
+# else
+# if __BYTE_ORDER == __BIG_ENDIAN
+  unsigned char __pad1;
+  unsigned char __pad2;
+  unsigned char __shared;
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned char __flags;
+# else
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned char __flags;
+  unsigned char __shared;
+  unsigned char __pad1;
+  unsigned char __pad2;
+# endif
+  int __cur_writer;
+#endif
+};
+
+#if _MIPS_SIM == _ABI64
+# define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags
+#else
+# if __BYTE_ORDER == __BIG_ENDIAN
+#  define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, __flags, 0
+# else
+#  define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, __flags, 0, 0, 0, 0
+# endif
+#endif
+
+#endif
diff --git a/sysdeps/nios2/nptl/bits/pthreadtypes-arch.h b/sysdeps/nios2/nptl/bits/pthreadtypes-arch.h
index 7e71f723d0..28d1d84ad8 100644
--- a/sysdeps/nios2/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/nios2/nptl/bits/pthreadtypes-arch.h
@@ -34,30 +34,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-struct __pthread_rwlock_arch_t
-{
-  unsigned int __readers;
-  unsigned int __writers;
-  unsigned int __wrphase_futex;
-  unsigned int __writers_futex;
-  unsigned int __pad3;
-  unsigned int __pad4;
-#if __BYTE_ORDER == __BIG_ENDIAN
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __shared;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-#else
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-  unsigned char __shared;
-  unsigned char __pad1;
-  unsigned char __pad2;
-#endif
-  int __cur_writer;
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/nptl/bits/rwlock-internal.h b/sysdeps/nptl/bits/rwlock-internal.h
new file mode 100644
index 0000000000..98ec18db47
--- /dev/null
+++ b/sysdeps/nptl/bits/rwlock-internal.h
@@ -0,0 +1,62 @@ 
+/* Default internal rwlock 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 __RWLOCK_INTERNAL_H
+#define __RWLOCK_INTERNAL_H
+
+#include <bits/endian.h>
+
+/* Generic struct for both POSIX read-write lock.  New ports are expected
+   to use the default layout, however archictetures can redefine it to add
+   arch-specific extensions (such as lock-elision).  The struct have a size
+   of 32 bytes on both LP32 and LP64 architectures.  */
+
+struct __pthread_rwlock_arch_t
+{
+  unsigned int __readers;
+  unsigned int __writers;
+  unsigned int __wrphase_futex;
+  unsigned int __writers_futex;
+  unsigned int __pad3;
+  unsigned int __pad4;
+  /* FLAGS must stay at its position in the structure to maintain
+     binary compatibility.  */
+#if __BYTE_ORDER == __BIG_ENDIAN
+  unsigned char __pad1;
+  unsigned char __pad2;
+  unsigned char __shared;
+  unsigned char __flags;
+#else
+  unsigned char __flags;
+  unsigned char __shared;
+  unsigned char __pad1;
+  unsigned char __pad2;
+#endif
+  int __cur_writer;
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+# define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, __flags, 0
+#else
+# define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, __flags, 0, 0, 0, 0
+#endif
+
+#endif
diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h
index 6bfaa79ca1..6e596d4528 100644
--- a/sysdeps/nptl/bits/thread-shared-types.h
+++ b/sysdeps/nptl/bits/thread-shared-types.h
@@ -39,10 +39,7 @@ 
 
    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.  */
+   __ONCE_ALIGNMENT - for pthread_once_t/once_flag definition.  */
 
 #include <bits/pthreadtypes-arch.h>
 
@@ -83,6 +80,19 @@  typedef struct __pthread_internal_slist
 
 #include <bits/mutex-internal.h>
 
+/* Arch-sepecific read-write lock definitions.  A generic implementation is
+   provided by sysdeps/nptl/bits/rwlock-internal.h.  If required, an
+   architecture can override it by defining:
+
+   1. struct __pthread_rwlock_arch_t (used on pthread_rwlock_t definition).
+      It should contain at least the internal members defined in the
+      generic version.
+
+   2. The macro __PTHREAD_RWLOCK_INITIALIZER used for static initialization.
+      It should initialize the rwlock internal type.  */
+
+#include <bits/rwlock-internal.h>
+
 
 /* Common definition of pthread_cond_t. */
 
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
index e673e3f4fc..a503b09993 100644
--- a/sysdeps/nptl/pthread.h
+++ b/sysdeps/nptl/pthread.h
@@ -105,34 +105,13 @@  enum
   PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_READER_NP
 };
 
-/* Define __PTHREAD_RWLOCK_INT_FLAGS_SHARED to 1 if pthread_rwlock_t
-   has the shared field.  All 64-bit architectures have the shared field
-   in pthread_rwlock_t.  */
-#ifndef __PTHREAD_RWLOCK_INT_FLAGS_SHARED
-# if __WORDSIZE == 64
-#  define __PTHREAD_RWLOCK_INT_FLAGS_SHARED 1
-# endif
-#endif
 
 /* Read-write lock initializers.  */
 # define PTHREAD_RWLOCK_INITIALIZER \
-  { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
+  { { __PTHREAD_RWLOCK_INITIALIZER (PTHREAD_RWLOCK_DEFAULT_NP) } }
 # ifdef __USE_GNU
-#  ifdef __PTHREAD_RWLOCK_INT_FLAGS_SHARED
-#   define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
-  { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,					      \
-	PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
-#  else
-#   if __BYTE_ORDER == __LITTLE_ENDIAN
-#    define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
-  { { 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, \
-      0, 0, 0, 0 } }
-#   else
-#    define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
-  { { 0, 0, 0, 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,\
-      0 } }
-#   endif
-#  endif
+#  define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+  { { __PTHREAD_RWLOCK_INITIALIZER (PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) } }
 # endif
 #endif  /* Unix98 or XOpen2K */
 
diff --git a/sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h b/sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h
index 429d42d77d..eff60d6306 100644
--- a/sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h
@@ -41,31 +41,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-struct __pthread_rwlock_arch_t
-{
-  unsigned int __readers;
-  unsigned int __writers;
-  unsigned int __wrphase_futex;
-  unsigned int __writers_futex;
-  unsigned int __pad3;
-  unsigned int __pad4;
-#if __WORDSIZE == 64
-  int __cur_writer;
-  int __shared;
-  unsigned long int __pad1;
-  unsigned long int __pad2;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned int __flags;
-#else
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __shared;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-  int __cur_writer;
-#endif
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/powerpc/nptl/bits/rwlock-internal.h b/sysdeps/powerpc/nptl/bits/rwlock-internal.h
new file mode 100644
index 0000000000..ee457b0bfa
--- /dev/null
+++ b/sysdeps/powerpc/nptl/bits/rwlock-internal.h
@@ -0,0 +1,61 @@ 
+/* PowerPC internal rwlock 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 _RWLOCK_INTERNAL_H
+#define _RWLOCK_INTERNAL_H
+
+struct __pthread_rwlock_arch_t
+{
+  unsigned int __readers;
+  unsigned int __writers;
+  unsigned int __wrphase_futex;
+  unsigned int __writers_futex;
+  unsigned int __pad3;
+  unsigned int __pad4;
+#if __WORDSIZE == 64
+  int __cur_writer;
+  int __shared;
+  unsigned char __rwelision;
+  unsigned char __pad1[7];
+  unsigned long int __pad2;
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned int __flags;
+# define __PTHREAD_RWLOCK_ELISION_EXTRA 0, {0, 0, 0, 0, 0, 0, 0 }
+#else
+  unsigned char __rwelision;
+  unsigned char __pad2;
+  unsigned char __shared;
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned char __flags;
+  int __cur_writer;
+# define __PTHREAD_RWLOCK_ELISION_EXTRA 0
+#endif
+};
+
+#if __WORDSIZE == 64
+# define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, __PTHREAD_RWLOCK_ELISION_EXTRA, 0, __flags
+#else
+# define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, __PTHREAD_RWLOCK_ELISION_EXTRA, 0, 0, __flags, 0
+#endif
+
+#endif
diff --git a/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h b/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
index 31f46ecbde..330c302fd2 100644
--- a/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
@@ -38,23 +38,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-/* There is a lot of padding in this structure.  While it's not strictly
-   necessary on RISC-V, we're going to leave it in to be on the safe side in
-   case it's needed in the future.  Most other architectures have the padding,
-   so this gives us the same extensibility as everyone else has.  */
-struct __pthread_rwlock_arch_t
-{
-  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;
-  unsigned long int __pad1;
-  unsigned long int __pad2;
-  unsigned int __flags;
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/riscv/nptl/bits/rwlock-internal.h b/sysdeps/riscv/nptl/bits/rwlock-internal.h
new file mode 100644
index 0000000000..65a094eedc
--- /dev/null
+++ b/sysdeps/riscv/nptl/bits/rwlock-internal.h
@@ -0,0 +1,45 @@ 
+/* RISC-V internal rwlock 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 _RWLOCK_INTERNAL_H
+#define _RWLOCK_INTERNAL_H
+
+/* There is a lot of padding in this structure.  While it's not strictly
+   necessary on RISC-V, we're going to leave it in to be on the safe side in
+   case it's needed in the future.  Most other architectures have the padding,
+   so this gives us the same extensibility as everyone else has.  */
+struct __pthread_rwlock_arch_t
+{
+  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;
+  unsigned long int __pad1;
+  unsigned long int __pad2;
+  unsigned int __flags;
+};
+
+#define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags
+
+#endif
diff --git a/sysdeps/s390/nptl/bits/pthreadtypes-arch.h b/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
index 5fd32ba756..99f27d3fd0 100644
--- a/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
@@ -40,31 +40,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-struct __pthread_rwlock_arch_t
-{
-  unsigned int __readers;
-  unsigned int __writers;
-  unsigned int __wrphase_futex;
-  unsigned int __writers_futex;
-  unsigned int __pad3;
-  unsigned int __pad4;
-#if __WORDSIZE == 64
-  int __cur_writer;
-  int __shared;
-  unsigned long int __pad1;
-  unsigned long int __pad2;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned int __flags;
-# else
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __shared;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-  int __cur_writer;
-#endif
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/s390/nptl/bits/rwlock-internal.h b/sysdeps/s390/nptl/bits/rwlock-internal.h
new file mode 100644
index 0000000000..5adad874a3
--- /dev/null
+++ b/sysdeps/s390/nptl/bits/rwlock-internal.h
@@ -0,0 +1,58 @@ 
+/* S390 internal rwlock 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 _RWLOCK_INTERNAL_H
+#define _RWLOCK_INTERNAL_H
+
+struct __pthread_rwlock_arch_t
+{
+  unsigned int __readers;
+  unsigned int __writers;
+  unsigned int __wrphase_futex;
+  unsigned int __writers_futex;
+  unsigned int __pad3;
+  unsigned int __pad4;
+#if __WORDSIZE == 64
+  int __cur_writer;
+  int __shared;
+  unsigned long int __pad1;
+  unsigned long int __pad2;
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned int __flags;
+# else
+  unsigned char __pad1;
+  unsigned char __pad2;
+  unsigned char __shared;
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned char __flags;
+  int __cur_writer;
+#endif
+};
+
+#if __WORDSIZE == 64
+# define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags
+#else
+# define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, __flags, 0
+#endif
+
+#endif
diff --git a/sysdeps/sh/nptl/bits/pthreadtypes-arch.h b/sysdeps/sh/nptl/bits/pthreadtypes-arch.h
index ec861133ca..dd70a5d4fd 100644
--- a/sysdeps/sh/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/sh/nptl/bits/pthreadtypes-arch.h
@@ -33,30 +33,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-struct __pthread_rwlock_arch_t
-{
-  unsigned int __readers;
-  unsigned int __writers;
-  unsigned int __wrphase_futex;
-  unsigned int __writers_futex;
-  unsigned int __pad3;
-  unsigned int __pad4;
-#if __BYTE_ORDER == __BIG_ENDIAN
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __shared;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-#else
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-  unsigned char __shared;
-  unsigned char __pad1;
-  unsigned char __pad2;
-#endif
-  unsigned long int __cur_writer;
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/sparc/nptl/bits/pthreadtypes-arch.h b/sysdeps/sparc/nptl/bits/pthreadtypes-arch.h
index 4cda2376d2..8ea295d0a0 100644
--- a/sysdeps/sparc/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/sparc/nptl/bits/pthreadtypes-arch.h
@@ -42,31 +42,4 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-struct __pthread_rwlock_arch_t
-{
-  unsigned int __readers;
-  unsigned int __writers;
-  unsigned int __wrphase_futex;
-  unsigned int __writers_futex;
-  unsigned int __pad3;
-  unsigned int __pad4;
-#if __WORDSIZE == 64
-  int __cur_writer;
-  int __shared;
-  unsigned long int __pad1;
-  unsigned long int __pad2;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned int __flags;
-#else
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __shared;
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-  int __cur_writer;
-#endif
-};
-
 #endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/sparc/nptl/bits/rwlock-internal.h b/sysdeps/sparc/nptl/bits/rwlock-internal.h
new file mode 100644
index 0000000000..8d3e799f46
--- /dev/null
+++ b/sysdeps/sparc/nptl/bits/rwlock-internal.h
@@ -0,0 +1,58 @@ 
+/* SPARC internal rwlock 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 _RWLOCK_INTERNAL_H
+#define _RWLOCK_INTERNAL_H
+
+struct __pthread_rwlock_arch_t
+{
+  unsigned int __readers;
+  unsigned int __writers;
+  unsigned int __wrphase_futex;
+  unsigned int __writers_futex;
+  unsigned int __pad3;
+  unsigned int __pad4;
+#if __WORDSIZE == 64
+  int __cur_writer;
+  int __shared;
+  unsigned long int __pad1;
+  unsigned long int __pad2;
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned int __flags;
+#else
+  unsigned char __pad1;
+  unsigned char __pad2;
+  unsigned char __shared;
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned char __flags;
+  int __cur_writer;
+#endif
+};
+
+#if __WORDSIZE == 64
+# define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags
+#else
+# define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, __flags, 0
+#endif
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/pthread.h b/sysdeps/unix/sysv/linux/hppa/pthread.h
index 3d1e7f3a45..61e5426712 100644
--- a/sysdeps/unix/sysv/linux/hppa/pthread.h
+++ b/sysdeps/unix/sysv/linux/hppa/pthread.h
@@ -104,23 +104,13 @@  enum
   PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_READER_NP
 };
 
-/* Define __PTHREAD_RWLOCK_INT_FLAGS_SHARED to 1 if pthread_rwlock_t
-   has the shared field.  All 64-bit architectures have the shared field
-   in pthread_rwlock_t.  */
-#ifndef __PTHREAD_RWLOCK_INT_FLAGS_SHARED
-# if __WORDSIZE == 64
-#  define __PTHREAD_RWLOCK_INT_FLAGS_SHARED 1
-# endif
-#endif
-
 
 /* Read-write lock initializers.  */
 # define PTHREAD_RWLOCK_INITIALIZER \
-  { { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
+  { { __PTHREAD_RWLOCK_INITIALIZER (PTHREAD_RWLOCK_DEFAULT_NP) } }
 # ifdef __USE_GNU
 #  define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
-   { { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-       PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 0, 0, 0 } }
+  { { __PTHREAD_RWLOCK_INITIALIZER (PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) } }
 # endif
 #endif  /* Unix98 or XOpen2K */
 
diff --git a/sysdeps/x86/nptl/bits/pthreadtypes-arch.h b/sysdeps/x86/nptl/bits/pthreadtypes-arch.h
index 668ec4a5d5..426a20751d 100644
--- a/sysdeps/x86/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/x86/nptl/bits/pthreadtypes-arch.h
@@ -50,34 +50,6 @@ 
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT
 
-struct __pthread_rwlock_arch_t
-{
-  unsigned int __readers;
-  unsigned int __writers;
-  unsigned int __wrphase_futex;
-  unsigned int __writers_futex;
-  unsigned int __pad3;
-  unsigned int __pad4;
-#ifdef __x86_64__
-  int __cur_writer;
-  int __shared;
-  unsigned long int __pad1;
-  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
-#else
-  /* FLAGS must stay at this position in the structure to maintain
-     binary compatibility.  */
-  unsigned char __flags;
-  unsigned char __shared;
-  unsigned char __pad1;
-  unsigned char __pad2;
-  int __cur_writer;
-#endif
-};
-
 #ifndef __x86_64__
 /* Extra attributes for the cleanup functions.  */
 # define __cleanup_fct_attribute __attribute__ ((__regparm__ (1)))
diff --git a/sysdeps/x86/nptl/bits/rwlock-internal.h b/sysdeps/x86/nptl/bits/rwlock-internal.h
new file mode 100644
index 0000000000..7f4728ec84
--- /dev/null
+++ b/sysdeps/x86/nptl/bits/rwlock-internal.h
@@ -0,0 +1,65 @@ 
+/* x86 internal rwlock 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 _RWLOCK_INTERNAL_H
+#define _RWLOCK_INTERNAL_H
+
+struct __pthread_rwlock_arch_t
+{
+  unsigned int __readers;
+  unsigned int __writers;
+  unsigned int __wrphase_futex;
+  unsigned int __writers_futex;
+  unsigned int __pad3;
+  unsigned int __pad4;
+#ifdef __x86_64__
+  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;
+#else /* __x86_64__  */
+  /* FLAGS must stay at this position in the structure to maintain
+     binary compatibility.  */
+  unsigned char __flags;
+  unsigned char __shared;
+  signed char __rwelision;
+  unsigned char __pad2;
+  int __cur_writer;
+#endif
+};
+
+#ifdef __x86_64__
+# define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, 0, 0, __PTHREAD_RWLOCK_ELISION_EXTRA, 0, __flags
+#else
+# define __PTHREAD_RWLOCK_INITIALIZER(__flags) \
+  0, 0, 0, 0, 0, 0, __flags, 0, 0, 0, 0
+#endif
+
+#endif