Skip to content

Commit 44df89c

Browse files
authored
[libc] add pthread_rwlock_clockrdlock and pthread_rwlock_clockwrlock … (#100543)
1 parent a7e8bdd commit 44df89c

File tree

13 files changed

+267
-3
lines changed

13 files changed

+267
-3
lines changed

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,8 @@ if(LLVM_LIBC_FULL_BUILD)
692692
libc.src.pthread.pthread_mutexattr_setrobust
693693
libc.src.pthread.pthread_mutexattr_settype
694694
libc.src.pthread.pthread_once
695+
libc.src.pthread.pthread_rwlock_clockrdlock
696+
libc.src.pthread.pthread_rwlock_clockwrlock
695697
libc.src.pthread.pthread_rwlock_destroy
696698
libc.src.pthread.pthread_rwlock_init
697699
libc.src.pthread.pthread_rwlock_rdlock

libc/config/linux/riscv/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,8 @@ if(LLVM_LIBC_FULL_BUILD)
703703
libc.src.pthread.pthread_mutexattr_setrobust
704704
libc.src.pthread.pthread_mutexattr_settype
705705
libc.src.pthread.pthread_once
706+
libc.src.pthread.pthread_rwlock_clockrdlock
707+
libc.src.pthread.pthread_rwlock_clockwrlock
706708
libc.src.pthread.pthread_rwlock_destroy
707709
libc.src.pthread.pthread_rwlock_init
708710
libc.src.pthread.pthread_rwlock_rdlock

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,8 @@ if(LLVM_LIBC_FULL_BUILD)
790790
libc.src.pthread.pthread_mutexattr_setrobust
791791
libc.src.pthread.pthread_mutexattr_settype
792792
libc.src.pthread.pthread_once
793+
libc.src.pthread.pthread_rwlock_clockrdlock
794+
libc.src.pthread.pthread_rwlock_clockwrlock
793795
libc.src.pthread.pthread_rwlock_destroy
794796
libc.src.pthread.pthread_rwlock_init
795797
libc.src.pthread.pthread_rwlock_rdlock

libc/docs/dev/undefined_behavior.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,8 @@ direction in this case.
9393
Non-const Constant Return Values
9494
--------------------------------
9595
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.
96+
97+
Unrecognized ``clockid_t`` values for ``pthread_rwlock_clock*`` APIs
98+
----------------------------------------------------------------------
99+
POSIX.1-2024 only demands support for ``CLOCK_REALTIME`` and ``CLOCK_MONOTONIC``. Currently,
100+
as in LLVM libc, if other clock ids are used, they will be treated as monotonic clocks.

libc/newhdrgen/yaml/pthread.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,20 @@ functions:
370370
arguments:
371371
- type: pthread_rwlock_t *__restrict
372372
- type: const struct timespec *__restrict
373+
- name: pthread_rwlock_clockrdlock
374+
standards: POSIX
375+
return_type: int
376+
arguments:
377+
- type: pthread_rwlock_t *__restrict
378+
- type: clockid_t
379+
- type: const struct timespec *__restrict
380+
- name: pthread_rwlock_clockwrlock
381+
standards: POSIX
382+
return_type: int
383+
arguments:
384+
- type: pthread_rwlock_t *__restrict
385+
- type: clockid_t
386+
- type: const struct timespec *__restrict
373387
- name: pthread_rwlock_rdlock
374388
standards: POSIX
375389
return_type: int

libc/spec/posix.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,16 @@ def POSIX : StandardSpec<"POSIX"> {
13251325
RetValSpec<IntType>,
13261326
[ArgSpec<RestrictedPThreadRWLockTPtr>, ArgSpec<ConstRestrictStructTimeSpecPtr>]
13271327
>,
1328+
FunctionSpec<
1329+
"pthread_rwlock_clockrdlock",
1330+
RetValSpec<IntType>,
1331+
[ArgSpec<RestrictedPThreadRWLockTPtr>, ArgSpec<ClockIdT>, ArgSpec<ConstRestrictStructTimeSpecPtr>]
1332+
>,
1333+
FunctionSpec<
1334+
"pthread_rwlock_clockwrlock",
1335+
RetValSpec<IntType>,
1336+
[ArgSpec<RestrictedPThreadRWLockTPtr>, ArgSpec<ClockIdT>, ArgSpec<ConstRestrictStructTimeSpecPtr>]
1337+
>,
13281338
FunctionSpec<
13291339
"pthread_rwlock_rdlock",
13301340
RetValSpec<IntType>,

libc/src/pthread/CMakeLists.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,28 @@ add_entrypoint_object(
556556
libc.src.__support.threads.linux.rwlock
557557
)
558558

559+
add_entrypoint_object(
560+
pthread_rwlock_clockrdlock
561+
SRCS
562+
pthread_rwlock_clockrdlock.cpp
563+
HDRS
564+
pthread_rwlock_clockrdlock.h
565+
DEPENDS
566+
libc.include.pthread
567+
libc.src.__support.threads.linux.rwlock
568+
)
569+
570+
add_entrypoint_object(
571+
pthread_rwlock_clockwrlock
572+
SRCS
573+
pthread_rwlock_clockwrlock.cpp
574+
HDRS
575+
pthread_rwlock_clockwrlock.h
576+
DEPENDS
577+
libc.include.pthread
578+
libc.src.__support.threads.linux.rwlock
579+
)
580+
559581
add_entrypoint_object(
560582
pthread_rwlock_timedrdlock
561583
SRCS
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===-- Implementation of the Rwlock's clockrdlock function ---------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/pthread/pthread_rwlock_clockrdlock.h"
10+
11+
#include "hdr/errno_macros.h"
12+
#include "src/__support/common.h"
13+
#include "src/__support/macros/config.h"
14+
#include "src/__support/threads/linux/rwlock.h"
15+
16+
#include <pthread.h>
17+
18+
namespace LIBC_NAMESPACE_DECL {
19+
20+
static_assert(
21+
sizeof(RwLock) == sizeof(pthread_rwlock_t) &&
22+
alignof(RwLock) == alignof(pthread_rwlock_t),
23+
"The public pthread_rwlock_t type must be of the same size and alignment "
24+
"as the internal rwlock type.");
25+
26+
LLVM_LIBC_FUNCTION(int, pthread_rwlock_clockrdlock,
27+
(pthread_rwlock_t * rwlock, clockid_t clockid,
28+
const timespec *abstime)) {
29+
if (!rwlock)
30+
return EINVAL;
31+
if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_REALTIME)
32+
return EINVAL;
33+
bool is_realtime = (clockid == CLOCK_REALTIME);
34+
RwLock *rw = reinterpret_cast<RwLock *>(rwlock);
35+
LIBC_ASSERT(abstime && "clockrdlock called with a null timeout");
36+
auto timeout = internal::AbsTimeout::from_timespec(
37+
*abstime, /*is_realtime=*/is_realtime);
38+
if (LIBC_LIKELY(timeout.has_value()))
39+
return static_cast<int>(rw->read_lock(timeout.value()));
40+
41+
switch (timeout.error()) {
42+
case internal::AbsTimeout::Error::Invalid:
43+
return EINVAL;
44+
case internal::AbsTimeout::Error::BeforeEpoch:
45+
return ETIMEDOUT;
46+
}
47+
__builtin_unreachable();
48+
}
49+
50+
} // namespace LIBC_NAMESPACE_DECL
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Implementation header for Rwlock's clockrdlock function --*- C++-*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCK_CLOCKRDLOCK_H
10+
#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCK_CLOCKRDLOCK_H
11+
12+
#include "src/__support/macros/config.h"
13+
#include <pthread.h>
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
int pthread_rwlock_clockrdlock(pthread_rwlock_t *__restrict rwlock,
18+
clockid_t clockid,
19+
const timespec *__restrict abstime);
20+
21+
} // namespace LIBC_NAMESPACE_DECL
22+
23+
#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCK_CLOCKRDLOCK_H
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===-- Implementation of the Rwlock's clockwrlock function----------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/pthread/pthread_rwlock_clockwrlock.h"
10+
11+
#include "hdr/errno_macros.h"
12+
#include "src/__support/common.h"
13+
#include "src/__support/macros/config.h"
14+
#include "src/__support/threads/linux/rwlock.h"
15+
#include "src/__support/time/linux/abs_timeout.h"
16+
17+
#include <pthread.h>
18+
19+
namespace LIBC_NAMESPACE_DECL {
20+
21+
static_assert(
22+
sizeof(RwLock) == sizeof(pthread_rwlock_t) &&
23+
alignof(RwLock) == alignof(pthread_rwlock_t),
24+
"The public pthread_rwlock_t type must be of the same size and alignment "
25+
"as the internal rwlock type.");
26+
27+
LLVM_LIBC_FUNCTION(int, pthread_rwlock_clockwrlock,
28+
(pthread_rwlock_t * rwlock, clockid_t clockid,
29+
const timespec *abstime)) {
30+
if (!rwlock)
31+
return EINVAL;
32+
if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_REALTIME)
33+
return EINVAL;
34+
bool is_realtime = (clockid == CLOCK_REALTIME);
35+
RwLock *rw = reinterpret_cast<RwLock *>(rwlock);
36+
LIBC_ASSERT(abstime && "clockwrlock called with a null timeout");
37+
auto timeout = internal::AbsTimeout::from_timespec(
38+
*abstime, /*is_realtime=*/is_realtime);
39+
if (LIBC_LIKELY(timeout.has_value()))
40+
return static_cast<int>(rw->write_lock(timeout.value()));
41+
42+
switch (timeout.error()) {
43+
case internal::AbsTimeout::Error::Invalid:
44+
return EINVAL;
45+
case internal::AbsTimeout::Error::BeforeEpoch:
46+
return ETIMEDOUT;
47+
}
48+
__builtin_unreachable();
49+
}
50+
51+
} // namespace LIBC_NAMESPACE_DECL

0 commit comments

Comments
 (0)