diff --git a/src/unix/bsd/apple/b32.rs b/src/unix/bsd/apple/b32.rs
index 8ca02544973ec5db0337d8f1820ccdbb37064b60..464939d74751594610bcaec415e2845398622def 100644
--- a/src/unix/bsd/apple/b32.rs
+++ b/src/unix/bsd/apple/b32.rs
@@ -14,6 +14,7 @@ pub const __PTHREAD_MUTEX_SIZE__: usize = 40;
 pub const __PTHREAD_COND_SIZE__: usize = 24;
 pub const __PTHREAD_CONDATTR_SIZE__: usize = 4;
 pub const __PTHREAD_RWLOCK_SIZE__: usize = 124;
+pub const __PTHREAD_RWLOCKATTR_SIZE__: usize = 12;
 
 pub const TIOCTIMESTAMP: ::c_ulong = 0x40087459;
 pub const TIOCDCDTIMESTAMP: ::c_ulong = 0x40087458;
diff --git a/src/unix/bsd/apple/b64.rs b/src/unix/bsd/apple/b64.rs
index 3f83230805fe3ad22f8ed6caeba92e05e1321a5d..aa25a0830a8ec6c03fd4a0f17296738ff9a83faf 100644
--- a/src/unix/bsd/apple/b64.rs
+++ b/src/unix/bsd/apple/b64.rs
@@ -14,6 +14,7 @@ pub const __PTHREAD_MUTEX_SIZE__: usize = 56;
 pub const __PTHREAD_COND_SIZE__: usize = 40;
 pub const __PTHREAD_CONDATTR_SIZE__: usize = 8;
 pub const __PTHREAD_RWLOCK_SIZE__: usize = 192;
+pub const __PTHREAD_RWLOCKATTR_SIZE__: usize = 16;
 
 pub const TIOCTIMESTAMP: ::c_ulong = 0x40107459;
 pub const TIOCDCDTIMESTAMP: ::c_ulong = 0x40107458;
diff --git a/src/unix/bsd/apple/mod.rs b/src/unix/bsd/apple/mod.rs
index 44e935e37888523100b9e0c37e6558c96599a1ed..86faf4eb8711db30dadb0251f70144a82514d5a7 100644
--- a/src/unix/bsd/apple/mod.rs
+++ b/src/unix/bsd/apple/mod.rs
@@ -146,6 +146,11 @@ s! {
         __opaque: [u8; __PTHREAD_RWLOCK_SIZE__],
     }
 
+    pub struct pthread_rwlockattr_t {
+        __sig: ::c_long,
+        __opaque: [u8; __PTHREAD_RWLOCKATTR_SIZE__],
+    }
+
     pub struct siginfo_t {
         pub si_signo: ::c_int,
         pub si_errno: ::c_int,
@@ -804,6 +809,8 @@ pub const _SC_XOPEN_UNIX: ::c_int = 115;
 pub const _SC_XOPEN_VERSION: ::c_int = 116;
 pub const _SC_XOPEN_XCU_VERSION: ::c_int = 121;
 
+pub const PTHREAD_PROCESS_PRIVATE: usize = 2;
+pub const PTHREAD_PROCESS_SHARED: usize = 1;
 pub const PTHREAD_CREATE_JOINABLE: ::c_int = 1;
 pub const PTHREAD_CREATE_DETACHED: ::c_int = 2;
 pub const PTHREAD_STACK_MIN: ::size_t = 8192;
@@ -1603,6 +1610,10 @@ extern {
                                         pshared: ::c_int) -> ::c_int;
     pub fn pthread_mutexattr_getpshared(attr: *const pthread_mutexattr_t,
                                         pshared: *mut ::c_int) -> ::c_int;
+    pub fn pthread_rwlockattr_getpshared(attr: *const pthread_rwlockattr_t,
+                                         val: *mut ::c_int) -> ::c_int;
+    pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t,
+                                         val: ::c_int) -> ::c_int;
     pub fn __error() -> *mut ::c_int;
     pub fn backtrace(buf: *mut *mut ::c_void,
                      sz: ::c_int) -> ::c_int;
diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs
index 8f25ce82f6658e7c8fccbfbab5be89687115206a..7540d7992d1f0f33369bad2cce6da74aeba3d030 100644
--- a/src/unix/bsd/freebsdlike/mod.rs
+++ b/src/unix/bsd/freebsdlike/mod.rs
@@ -7,6 +7,7 @@ pub type pthread_mutexattr_t = *mut ::c_void;
 pub type pthread_cond_t = *mut ::c_void;
 pub type pthread_condattr_t = *mut ::c_void;
 pub type pthread_rwlock_t = *mut ::c_void;
+pub type pthread_rwlockattr_t = *mut ::c_void;
 pub type pthread_key_t = ::c_int;
 pub type tcflag_t = ::c_uint;
 pub type speed_t = ::c_uint;
@@ -466,6 +467,8 @@ pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2;
 pub const POSIX_MADV_WILLNEED: ::c_int = 3;
 pub const POSIX_MADV_DONTNEED: ::c_int = 4;
 
+pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0;
+pub const PTHREAD_PROCESS_SHARED: ::c_int = 1;
 pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0;
 pub const PTHREAD_CREATE_DETACHED: ::c_int = 1;
 
@@ -1059,6 +1062,10 @@ extern {
                                         pshared: ::c_int) -> ::c_int;
     pub fn pthread_mutexattr_getpshared(attr: *const pthread_mutexattr_t,
                                         pshared: *mut ::c_int) -> ::c_int;
+    pub fn pthread_rwlockattr_getpshared(attr: *const pthread_rwlockattr_t,
+                                         val: *mut ::c_int) -> ::c_int;
+    pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t,
+                                         val: ::c_int) -> ::c_int;
     pub fn getpriority(which: ::c_int, who: ::c_int) -> ::c_int;
     pub fn setpriority(which: ::c_int, who: ::c_int, prio: ::c_int) -> ::c_int;
 
diff --git a/src/unix/bsd/netbsdlike/netbsd/mod.rs b/src/unix/bsd/netbsdlike/netbsd/mod.rs
index 0230080bdc515a1894d7b3fa7d7d30293b225c98..79f2fce7561046bc21e7201602b0d577d00e4777 100644
--- a/src/unix/bsd/netbsdlike/netbsd/mod.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/mod.rs
@@ -165,6 +165,11 @@ s! {
         ptma_private: *mut ::c_void,
     }
 
+    pub struct pthread_rwlockattr_t {
+        ptra_magic: ::c_uint,
+        ptra_private: *mut ::c_void,
+    }
+
     pub struct pthread_cond_t {
         ptc_magic: ::c_uint,
         ptc_lock: ::c_uchar,
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/mod.rs b/src/unix/bsd/netbsdlike/openbsdlike/mod.rs
index 0ff399f3988ca2fe4f52476bc979140a726e58ec..e3a5115d0b50a6acff928a668b27947681bf0c9f 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/mod.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/mod.rs
@@ -13,6 +13,7 @@ pub type pthread_mutexattr_t = *mut ::c_void;
 pub type pthread_cond_t = *mut ::c_void;
 pub type pthread_condattr_t = *mut ::c_void;
 pub type pthread_rwlock_t = *mut ::c_void;
+pub type pthread_rwlockattr_t = *mut ::c_void;
 
 s! {
     pub struct dirent {
diff --git a/src/unix/haiku/mod.rs b/src/unix/haiku/mod.rs
index e3bb9ab8f8c809c633b88ac135255c95cd70a6c7..9366e02b1aaf406ebb0b266dd3dce0d35bb010ba 100644
--- a/src/unix/haiku/mod.rs
+++ b/src/unix/haiku/mod.rs
@@ -23,6 +23,7 @@ pub type useconds_t = u32;
 pub type socklen_t = u32;
 pub type pthread_t = ::uintptr_t;
 pub type pthread_mutexattr_t = ::uintptr_t;
+pub type pthread_rwlockattr_t = ::uintptr_t;
 pub type sigset_t = u64;
 pub type fsblkcnt_t = i64;
 pub type fsfilcnt_t = i64;
diff --git a/src/unix/mod.rs b/src/unix/mod.rs
index 14bf9c5393e2891ce7b3d3d28945835c99b8fbab..1c22538b3fc543a982dbf9ccc4be575bea507c97 100644
--- a/src/unix/mod.rs
+++ b/src/unix/mod.rs
@@ -647,6 +647,10 @@ extern {
     pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> ::c_int;
     pub fn pthread_condattr_init(attr: *mut pthread_condattr_t) -> ::c_int;
     pub fn pthread_condattr_destroy(attr: *mut pthread_condattr_t) -> ::c_int;
+    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
+               link_name = "pthread_rwlock_init$UNIX2003")]
+    pub fn pthread_rwlock_init(lock: *mut pthread_rwlock_t,
+                               attr: *const pthread_rwlockattr_t) -> ::c_int;
     #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
                link_name = "pthread_rwlock_destroy$UNIX2003")]
     pub fn pthread_rwlock_destroy(lock: *mut pthread_rwlock_t) -> ::c_int;
@@ -665,6 +669,9 @@ extern {
     #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
                link_name = "pthread_rwlock_unlock$UNIX2003")]
     pub fn pthread_rwlock_unlock(lock: *mut pthread_rwlock_t) -> ::c_int;
+    pub fn pthread_rwlockattr_init(attr: *mut pthread_rwlockattr_t) -> ::c_int;
+    pub fn pthread_rwlockattr_destroy(attr: *mut pthread_rwlockattr_t)
+                                      -> ::c_int;
     #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
                link_name = "pthread_sigmask$UNIX2003")]
     pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t,
diff --git a/src/unix/notbsd/android/mod.rs b/src/unix/notbsd/android/mod.rs
index e65f679ddf4b17ed40b5f37f73f8801c674cc949..31ed1b8e123092c0c7a5227855ea9f02f4e2ca96 100644
--- a/src/unix/notbsd/android/mod.rs
+++ b/src/unix/notbsd/android/mod.rs
@@ -12,6 +12,7 @@ pub type nlink_t = u32;
 pub type useconds_t = u32;
 pub type pthread_t = ::c_long;
 pub type pthread_mutexattr_t = ::c_long;
+pub type pthread_rwlockattr_t = ::c_long;
 pub type pthread_condattr_t = ::c_long;
 pub type fsfilcnt_t = ::c_ulong;
 pub type fsblkcnt_t = ::c_ulong;
diff --git a/src/unix/notbsd/linux/mips/mips32.rs b/src/unix/notbsd/linux/mips/mips32.rs
index f3e4c4788c9ab167c39c5736c7db1e9d7011c4d5..8bbaeb9c4b2d04b16d41e29649f41652f71a7af5 100644
--- a/src/unix/notbsd/linux/mips/mips32.rs
+++ b/src/unix/notbsd/linux/mips/mips32.rs
@@ -229,6 +229,7 @@ pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
 pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24;
 pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32;
 pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
+pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;
 
 pub const RLIM_INFINITY: ::rlim_t = 0x7fffffff;
 
diff --git a/src/unix/notbsd/linux/mips/mips64.rs b/src/unix/notbsd/linux/mips/mips64.rs
index 1a56b6cc48819794ad2ced8c0743b4b2d8de021d..9091c566ab06e5adcd3f6d64f38d7d89bd9d1b20 100644
--- a/src/unix/notbsd/linux/mips/mips64.rs
+++ b/src/unix/notbsd/linux/mips/mips64.rs
@@ -215,6 +215,7 @@ pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
 pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
 pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40;
 pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56;
+pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;
 
 pub const RLIM_INFINITY: ::rlim_t = 0xffff_ffff_ffff_ffff;
 
diff --git a/src/unix/notbsd/linux/mod.rs b/src/unix/notbsd/linux/mod.rs
index 45d097e224200f2fb88e975958e7d8798acd1e92..39eea4d0786be34c4f051c469ccd891f42f381b0 100644
--- a/src/unix/notbsd/linux/mod.rs
+++ b/src/unix/notbsd/linux/mod.rs
@@ -104,6 +104,14 @@ s! {
         size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T],
     }
 
+    pub struct pthread_rwlockattr_t {
+        #[cfg(any(target_env = "musl"))]
+        __align: [::c_int; 0],
+        #[cfg(not(any(target_env = "musl")))]
+        __align: [::c_long; 0],
+        size: [u8; __SIZEOF_PTHREAD_RWLOCKATTR_T],
+    }
+
     pub struct pthread_cond_t {
         #[cfg(any(target_env = "musl"))]
         __align: [*const ::c_void; 0],
@@ -647,6 +655,8 @@ pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0;
 pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1;
 pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2;
 pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL;
+pub const PTHREAD_PROCESS_PRIVATE: usize = 0;
+pub const PTHREAD_PROCESS_SHARED: usize = 1;
 pub const __SIZEOF_PTHREAD_COND_T: usize = 48;
 
 pub const SCHED_OTHER: ::c_int = 0;
diff --git a/src/unix/notbsd/linux/musl/mod.rs b/src/unix/notbsd/linux/musl/mod.rs
index 7a1dcb9b5d67d34fa1483a6aac0bcf081082bbb7..e755c7a37d7ce6b5b7fb425ba399f55712b5f85c 100644
--- a/src/unix/notbsd/linux/musl/mod.rs
+++ b/src/unix/notbsd/linux/musl/mod.rs
@@ -160,6 +160,7 @@ pub const FALLOC_FL_PUNCH_HOLE: ::c_int = 0x02;
 
 pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
 pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
+pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;
 
 pub const CPU_SETSIZE: ::c_int = 128;
 
diff --git a/src/unix/notbsd/linux/other/b32/mod.rs b/src/unix/notbsd/linux/other/b32/mod.rs
index 8b8b1d5ac2fd5843f7b8f0ef606c63ba1b3e07b6..3218fa7fcddf07702b430146828c7c8d21b10f6b 100644
--- a/src/unix/notbsd/linux/other/b32/mod.rs
+++ b/src/unix/notbsd/linux/other/b32/mod.rs
@@ -263,6 +263,7 @@ pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
 pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24;
 pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32;
 pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
+pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;
 
 pub const PTRACE_GETFPREGS: ::c_uint = 14;
 pub const PTRACE_SETFPREGS: ::c_uint = 15;
diff --git a/src/unix/notbsd/linux/other/b64/mod.rs b/src/unix/notbsd/linux/other/b64/mod.rs
index 2fcec73a894610d61377ec221c157fad40910e90..1e306dad2b3c8d68c40583546176ffcfb8f987a3 100644
--- a/src/unix/notbsd/linux/other/b64/mod.rs
+++ b/src/unix/notbsd/linux/other/b64/mod.rs
@@ -47,6 +47,7 @@ s! {
 }
 
 pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56;
+pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;
 
 cfg_if! {
     if #[cfg(target_arch = "aarch64")] {
diff --git a/src/unix/notbsd/linux/other/mod.rs b/src/unix/notbsd/linux/other/mod.rs
index 496eb88c0ea6b3f9c2633db3d6244ca661f4fe1e..ef34b37ef9c256e82194c286f0e0f5473de4431a 100644
--- a/src/unix/notbsd/linux/other/mod.rs
+++ b/src/unix/notbsd/linux/other/mod.rs
@@ -576,6 +576,10 @@ extern {
     pub fn pthread_setaffinity_np(thread: ::pthread_t,
                                   cpusetsize: ::size_t,
                                   cpuset: *const ::cpu_set_t) -> ::c_int;
+    pub fn pthread_rwlockattr_getkind_np(attr: *const ::pthread_rwlockattr_t,
+                                         val: *mut ::c_int) -> ::c_int;
+    pub fn pthread_rwlockattr_setkind_np(attr: *mut ::pthread_rwlockattr_t,
+                                         val: ::c_int) -> ::c_int;
     pub fn sched_getcpu() -> ::c_int;
 }
 
diff --git a/src/unix/notbsd/linux/s390x.rs b/src/unix/notbsd/linux/s390x.rs
index 070838de3cf291dcba80d0b437f44bb88f00784b..21d96bfb0dca2e89bf979c0341f58da2e3d9c1af 100644
--- a/src/unix/notbsd/linux/s390x.rs
+++ b/src/unix/notbsd/linux/s390x.rs
@@ -314,6 +314,7 @@ pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
 pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
 pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40;
 pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56;
+pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;
 
 pub const EADDRINUSE: ::c_int = 98;
 pub const EADDRNOTAVAIL: ::c_int = 99;
diff --git a/src/unix/notbsd/mod.rs b/src/unix/notbsd/mod.rs
index 8fa3750406e1b8ee83d9d8ed8b1bf58247e9c80c..3f7c5a7491c23864ca93218aadd94e65fd0542d7 100644
--- a/src/unix/notbsd/mod.rs
+++ b/src/unix/notbsd/mod.rs
@@ -992,6 +992,10 @@ extern {
                                         pshared: ::c_int) -> ::c_int;
     pub fn pthread_mutexattr_getpshared(attr: *const pthread_mutexattr_t,
                                         pshared: *mut ::c_int) -> ::c_int;
+    pub fn pthread_rwlockattr_getpshared(attr: *const pthread_rwlockattr_t,
+                                         val: *mut ::c_int) -> ::c_int;
+    pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t,
+                                         val: ::c_int) -> ::c_int;
     pub fn ptsname_r(fd: ::c_int,
                      buf: *mut ::c_char,
                      buflen: ::size_t) -> ::c_int;
diff --git a/src/unix/solaris/mod.rs b/src/unix/solaris/mod.rs
index 08544c68e7d61c3713419a280fcce5d2830d75d6..51d034e0f4d4ae7cfd52ae002932ef746592a433 100644
--- a/src/unix/solaris/mod.rs
+++ b/src/unix/solaris/mod.rs
@@ -169,6 +169,10 @@ s! {
         __pthread_rwlock_writercv: ::pthread_cond_t
     }
 
+    pub struct pthread_rwlockattr_t {
+        __pthread_rwlockattrp: *mut ::c_void,
+    }
+
     pub struct dirent {
         pub d_ino: ::ino_t,
         pub d_off: ::off_t,
@@ -769,7 +773,7 @@ pub const POSIX_MADV_DONTNEED: ::c_int = 4;
 pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0;
 pub const PTHREAD_CREATE_DETACHED: ::c_int = 0x40;
 pub const PTHREAD_PROCESS_SHARED: ::c_int = 1;
-pub const PTHREAD_PROCESS_PRIVATE: u16 = 0;
+pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0;
 pub const PTHREAD_STACK_MIN: ::size_t = 4096;
 
 pub const SIGSTKSZ: ::size_t = 8192;
diff --git a/src/unix/uclibc/mod.rs b/src/unix/uclibc/mod.rs
index 09f7d055f3d0349b11a3a2d36c2857fe8d098816..01960361b935eef76a51b31aac65aa05c374c856 100644
--- a/src/unix/uclibc/mod.rs
+++ b/src/unix/uclibc/mod.rs
@@ -257,6 +257,11 @@ s! {
         size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T],
     }
 
+    pub struct pthread_rwlockattr_t {
+        __lockkind: ::c_int,
+        __pshared: ::c_int,
+    }
+
     pub struct pthread_cond_t {
         __align: [::c_longlong; 0],
         size: [u8; __SIZEOF_PTHREAD_COND_T],
@@ -1577,6 +1582,14 @@ extern {
                                         pshared: ::c_int) -> ::c_int;
     pub fn pthread_mutexattr_getpshared(attr: *const pthread_mutexattr_t,
                                         pshared: *mut ::c_int) -> ::c_int;
+    pub fn pthread_rwlockattr_getkind_np(attr: *const pthread_rwlockattr_t,
+                                         val: *mut ::c_int) -> ::c_int;
+    pub fn pthread_rwlockattr_setkind_np(attr: *mut pthread_rwlockattr_t,
+                                         val: ::c_int) -> ::c_int;
+    pub fn pthread_rwlockattr_getpshared(attr: *const pthread_rwlockattr_t,
+                                         val: *mut ::c_int) -> ::c_int;
+    pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t,
+                                         val: ::c_int) -> ::c_int;
     pub fn ptsname_r(fd: ::c_int,
                      buf: *mut ::c_char,
                      buflen: ::size_t) -> ::c_int;