[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 02:57:28 PDT 2024
https://github.com/Eric977 updated https://github.com/llvm/llvm-project/pull/100543
>From 79345936aca219199a0fbbd2a7d4d7428da8cbeb 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 77da994d8dfdf..4e7b23225f54e 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 3ec166fc0096c..04b8b3bc4ce39 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 fe3bd7a757e8f..fa656d946eceb 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 d324b1fd3d7174c1ead39f49a7c60d2d6a15dc3a 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 1878b1ee2ae41..1b7e18e999600 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -1325,6 +1325,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 bdeaaa29da66ac6a58a0d126fe23039c3b0db054 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 dfbabc6bba11cc73ea3aa34c3d50e8c8a3487299 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 3faae3134ce2a..9f50545d745d6 100644
--- a/libc/docs/dev/undefined_behavior.rst
+++ b/libc/docs/dev/undefined_behavior.rst
@@ -93,3 +93,8 @@ direction in this case.
Non-const Constant Return Values
--------------------------------
Some libc functions, like ``dlerror()``, return ``char *`` instead of ``const char *`` and then tell the caller they promise not to to modify this value. Any modification of this value is undefined behavior.
+
+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