diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index a8e28992766712..4a6d9659380321 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -670,8 +670,10 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.pthread.pthread_mutexattr_settype libc.src.pthread.pthread_once libc.src.pthread.pthread_rwlockattr_destroy + libc.src.pthread.pthread_rwlockattr_getkind_np libc.src.pthread.pthread_rwlockattr_getpshared libc.src.pthread.pthread_rwlockattr_init + libc.src.pthread.pthread_rwlockattr_setkind_np libc.src.pthread.pthread_rwlockattr_setpshared libc.src.pthread.pthread_setspecific diff --git a/libc/include/llvm-libc-types/pthread_rwlockattr_t.h b/libc/include/llvm-libc-types/pthread_rwlockattr_t.h index a63de4f7b438c1..397c8440402a12 100644 --- a/libc/include/llvm-libc-types/pthread_rwlockattr_t.h +++ b/libc/include/llvm-libc-types/pthread_rwlockattr_t.h @@ -10,6 +10,7 @@ typedef struct { int pshared; + int pref; } pthread_rwlockattr_t; #endif // LLVM_LIBC_TYPES_PTHREAD_RWLOCKATTR_T_H diff --git a/libc/include/pthread.h.def b/libc/include/pthread.h.def index a94d770657e100..d41273b5590eaa 100644 --- a/libc/include/pthread.h.def +++ b/libc/include/pthread.h.def @@ -38,6 +38,11 @@ enum { #define PTHREAD_PROCESS_PRIVATE 0 #define PTHREAD_PROCESS_SHARED 1 +#define PTHREAD_RWLOCK_PREFER_READER_NP 0 +#define PTHREAD_RWLOCK_PREFER_WRITER_NP 1 +#define PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 2 + + %%public_api() #endif // LLVM_LIBC_PTHREAD_H diff --git a/libc/spec/posix.td b/libc/spec/posix.td index d428d54e32a331..e8a6dff25d7300 100644 --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -1229,6 +1229,11 @@ def POSIX : StandardSpec<"POSIX"> { RetValSpec, [ArgSpec] >, + FunctionSpec< + "pthread_rwlockattr_getkind_np", + RetValSpec, + [ArgSpec, ArgSpec] + >, FunctionSpec< "pthread_rwlockattr_getpshared", RetValSpec, @@ -1239,6 +1244,11 @@ def POSIX : StandardSpec<"POSIX"> { RetValSpec, [ArgSpec] >, + FunctionSpec< + "pthread_rwlockattr_setkind_np", + RetValSpec, + [ArgSpec, ArgSpec] + >, FunctionSpec< "pthread_rwlockattr_setpshared", RetValSpec, diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt index c57475c9114fa6..e5bebb63c64013 100644 --- a/libc/src/pthread/CMakeLists.txt +++ b/libc/src/pthread/CMakeLists.txt @@ -470,6 +470,16 @@ add_entrypoint_object( libc.include.pthread ) +add_entrypoint_object( + pthread_rwlockattr_getkind_np + SRCS + pthread_rwlockattr_getkind_np.cpp + HDRS + pthread_rwlockattr_getkind_np.h + DEPENDS + libc.include.pthread +) + add_entrypoint_object( pthread_rwlockattr_getpshared SRCS @@ -490,6 +500,17 @@ add_entrypoint_object( libc.include.pthread ) +add_entrypoint_object( + pthread_rwlockattr_setkind_np + SRCS + pthread_rwlockattr_setkind_np.cpp + HDRS + pthread_rwlockattr_setkind_np.h + DEPENDS + libc.include.pthread + libc.include.errno +) + add_entrypoint_object( pthread_rwlockattr_setpshared SRCS diff --git a/libc/src/pthread/pthread_rwlockattr_getkind_np.cpp b/libc/src/pthread/pthread_rwlockattr_getkind_np.cpp new file mode 100644 index 00000000000000..0c821797b42cae --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_getkind_np.cpp @@ -0,0 +1,24 @@ +//===-- Implementation of the pthread_rwlockattr_getkind_np ---------------===// +// +// 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 "pthread_rwlockattr_getkind_np.h" + +#include "src/__support/common.h" + +#include // pthread_rwlockattr_t + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_getkind_np, + (const pthread_rwlockattr_t *__restrict attr, + int *__restrict pref)) { + *pref = attr->pref; + return 0; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/pthread/pthread_rwlockattr_getkind_np.h b/libc/src/pthread/pthread_rwlockattr_getkind_np.h new file mode 100644 index 00000000000000..51f633cd559d4b --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_getkind_np.h @@ -0,0 +1,21 @@ +//===-- Implementation header for pthread_rwlockattr_getkind_np -*- 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_RWLOCKATTR_GETKIND_NP_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_GETKIND_NP_H + +#include + +namespace LIBC_NAMESPACE { + +int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t *__restrict attr, + int *__restrict pref); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_GETKIND_NP_H diff --git a/libc/src/pthread/pthread_rwlockattr_init.cpp b/libc/src/pthread/pthread_rwlockattr_init.cpp index 7971f1714db484..bbc89555c6c1cd 100644 --- a/libc/src/pthread/pthread_rwlockattr_init.cpp +++ b/libc/src/pthread/pthread_rwlockattr_init.cpp @@ -17,6 +17,7 @@ namespace LIBC_NAMESPACE { LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_init, (pthread_rwlockattr_t * attr)) { attr->pshared = PTHREAD_PROCESS_PRIVATE; + attr->pref = PTHREAD_RWLOCK_PREFER_READER_NP; return 0; } diff --git a/libc/src/pthread/pthread_rwlockattr_setkind_np.cpp b/libc/src/pthread/pthread_rwlockattr_setkind_np.cpp new file mode 100644 index 00000000000000..47fbf2a851e502 --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_setkind_np.cpp @@ -0,0 +1,30 @@ +//===-- Implementation of the pthread_rwlockattr_setkind_np ---------------===// +// +// 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 "pthread_rwlockattr_setkind_np.h" + +#include "src/__support/common.h" + +#include +#include // pthread_rwlockattr_t + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_setkind_np, + (pthread_rwlockattr_t * attr, int pref)) { + + if (pref != PTHREAD_RWLOCK_PREFER_READER_NP && + pref != PTHREAD_RWLOCK_PREFER_WRITER_NP && + pref != PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) + return EINVAL; + + attr->pref = pref; + return 0; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/pthread/pthread_rwlockattr_setkind_np.h b/libc/src/pthread/pthread_rwlockattr_setkind_np.h new file mode 100644 index 00000000000000..00ef8e1bbe0090 --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_setkind_np.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pthread_rwlockattr_setkind_np -*- 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_RWLOCKATTR_SETKIND_NP_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_SETKIND_NP_H + +#include + +namespace LIBC_NAMESPACE { + +int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *attr, int pref); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_SETKIND_NP_H diff --git a/libc/test/src/pthread/CMakeLists.txt b/libc/test/src/pthread/CMakeLists.txt index ea75e65f57c9eb..0eeec445d5f49c 100644 --- a/libc/test/src/pthread/CMakeLists.txt +++ b/libc/test/src/pthread/CMakeLists.txt @@ -68,7 +68,9 @@ add_libc_unittest( libc.include.errno libc.include.pthread libc.src.pthread.pthread_rwlockattr_destroy + libc.src.pthread.pthread_rwlockattr_getkind_np libc.src.pthread.pthread_rwlockattr_getpshared libc.src.pthread.pthread_rwlockattr_init + libc.src.pthread.pthread_rwlockattr_setkind_np libc.src.pthread.pthread_rwlockattr_setpshared ) diff --git a/libc/test/src/pthread/pthread_rwlockattr_test.cpp b/libc/test/src/pthread/pthread_rwlockattr_test.cpp index 6e5ae70df7343f..3791f568e2228d 100644 --- a/libc/test/src/pthread/pthread_rwlockattr_test.cpp +++ b/libc/test/src/pthread/pthread_rwlockattr_test.cpp @@ -8,8 +8,10 @@ #include "include/llvm-libc-macros/generic-error-number-macros.h" // EINVAL #include "src/pthread/pthread_rwlockattr_destroy.h" +#include "src/pthread/pthread_rwlockattr_getkind_np.h" #include "src/pthread/pthread_rwlockattr_getpshared.h" #include "src/pthread/pthread_rwlockattr_init.h" +#include "src/pthread/pthread_rwlockattr_setkind_np.h" #include "src/pthread/pthread_rwlockattr_setpshared.h" #include "test/UnitTest/Test.h" @@ -25,40 +27,61 @@ TEST(LlvmLibcPThreadRWLockAttrTest, InitAndDestroy) { TEST(LlvmLibcPThreadRWLockAttrTest, GetDefaultValues) { pthread_rwlockattr_t attr; - // Invalid value. + // Invalid values. int pshared = 42; + int pref = 1337; ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0); ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getpshared(&attr, &pshared), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getkind_np(&attr, &pref), 0); + ASSERT_EQ(pshared, PTHREAD_PROCESS_PRIVATE); + ASSERT_EQ(pref, PTHREAD_RWLOCK_PREFER_READER_NP); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0); } TEST(LlvmLibcPThreadRWLockAttrTest, SetGoodValues) { pthread_rwlockattr_t attr; - // Invalid value. + // Invalid values. int pshared = 42; + int pref = 1337; ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0); ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_setpshared( &attr, PTHREAD_PROCESS_SHARED), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_setkind_np( + &attr, PTHREAD_RWLOCK_PREFER_WRITER_NP), + 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getpshared(&attr, &pshared), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getkind_np(&attr, &pref), 0); + ASSERT_EQ(pshared, PTHREAD_PROCESS_SHARED); + ASSERT_EQ(pref, PTHREAD_RWLOCK_PREFER_WRITER_NP); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0); } TEST(LlvmLibcPThreadRWLockAttrTest, SetBadValues) { pthread_rwlockattr_t attr; - // Invalid value. + // Invalid values. int pshared = 42; + int pref = 1337; ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0); ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_setpshared(&attr, pshared), EINVAL); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_setkind_np(&attr, pref), EINVAL); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getpshared(&attr, &pshared), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getkind_np(&attr, &pref), 0); + ASSERT_EQ(pshared, PTHREAD_PROCESS_PRIVATE); + ASSERT_EQ(pref, PTHREAD_RWLOCK_PREFER_READER_NP); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0); }