[libc-commits] [libc] [libc][WIP] add `pthread_cond_*` public interface (PR #193656)
Schrodinger ZHU Yifan via libc-commits
libc-commits at lists.llvm.org
Wed Apr 22 20:58:46 PDT 2026
https://github.com/SchrodingerZhu created https://github.com/llvm/llvm-project/pull/193656
This patch adds pthread_cond_* entrypoints and related types.
Assisted-by: Codex with gpt-5.4 high fast
>From a3b3eca52081ea7f3decf3c4c96dc451c27319d1 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Wed, 22 Apr 2026 23:56:49 -0400
Subject: [PATCH] [libc][WIP] add `pthread_cond_*` public interface
This patch adds pthread_cond_* entrypoints and related types.
Assisted-by: Codex with gpt-5.4 high fast
---
libc/config/linux/x86_64/entrypoints.txt | 2 +
libc/include/CMakeLists.txt | 2 +
.../include/llvm-libc-macros/pthread-macros.h | 6 +++
libc/include/llvm-libc-types/CMakeLists.txt | 1 +
libc/include/llvm-libc-types/pthread_cond_t.h | 26 ++++++++++
libc/include/pthread.yaml | 12 +++++
libc/include/sys/types.yaml | 1 +
libc/src/__support/threads/CndVar.h | 12 +++--
libc/src/pthread/CMakeLists.txt | 28 +++++++++++
libc/src/pthread/pthread_cond_destroy.cpp | 31 ++++++++++++
libc/src/pthread/pthread_cond_destroy.h | 21 ++++++++
libc/src/pthread/pthread_cond_init.cpp | 49 +++++++++++++++++++
libc/src/pthread/pthread_cond_init.h | 23 +++++++++
13 files changed, 211 insertions(+), 3 deletions(-)
create mode 100644 libc/include/llvm-libc-types/pthread_cond_t.h
create mode 100644 libc/src/pthread/pthread_cond_destroy.cpp
create mode 100644 libc/src/pthread/pthread_cond_destroy.h
create mode 100644 libc/src/pthread/pthread_cond_init.cpp
create mode 100644 libc/src/pthread/pthread_cond_init.h
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index f67d658d0b176..2ba35d84e603f 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1190,6 +1190,8 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.pthread.pthread_condattr_init
libc.src.pthread.pthread_condattr_setclock
libc.src.pthread.pthread_condattr_setpshared
+ libc.src.pthread.pthread_cond_destroy
+ libc.src.pthread.pthread_cond_init
libc.src.pthread.pthread_create
libc.src.pthread.pthread_detach
libc.src.pthread.pthread_equal
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 67f8009d8b099..82a2b71d6311b 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -447,6 +447,7 @@ add_header_macro(
.llvm-libc-types.__pthread_start_t
.llvm-libc-types.__pthread_tss_dtor_t
.llvm-libc-types.pthread_attr_t
+ .llvm-libc-types.pthread_cond_t
.llvm-libc-types.pthread_condattr_t
.llvm-libc-types.pthread_key_t
.llvm-libc-types.pthread_barrier_t
@@ -789,6 +790,7 @@ add_header_macro(
.llvm-libc-types.off_t
.llvm-libc-types.pid_t
.llvm-libc-types.pthread_attr_t
+ .llvm-libc-types.pthread_cond_t
.llvm-libc-types.pthread_key_t
.llvm-libc-types.pthread_mutex_t
.llvm-libc-types.pthread_mutexattr_t
diff --git a/libc/include/llvm-libc-macros/pthread-macros.h b/libc/include/llvm-libc-macros/pthread-macros.h
index e6ade6507e070..34082bed32dff 100644
--- a/libc/include/llvm-libc-macros/pthread-macros.h
+++ b/libc/include/llvm-libc-macros/pthread-macros.h
@@ -45,6 +45,12 @@
}
#endif
+#define PTHREAD_COND_INITIALIZER \
+ { \
+ /* .__waiter_queue = */ {NULL, NULL}, /* .__futex = */ {0}, \
+ /* .__shared = */ {0}, /* .__padding = */ {0}, \
+ }
+
#define PTHREAD_RWLOCK_INITIALIZER \
{ \
/* .__raw = */ { \
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 6c2a001103250..4cd889e4789a2 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -72,6 +72,7 @@ add_header(posix_spawn_file_actions_t HDR posix_spawn_file_actions_t.h)
add_header(posix_spawnattr_t HDR posix_spawnattr_t.h)
add_header(posix_tnode HDR posix_tnode.h)
add_header(pthread_attr_t HDR pthread_attr_t.h DEPENDS .size_t)
+add_header(pthread_cond_t HDR pthread_cond_t.h DEPENDS .__futex_word .size_t)
add_header(pthread_condattr_t HDR pthread_condattr_t.h DEPENDS .clockid_t)
add_header(pthread_key_t HDR pthread_key_t.h)
add_header(pthread_mutex_t HDR pthread_mutex_t.h DEPENDS .__futex_word .__mutex_type)
diff --git a/libc/include/llvm-libc-types/pthread_cond_t.h b/libc/include/llvm-libc-types/pthread_cond_t.h
new file mode 100644
index 0000000000000..77785d325f113
--- /dev/null
+++ b/libc/include/llvm-libc-types/pthread_cond_t.h
@@ -0,0 +1,26 @@
+//===-- Definition of pthread_cond_t type ---------------------------------===//
+//
+// 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_TYPES_PTHREAD_COND_T_H
+#define LLVM_LIBC_TYPES_PTHREAD_COND_T_H
+
+#include "__futex_word.h"
+#include "size_t.h"
+
+typedef struct {
+ union {
+ void *__waiter_queue[2];
+ size_t __waiter_size;
+ };
+ __futex_word __futex;
+ char __shared;
+ char __is_realtime;
+ char __padding[2];
+} pthread_cond_t;
+
+#endif // LLVM_LIBC_TYPES_PTHREAD_COND_T_H
diff --git a/libc/include/pthread.yaml b/libc/include/pthread.yaml
index 782a37c8ffad2..8b45c8431b2d0 100644
--- a/libc/include/pthread.yaml
+++ b/libc/include/pthread.yaml
@@ -30,6 +30,8 @@ macros:
macro_header: pthread-macros.h
- macro_name: "PTHREAD_MUTEX_INITIALIZER"
macro_header: pthread-macros.h
+ - macro_name: "PTHREAD_COND_INITIALIZER"
+ macro_header: pthread-macros.h
- macro_name: "PTHREAD_RWLOCK_INITIALIZER"
macro_header: pthread-macros.h
- macro_name: "PTHREAD_STACK_MIN"
@@ -56,6 +58,7 @@ types:
- type_name: pthread_barrier_t
- type_name: pthread_barrierattr_t
- type_name: pthread_key_t
+ - type_name: pthread_cond_t
- type_name: pthread_condattr_t
- type_name: pthread_rwlock_t
- type_name: pthread_rwlockattr_t
@@ -156,6 +159,15 @@ functions:
arguments:
- type: pthread_condattr_t *
- type: int
+ - name: pthread_cond_destroy
+ return_type: int
+ arguments:
+ - type: pthread_cond_t *
+ - name: pthread_cond_init
+ return_type: int
+ arguments:
+ - type: pthread_cond_t *__restrict
+ - type: const pthread_condattr_t *__restrict
- name: pthread_create
return_type: int
arguments:
diff --git a/libc/include/sys/types.yaml b/libc/include/sys/types.yaml
index 126c597b30353..cdc9602520a0b 100644
--- a/libc/include/sys/types.yaml
+++ b/libc/include/sys/types.yaml
@@ -14,6 +14,7 @@ types:
- type_name: off_t
- type_name: pid_t
- type_name: pthread_attr_t
+ - type_name: pthread_cond_t
- type_name: pthread_condattr_t
- type_name: pthread_key_t
- type_name: pthread_mutex_t
diff --git a/libc/src/__support/threads/CndVar.h b/libc/src/__support/threads/CndVar.h
index e1dd4db894632..09487c808e052 100644
--- a/libc/src/__support/threads/CndVar.h
+++ b/libc/src/__support/threads/CndVar.h
@@ -164,7 +164,8 @@ class CndVar {
Futex shared_futex;
};
- bool is_shared;
+ const bool is_shared;
+ const bool is_realtime;
LIBC_INLINE void notify(bool is_broadcast) {
if (LIBC_UNLIKELY(is_shared)) {
@@ -225,8 +226,9 @@ class CndVar {
}
public:
- LIBC_INLINE constexpr CndVar(bool is_shared)
- : waiter_queue{}, queue_lock{}, is_shared(is_shared) {
+ LIBC_INLINE constexpr CndVar(bool is_shared, bool is_realtime = false)
+ : waiter_queue{}, queue_lock{}, is_shared(is_shared),
+ is_realtime(is_realtime) {
if (is_shared) {
new (&shared_waiters) cpp::Atomic<size_t>(0);
new (&shared_futex) Futex(0);
@@ -244,6 +246,10 @@ class CndVar {
waiter_queue.next = nullptr;
}
+ // The is_realtime field is just a field we spared for pthread_cond_t
+ // It is not used in wait directly.
+ LIBC_INLINE bool default_clock_is_realtime() const { return is_realtime; }
+
// TODO: register callback for pthread cancellation
LIBC_INLINE CndVarResult wait(Mutex *mutex,
cpp::optional<Timeout> timeout = cpp::nullopt) {
diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt
index 943b29d99f9ee..203420c1b058d 100644
--- a/libc/src/pthread/CMakeLists.txt
+++ b/libc/src/pthread/CMakeLists.txt
@@ -191,6 +191,34 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ pthread_cond_destroy
+ SRCS
+ pthread_cond_destroy.cpp
+ HDRS
+ pthread_cond_destroy.h
+ DEPENDS
+ libc.include.llvm-libc-types.pthread_cond_t
+ libc.src.__support.threads.CndVar
+)
+
+add_entrypoint_object(
+ pthread_cond_init
+ SRCS
+ pthread_cond_init.cpp
+ HDRS
+ pthread_cond_init.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.time_macros
+ libc.include.llvm-libc-macros.pthread_macros
+ libc.include.llvm-libc-types.pthread_cond_t
+ libc.include.llvm-libc-types.pthread_condattr_t
+ libc.src.__support.CPP.new
+ libc.src.__support.macros.null_check
+ libc.src.__support.threads.CndVar
+ )
+
add_header_library(
pthread_mutexattr
HDRS
diff --git a/libc/src/pthread/pthread_cond_destroy.cpp b/libc/src/pthread/pthread_cond_destroy.cpp
new file mode 100644
index 0000000000000..b35086e2bb096
--- /dev/null
+++ b/libc/src/pthread/pthread_cond_destroy.cpp
@@ -0,0 +1,31 @@
+//===-- Implementation of the pthread_cond_destroy 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 "pthread_cond_destroy.h"
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/threads/CndVar.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static_assert(
+ sizeof(CndVar) == sizeof(pthread_cond_t) &&
+ alignof(CndVar) == alignof(pthread_cond_t),
+ "The public pthread_cond_t type must be of the same size and alignment "
+ "as the internal condition variable type.");
+
+LLVM_LIBC_FUNCTION(int, pthread_cond_destroy, (pthread_cond_t * cond)) {
+ // TODO: use cpp:start_lifetime_as once
+ // https://github.com/llvm/llvm-project/pull/193326 is merged
+ auto *cndvar = reinterpret_cast<CndVar *>(cond);
+ cndvar->reset();
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/pthread/pthread_cond_destroy.h b/libc/src/pthread/pthread_cond_destroy.h
new file mode 100644
index 0000000000000..723f184faec05
--- /dev/null
+++ b/libc/src/pthread/pthread_cond_destroy.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for pthread_cond_destroy ---------*- 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_COND_DESTROY_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_COND_DESTROY_H
+
+#include "include/llvm-libc-types/pthread_cond_t.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int pthread_cond_destroy(pthread_cond_t *cond);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_COND_DESTROY_H
diff --git a/libc/src/pthread/pthread_cond_init.cpp b/libc/src/pthread/pthread_cond_init.cpp
new file mode 100644
index 0000000000000..62b050a6c8ce2
--- /dev/null
+++ b/libc/src/pthread/pthread_cond_init.cpp
@@ -0,0 +1,49 @@
+//===-- Implementation of the pthread_cond_init 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 "pthread_cond_init.h"
+
+#include "include/llvm-libc-macros/pthread-macros.h"
+#include "src/__support/CPP/new.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+#include "src/__support/threads/CndVar.h"
+
+#include "hdr/errno_macros.h" // EINVAL
+#include "hdr/time_macros.h" // CLOCK_MONOTONIC, CLOCK_REALTIME
+
+namespace LIBC_NAMESPACE_DECL {
+
+static_assert(
+ sizeof(CndVar) == sizeof(pthread_cond_t) &&
+ alignof(CndVar) == alignof(pthread_cond_t),
+ "The public pthread_cond_t type must be of the same size and alignment "
+ "as the internal condition variable type.");
+
+LLVM_LIBC_FUNCTION(int, pthread_cond_init,
+ (pthread_cond_t *__restrict cond,
+ const pthread_condattr_t *__restrict attr)) {
+ LIBC_CRASH_ON_NULLPTR(cond);
+ // POSIX.1 says that CLOCK_REALTIME shall be used if the clock is not
+ // monotonic explicitly.
+ pthread_condattr_t condattr{
+ /*clock=*/CLOCK_REALTIME,
+ /*pshared=*/PTHREAD_PROCESS_PRIVATE,
+ };
+ if (attr)
+ condattr = *attr;
+
+ // POSIX.1 does not specify behavior for invalid clock values.
+ bool is_shared = condattr.pshared == PTHREAD_PROCESS_SHARED;
+ bool is_realtime = condattr.clock == CLOCK_REALTIME;
+ new (cond) CndVar(is_shared, is_realtime);
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/pthread/pthread_cond_init.h b/libc/src/pthread/pthread_cond_init.h
new file mode 100644
index 0000000000000..4c334fdfd66b6
--- /dev/null
+++ b/libc/src/pthread/pthread_cond_init.h
@@ -0,0 +1,23 @@
+//===-- Implementation header for pthread_cond_init -------------*- 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_COND_INIT_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_COND_INIT_H
+
+#include "include/llvm-libc-types/pthread_cond_t.h"
+#include "include/llvm-libc-types/pthread_condattr_t.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int pthread_cond_init(pthread_cond_t *__restrict cond,
+ const pthread_condattr_t *__restrict attr);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_COND_INIT_H
More information about the libc-commits
mailing list