[libc-commits] [libc] [libc] add pthread_rwlock_clockrdlock and pthread_rwlock_clockwrlock … (PR #100543)

via libc-commits libc-commits at lists.llvm.org
Sun Jul 28 01:48:29 PDT 2024


https://github.com/Eric977 updated https://github.com/llvm/llvm-project/pull/100543

>From c8160342cad6dba35207de76be58c76ddae4f77d Mon Sep 17 00:00:00 2001
From: Eric977 <zxc1305530 at gmail.com>
Date: Sun, 21 Jul 2024 09:48:37 +0800
Subject: [PATCH 1/4] [libc] add pthread_rwlock_clockrdlock and
 pthread_rwlock_clockwrlock GNU extensions

---
 libc/config/linux/aarch64/entrypoints.txt     |  2 +
 libc/config/linux/riscv/entrypoints.txt       |  2 +
 libc/config/linux/x86_64/entrypoints.txt      |  2 +
 libc/src/pthread/CMakeLists.txt               | 22 ++++++++
 .../pthread/pthread_rwlock_clockrdlock.cpp    | 51 ++++++++++++++++++
 libc/src/pthread/pthread_rwlock_clockrdlock.h | 23 ++++++++
 .../pthread/pthread_rwlock_clockwrlock.cpp    | 52 +++++++++++++++++++
 libc/src/pthread/pthread_rwlock_clockwrlock.h | 23 ++++++++
 .../integration/src/pthread/CMakeLists.txt    |  2 +
 .../src/pthread/pthread_rwlock_test.cpp       | 41 +++++++++++++--
 10 files changed, 217 insertions(+), 3 deletions(-)
 create mode 100644 libc/src/pthread/pthread_rwlock_clockrdlock.cpp
 create mode 100644 libc/src/pthread/pthread_rwlock_clockrdlock.h
 create mode 100644 libc/src/pthread/pthread_rwlock_clockwrlock.cpp
 create mode 100644 libc/src/pthread/pthread_rwlock_clockwrlock.h

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 2334fed773702..260424291f3ab 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -692,6 +692,8 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.pthread.pthread_mutexattr_setrobust
     libc.src.pthread.pthread_mutexattr_settype
     libc.src.pthread.pthread_once
+    libc.src.pthread.pthread_rwlock_clockrdlock
+    libc.src.pthread.pthread_rwlock_clockwrlock
     libc.src.pthread.pthread_rwlock_destroy
     libc.src.pthread.pthread_rwlock_init
     libc.src.pthread.pthread_rwlock_rdlock
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 07466805b34cd..ead1fabc397ee 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -703,6 +703,8 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.pthread.pthread_mutexattr_setrobust
     libc.src.pthread.pthread_mutexattr_settype
     libc.src.pthread.pthread_once
+    libc.src.pthread.pthread_rwlock_clockrdlock
+    libc.src.pthread.pthread_rwlock_clockwrlock
     libc.src.pthread.pthread_rwlock_destroy
     libc.src.pthread.pthread_rwlock_init
     libc.src.pthread.pthread_rwlock_rdlock
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 035ceb8ca57bf..6911b2972f80c 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -790,6 +790,8 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.pthread.pthread_mutexattr_setrobust
     libc.src.pthread.pthread_mutexattr_settype
     libc.src.pthread.pthread_once
+    libc.src.pthread.pthread_rwlock_clockrdlock
+    libc.src.pthread.pthread_rwlock_clockwrlock
     libc.src.pthread.pthread_rwlock_destroy
     libc.src.pthread.pthread_rwlock_init
     libc.src.pthread.pthread_rwlock_rdlock
diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt
index dc748b22e0378..70d10e6c4e3f8 100644
--- a/libc/src/pthread/CMakeLists.txt
+++ b/libc/src/pthread/CMakeLists.txt
@@ -556,6 +556,28 @@ add_entrypoint_object(
     libc.src.__support.threads.linux.rwlock
 )
 
+add_entrypoint_object(
+  pthread_rwlock_clockrdlock
+  SRCS
+    pthread_rwlock_clockrdlock.cpp
+  HDRS
+    pthread_rwlock_clockrdlock.h
+  DEPENDS
+    libc.include.pthread
+    libc.src.__support.threads.linux.rwlock
+)
+
+add_entrypoint_object(
+  pthread_rwlock_clockwrlock
+  SRCS
+    pthread_rwlock_clockwrlock.cpp
+  HDRS
+    pthread_rwlock_clockwrlock.h
+  DEPENDS
+    libc.include.pthread
+    libc.src.__support.threads.linux.rwlock
+)
+
 add_entrypoint_object(
   pthread_rwlock_timedrdlock
   SRCS
diff --git a/libc/src/pthread/pthread_rwlock_clockrdlock.cpp b/libc/src/pthread/pthread_rwlock_clockrdlock.cpp
new file mode 100644
index 0000000000000..421bbbab0011a
--- /dev/null
+++ b/libc/src/pthread/pthread_rwlock_clockrdlock.cpp
@@ -0,0 +1,51 @@
+//===-- Implementation of the Rwlock's clockrdlock function
+//--------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/pthread/pthread_rwlock_clockrdlock.h"
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/threads/linux/rwlock.h"
+
+#include <errno.h>
+#include <pthread.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+static_assert(
+    sizeof(RwLock) == sizeof(pthread_rwlock_t) &&
+        alignof(RwLock) == alignof(pthread_rwlock_t),
+    "The public pthread_rwlock_t type must be of the same size and alignment "
+    "as the internal rwlock type.");
+
+LLVM_LIBC_FUNCTION(int, pthread_rwlock_clockrdlock,
+                   (pthread_rwlock_t * rwlock, clockid_t clockid,
+                    const struct timespec *abstime)) {
+  if (!rwlock)
+    return EINVAL;
+  if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_REALTIME)
+    return EINVAL;
+  bool is_realtime = (clockid == CLOCK_REALTIME);
+  RwLock *rw = reinterpret_cast<RwLock *>(rwlock);
+  LIBC_ASSERT(abstime && "clockrdlock called with a null timeout");
+  auto timeout = internal::AbsTimeout::from_timespec(
+      *abstime, /*is_realtime=*/is_realtime);
+  if (LIBC_LIKELY(timeout.has_value()))
+    return static_cast<int>(rw->read_lock(timeout.value()));
+
+  switch (timeout.error()) {
+  case internal::AbsTimeout::Error::Invalid:
+    return EINVAL;
+  case internal::AbsTimeout::Error::BeforeEpoch:
+    return ETIMEDOUT;
+  }
+  __builtin_unreachable();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/pthread/pthread_rwlock_clockrdlock.h b/libc/src/pthread/pthread_rwlock_clockrdlock.h
new file mode 100644
index 0000000000000..dd11d3cdf0814
--- /dev/null
+++ b/libc/src/pthread/pthread_rwlock_clockrdlock.h
@@ -0,0 +1,23 @@
+//===-- Implementation header for Rwlock's clockrdlock function -------*-
+// C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCK_CLOCKRDLOCK_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCK_CLOCKRDLOCK_H
+
+#include "src/__support/macros/config.h"
+#include <pthread.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+int pthread_rwlock_clockrdlock(pthread_rwlock_t *rwlock, clockid_t clockid,
+                               const struct timespec *abstime);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCK_CLOCKRDLOCK_H
diff --git a/libc/src/pthread/pthread_rwlock_clockwrlock.cpp b/libc/src/pthread/pthread_rwlock_clockwrlock.cpp
new file mode 100644
index 0000000000000..8c65970670c07
--- /dev/null
+++ b/libc/src/pthread/pthread_rwlock_clockwrlock.cpp
@@ -0,0 +1,52 @@
+//===-- Implementation of the Rwlock's clockwrlock function
+//--------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/pthread/pthread_rwlock_clockwrlock.h"
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/threads/linux/rwlock.h"
+#include "src/__support/time/linux/abs_timeout.h"
+
+#include <errno.h>
+#include <pthread.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+static_assert(
+    sizeof(RwLock) == sizeof(pthread_rwlock_t) &&
+        alignof(RwLock) == alignof(pthread_rwlock_t),
+    "The public pthread_rwlock_t type must be of the same size and alignment "
+    "as the internal rwlock type.");
+
+LLVM_LIBC_FUNCTION(int, pthread_rwlock_clockwrlock,
+                   (pthread_rwlock_t * rwlock, clockid_t clockid,
+                    const struct timespec *abstime)) {
+  if (!rwlock)
+    return EINVAL;
+  if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_REALTIME)
+    return EINVAL;
+  bool is_realtime = (clockid == CLOCK_REALTIME);
+  RwLock *rw = reinterpret_cast<RwLock *>(rwlock);
+  LIBC_ASSERT(abstime && "clockwrlock called with a null timeout");
+  auto timeout = internal::AbsTimeout::from_timespec(
+      *abstime, /*is_realtime=*/is_realtime);
+  if (LIBC_LIKELY(timeout.has_value()))
+    return static_cast<int>(rw->write_lock(timeout.value()));
+
+  switch (timeout.error()) {
+  case internal::AbsTimeout::Error::Invalid:
+    return EINVAL;
+  case internal::AbsTimeout::Error::BeforeEpoch:
+    return ETIMEDOUT;
+  }
+  __builtin_unreachable();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/pthread/pthread_rwlock_clockwrlock.h b/libc/src/pthread/pthread_rwlock_clockwrlock.h
new file mode 100644
index 0000000000000..ee0ec15a521a9
--- /dev/null
+++ b/libc/src/pthread/pthread_rwlock_clockwrlock.h
@@ -0,0 +1,23 @@
+//===-- Implementation header for Rwlock's clockwrlock function -------*-
+// C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCK_CLOCKWRLOCK_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCK_CLOCKWRLOCK_H
+
+#include "src/__support/macros/config.h"
+#include <pthread.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+int pthread_rwlock_clockwrlock(pthread_rwlock_t *rwlock, clockid_t clockid,
+                               const struct timespec *abstime);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCK_CLOCKWRLOCK_H
diff --git a/libc/test/integration/src/pthread/CMakeLists.txt b/libc/test/integration/src/pthread/CMakeLists.txt
index fa5fd3ad55d5f..eb26822597c2f 100644
--- a/libc/test/integration/src/pthread/CMakeLists.txt
+++ b/libc/test/integration/src/pthread/CMakeLists.txt
@@ -32,9 +32,11 @@ add_integration_test(
     libc.src.pthread.pthread_rwlock_rdlock
     libc.src.pthread.pthread_rwlock_tryrdlock
     libc.src.pthread.pthread_rwlock_timedrdlock
+    libc.src.pthread.pthread_rwlock_clockrdlock
     libc.src.pthread.pthread_rwlock_wrlock
     libc.src.pthread.pthread_rwlock_trywrlock
     libc.src.pthread.pthread_rwlock_timedwrlock
+    libc.src.pthread.pthread_rwlock_clockwrlock
     libc.src.pthread.pthread_rwlock_unlock
     libc.src.pthread.pthread_create
     libc.src.pthread.pthread_join
diff --git a/libc/test/integration/src/pthread/pthread_rwlock_test.cpp b/libc/test/integration/src/pthread/pthread_rwlock_test.cpp
index 455003b6af811..39194ce55fe30 100644
--- a/libc/test/integration/src/pthread/pthread_rwlock_test.cpp
+++ b/libc/test/integration/src/pthread/pthread_rwlock_test.cpp
@@ -15,6 +15,8 @@
 #include "src/__support/threads/sleep.h"
 #include "src/pthread/pthread_create.h"
 #include "src/pthread/pthread_join.h"
+#include "src/pthread/pthread_rwlock_clockrdlock.h"
+#include "src/pthread/pthread_rwlock_clockwrlock.h"
 #include "src/pthread/pthread_rwlock_destroy.h"
 #include "src/pthread/pthread_rwlock_init.h"
 #include "src/pthread/pthread_rwlock_rdlock.h"
@@ -112,6 +114,8 @@ static void nullptr_test() {
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_wrlock(nullptr), EINVAL);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedrdlock(nullptr, &ts), EINVAL);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedwrlock(nullptr, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(nullptr, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(nullptr, &ts), EINVAL);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_tryrdlock(nullptr), EINVAL);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_trywrlock(nullptr), EINVAL);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_unlock(nullptr), EINVAL);
@@ -159,16 +163,26 @@ static void unusual_timespec_test() {
   timespec ts = {0, -1};
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedrdlock(&rwlock, &ts), EINVAL);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedwrlock(&rwlock, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, &ts), EINVAL);
   ts.tv_nsec = 1'000'000'000;
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedrdlock(&rwlock, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, &ts), EINVAL);
   ts.tv_nsec += 1;
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedwrlock(&rwlock, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, &ts), EINVAL);
   ts.tv_nsec = 0;
   ts.tv_sec = -1;
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedrdlock(&rwlock, &ts),
             ETIMEDOUT);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedwrlock(&rwlock, &ts),
             ETIMEDOUT);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, &ts),
+            ETIMEDOUT);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, &ts),
+            ETIMEDOUT);
 }
 
 static void timedlock_with_deadlock_test() {
@@ -184,6 +198,9 @@ static void timedlock_with_deadlock_test() {
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedwrlock(&rwlock, &ts),
             ETIMEDOUT);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedrdlock(&rwlock, &ts), 0);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, &ts),
+            ETIMEDOUT);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, &ts), 0);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_unlock(&rwlock), 0);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_unlock(&rwlock), 0);
   // notice that ts is already expired, but the following should still succeed.
@@ -270,9 +287,11 @@ enum class Operation : int {
   WRITE = 1,
   TIMED_READ = 2,
   TIMED_WRITE = 3,
-  TRY_READ = 4,
-  TRY_WRITE = 5,
-  COUNT = 6
+  CLOCK_READ = 4,
+  CLOCK_WRITE = 5,
+  TRY_READ = 6,
+  TRY_WRITE = 7,
+  COUNT = 8
 };
 
 LIBC_NAMESPACE::RawMutex *io_mutex;
@@ -358,6 +377,22 @@ static void randomized_thread_operation(SharedData *data, ThreadGuard &guard) {
     }
     break;
   }
+  case Operation::CLOCK_READ: {
+    timespec ts = get_ts();
+    if (LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&data->lock, &ts) == 0) {
+      read_ops();
+      LIBC_NAMESPACE::pthread_rwlock_unlock(&data->lock);
+    }
+    break;
+  }
+  case Operation::CLOCK_WRITE: {
+    timespec ts = get_ts();
+    if (LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&data->lock, &ts) == 0) {
+      write_ops();
+      LIBC_NAMESPACE::pthread_rwlock_unlock(&data->lock);
+    }
+    break;
+  }
   case Operation::TRY_READ: {
     if (LIBC_NAMESPACE::pthread_rwlock_tryrdlock(&data->lock) == 0) {
       read_ops();

>From e67091c94d8c73c636c35163677828e2df0ef50f Mon Sep 17 00:00:00 2001
From: Eric977 <zxc1305530 at gmail.com>
Date: Sat, 27 Jul 2024 18:12:11 +0800
Subject: [PATCH 2/4] add function definitions

---
 libc/newhdrgen/yaml/pthread.yaml              | 14 ++++++++++++++
 libc/spec/posix.td                            | 10 ++++++++++
 libc/src/pthread/pthread_rwlock_clockrdlock.h |  5 +++--
 libc/src/pthread/pthread_rwlock_clockwrlock.h |  5 +++--
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/libc/newhdrgen/yaml/pthread.yaml b/libc/newhdrgen/yaml/pthread.yaml
index 292d91751e406..d492dfcbd51eb 100644
--- a/libc/newhdrgen/yaml/pthread.yaml
+++ b/libc/newhdrgen/yaml/pthread.yaml
@@ -370,6 +370,20 @@ functions:
     arguments:
       - type: pthread_rwlock_t *__restrict
       - type: const struct timespec *__restrict
+  - name: pthread_rwlock_clockrdlock
+    standards: POSIX
+    return_type: int
+    arguments:
+      - type: pthread_rwlock_t *__restrict
+      - type: clockid_t
+      - type: const struct timespec *__restrict
+  - name: pthread_rwlock_clockwrlock
+    standards: POSIX
+    return_type: int
+    arguments:
+      - type: pthread_rwlock_t *__restrict
+      - type: clockid_t
+      - type: const struct timespec *__restrict
   - name: pthread_rwlock_rdlock
     standards: POSIX
     return_type: int
diff --git a/libc/spec/posix.td b/libc/spec/posix.td
index 48f743dff4e6f..58a2dffd2d58b 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -1320,6 +1320,16 @@ def POSIX : StandardSpec<"POSIX"> {
         RetValSpec<IntType>,
         [ArgSpec<RestrictedPThreadRWLockTPtr>, ArgSpec<ConstRestrictStructTimeSpecPtr>]
       >,
+      FunctionSpec<
+        "pthread_rwlock_clockrdlock",
+        RetValSpec<IntType>,
+        [ArgSpec<RestrictedPThreadRWLockTPtr>, ArgSpec<ClockIdT>, ArgSpec<ConstRestrictStructTimeSpecPtr>]
+      >,
+      FunctionSpec<
+        "pthread_rwlock_clockwrlock",
+        RetValSpec<IntType>,
+        [ArgSpec<RestrictedPThreadRWLockTPtr>, ArgSpec<ClockIdT>, ArgSpec<ConstRestrictStructTimeSpecPtr>]
+      >,
       FunctionSpec<
         "pthread_rwlock_rdlock",
         RetValSpec<IntType>,
diff --git a/libc/src/pthread/pthread_rwlock_clockrdlock.h b/libc/src/pthread/pthread_rwlock_clockrdlock.h
index dd11d3cdf0814..bf6edd62d0db6 100644
--- a/libc/src/pthread/pthread_rwlock_clockrdlock.h
+++ b/libc/src/pthread/pthread_rwlock_clockrdlock.h
@@ -15,8 +15,9 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-int pthread_rwlock_clockrdlock(pthread_rwlock_t *rwlock, clockid_t clockid,
-                               const struct timespec *abstime);
+int pthread_rwlock_clockrdlock(pthread_rwlock_t *__restrict rwlock,
+                               clockid_t clockid,
+                               const struct timespec *__restrict abstime);
 
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/pthread/pthread_rwlock_clockwrlock.h b/libc/src/pthread/pthread_rwlock_clockwrlock.h
index ee0ec15a521a9..ca935ed44d163 100644
--- a/libc/src/pthread/pthread_rwlock_clockwrlock.h
+++ b/libc/src/pthread/pthread_rwlock_clockwrlock.h
@@ -15,8 +15,9 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-int pthread_rwlock_clockwrlock(pthread_rwlock_t *rwlock, clockid_t clockid,
-                               const struct timespec *abstime);
+int pthread_rwlock_clockwrlock(pthread_rwlock_t *__restrict rwlock,
+                               clockid_t clockid,
+                               const struct timespec *__restrict abstime);
 
 } // namespace LIBC_NAMESPACE_DECL
 

>From 97ec6e344e3d7e35ab6c0d959dce61660404e136 Mon Sep 17 00:00:00 2001
From: Eric977 <zxc1305530 at gmail.com>
Date: Sat, 27 Jul 2024 23:54:36 +0800
Subject: [PATCH 3/4] change include header

---
 libc/src/pthread/pthread_rwlock_clockrdlock.cpp | 7 +++----
 libc/src/pthread/pthread_rwlock_clockrdlock.h   | 5 ++---
 libc/src/pthread/pthread_rwlock_clockwrlock.cpp | 7 +++----
 libc/src/pthread/pthread_rwlock_clockwrlock.h   | 5 ++---
 4 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/libc/src/pthread/pthread_rwlock_clockrdlock.cpp b/libc/src/pthread/pthread_rwlock_clockrdlock.cpp
index 421bbbab0011a..1e44e6d7694f6 100644
--- a/libc/src/pthread/pthread_rwlock_clockrdlock.cpp
+++ b/libc/src/pthread/pthread_rwlock_clockrdlock.cpp
@@ -1,5 +1,4 @@
-//===-- Implementation of the Rwlock's clockrdlock function
-//--------------------===//
+//===-- Implementation of the Rwlock's clockrdlock function ---------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -9,11 +8,11 @@
 
 #include "src/pthread/pthread_rwlock_clockrdlock.h"
 
+#include "hdr/errno_macros.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
 #include "src/__support/threads/linux/rwlock.h"
 
-#include <errno.h>
 #include <pthread.h>
 
 namespace LIBC_NAMESPACE_DECL {
@@ -26,7 +25,7 @@ static_assert(
 
 LLVM_LIBC_FUNCTION(int, pthread_rwlock_clockrdlock,
                    (pthread_rwlock_t * rwlock, clockid_t clockid,
-                    const struct timespec *abstime)) {
+                    const timespec *abstime)) {
   if (!rwlock)
     return EINVAL;
   if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_REALTIME)
diff --git a/libc/src/pthread/pthread_rwlock_clockrdlock.h b/libc/src/pthread/pthread_rwlock_clockrdlock.h
index bf6edd62d0db6..8fbd3b089a111 100644
--- a/libc/src/pthread/pthread_rwlock_clockrdlock.h
+++ b/libc/src/pthread/pthread_rwlock_clockrdlock.h
@@ -1,5 +1,4 @@
-//===-- Implementation header for Rwlock's clockrdlock function -------*-
-// C++-*-===//
+//===-- Implementation header for Rwlock's clockrdlock function --*- C++-*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -17,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
 
 int pthread_rwlock_clockrdlock(pthread_rwlock_t *__restrict rwlock,
                                clockid_t clockid,
-                               const struct timespec *__restrict abstime);
+                               const timespec *__restrict abstime);
 
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/pthread/pthread_rwlock_clockwrlock.cpp b/libc/src/pthread/pthread_rwlock_clockwrlock.cpp
index 8c65970670c07..8f58c7f24bb10 100644
--- a/libc/src/pthread/pthread_rwlock_clockwrlock.cpp
+++ b/libc/src/pthread/pthread_rwlock_clockwrlock.cpp
@@ -1,5 +1,4 @@
-//===-- Implementation of the Rwlock's clockwrlock function
-//--------------------===//
+//===-- Implementation of the Rwlock's clockwrlock function----------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -9,12 +8,12 @@
 
 #include "src/pthread/pthread_rwlock_clockwrlock.h"
 
+#include "hdr/errno_macros.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
 #include "src/__support/threads/linux/rwlock.h"
 #include "src/__support/time/linux/abs_timeout.h"
 
-#include <errno.h>
 #include <pthread.h>
 
 namespace LIBC_NAMESPACE_DECL {
@@ -27,7 +26,7 @@ static_assert(
 
 LLVM_LIBC_FUNCTION(int, pthread_rwlock_clockwrlock,
                    (pthread_rwlock_t * rwlock, clockid_t clockid,
-                    const struct timespec *abstime)) {
+                    const timespec *abstime)) {
   if (!rwlock)
     return EINVAL;
   if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_REALTIME)
diff --git a/libc/src/pthread/pthread_rwlock_clockwrlock.h b/libc/src/pthread/pthread_rwlock_clockwrlock.h
index ca935ed44d163..cb3fa3909fd2b 100644
--- a/libc/src/pthread/pthread_rwlock_clockwrlock.h
+++ b/libc/src/pthread/pthread_rwlock_clockwrlock.h
@@ -1,5 +1,4 @@
-//===-- Implementation header for Rwlock's clockwrlock function -------*-
-// C++-*-===//
+//===-- Implementation header for Rwlock's clockwrlock function --*- C++-*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -17,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
 
 int pthread_rwlock_clockwrlock(pthread_rwlock_t *__restrict rwlock,
                                clockid_t clockid,
-                               const struct timespec *__restrict abstime);
+                               const timespec *__restrict abstime);
 
 } // namespace LIBC_NAMESPACE_DECL
 

>From fb61296dc657b8d75be2f04fa59d606a0b3a6367 Mon Sep 17 00:00:00 2001
From: b08902132 <b08902132 at ws1.csie.ntu.edu.tw>
Date: Sun, 28 Jul 2024 16:41:01 +0800
Subject: [PATCH 4/4] fix wrong function parameter

---
 libc/docs/dev/undefined_behavior.rst          |  5 ++++
 .../src/pthread/pthread_rwlock_test.cpp       | 28 +++++++++----------
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/libc/docs/dev/undefined_behavior.rst b/libc/docs/dev/undefined_behavior.rst
index b712780222aa3..6c3963f069bbd 100644
--- a/libc/docs/dev/undefined_behavior.rst
+++ b/libc/docs/dev/undefined_behavior.rst
@@ -116,3 +116,8 @@ inherited from parent process triggered inside the instruction window between ``
 and ``exec*``. As libc failed to maintain its internal states correctly, even though the
 functions used inside the signal handlers are marked as ``async-signal-safe`` (such as
 ``getpid``), they will still return wrong values or lead to other even worse situations.
+
+Unrecognized ``clockid_t`` values for ``pthread_rwlock_clock*`` APIs
+----------------------------------------------------------------------
+POSIX.1-2024 only demands support for ``CLOCK_REALTIME`` and ``CLOCK_MONOTONIC``. Currently,
+as in LLVM libc, if other clock ids are used, they will be treated as monotonic clocks.
diff --git a/libc/test/integration/src/pthread/pthread_rwlock_test.cpp b/libc/test/integration/src/pthread/pthread_rwlock_test.cpp
index 39194ce55fe30..1fc4501f262be 100644
--- a/libc/test/integration/src/pthread/pthread_rwlock_test.cpp
+++ b/libc/test/integration/src/pthread/pthread_rwlock_test.cpp
@@ -114,8 +114,8 @@ static void nullptr_test() {
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_wrlock(nullptr), EINVAL);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedrdlock(nullptr, &ts), EINVAL);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedwrlock(nullptr, &ts), EINVAL);
-  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(nullptr, &ts), EINVAL);
-  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(nullptr, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(nullptr, CLOCK_MONOTONIC, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(nullptr, CLOCK_MONOTONIC, &ts), EINVAL);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_tryrdlock(nullptr), EINVAL);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_trywrlock(nullptr), EINVAL);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_unlock(nullptr), EINVAL);
@@ -163,25 +163,25 @@ static void unusual_timespec_test() {
   timespec ts = {0, -1};
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedrdlock(&rwlock, &ts), EINVAL);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedwrlock(&rwlock, &ts), EINVAL);
-  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, &ts), EINVAL);
-  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, CLOCK_MONOTONIC, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, CLOCK_MONOTONIC, &ts), EINVAL);
   ts.tv_nsec = 1'000'000'000;
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedrdlock(&rwlock, &ts), EINVAL);
-  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, &ts), EINVAL);
-  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, CLOCK_MONOTONIC, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, CLOCK_MONOTONIC, &ts), EINVAL);
   ts.tv_nsec += 1;
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedwrlock(&rwlock, &ts), EINVAL);
-  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, &ts), EINVAL);
-  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, CLOCK_MONOTONIC, &ts), EINVAL);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, CLOCK_MONOTONIC, &ts), EINVAL);
   ts.tv_nsec = 0;
   ts.tv_sec = -1;
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedrdlock(&rwlock, &ts),
             ETIMEDOUT);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedwrlock(&rwlock, &ts),
             ETIMEDOUT);
-  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, &ts),
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, CLOCK_MONOTONIC, &ts),
             ETIMEDOUT);
-  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, &ts),
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, CLOCK_MONOTONIC, &ts),
             ETIMEDOUT);
 }
 
@@ -198,9 +198,9 @@ static void timedlock_with_deadlock_test() {
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedwrlock(&rwlock, &ts),
             ETIMEDOUT);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_timedrdlock(&rwlock, &ts), 0);
-  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, &ts),
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&rwlock, CLOCK_MONOTONIC, &ts),
             ETIMEDOUT);
-  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, &ts), 0);
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&rwlock, CLOCK_MONOTONIC, &ts), 0);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_unlock(&rwlock), 0);
   ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlock_unlock(&rwlock), 0);
   // notice that ts is already expired, but the following should still succeed.
@@ -379,7 +379,7 @@ static void randomized_thread_operation(SharedData *data, ThreadGuard &guard) {
   }
   case Operation::CLOCK_READ: {
     timespec ts = get_ts();
-    if (LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&data->lock, &ts) == 0) {
+    if (LIBC_NAMESPACE::pthread_rwlock_clockrdlock(&data->lock, CLOCK_MONOTONIC, &ts) == 0) {
       read_ops();
       LIBC_NAMESPACE::pthread_rwlock_unlock(&data->lock);
     }
@@ -387,7 +387,7 @@ static void randomized_thread_operation(SharedData *data, ThreadGuard &guard) {
   }
   case Operation::CLOCK_WRITE: {
     timespec ts = get_ts();
-    if (LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&data->lock, &ts) == 0) {
+    if (LIBC_NAMESPACE::pthread_rwlock_clockwrlock(&data->lock, CLOCK_MONOTONIC, &ts) == 0) {
       write_ops();
       LIBC_NAMESPACE::pthread_rwlock_unlock(&data->lock);
     }



More information about the libc-commits mailing list