From 2d5b880393cbd430f088da8146a41f68d490c6dc Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Thu, 10 Jul 2025 21:01:39 +0000 Subject: [PATCH 01/16] Barrier class implemented; begin work on public functions --- libc/include/llvm-libc-types/CMakeLists.txt | 2 + .../llvm-libc-types/pthread_barrier_t.h | 16 +++++ .../llvm-libc-types/pthread_barrierattr_t.h | 16 +++++ libc/src/__support/threads/barrier.cpp | 70 +++++++++++++++++++ libc/src/__support/threads/barrier.h | 39 +++++++++++ libc/src/pthread/pthread_barrier_destroy.cpp | 24 +++++++ libc/src/pthread/pthread_barrier_destroy.h | 21 ++++++ libc/src/pthread/pthread_barrier_init.cpp | 32 +++++++++ libc/src/pthread/pthread_barrier_init.h | 23 ++++++ libc/src/pthread/pthread_barrier_wait.cpp | 27 +++++++ libc/src/pthread/pthread_barrier_wait.h | 21 ++++++ .../src/pthread/pthread_barrier_test.cpp | 35 ++++++++++ 12 files changed, 326 insertions(+) create mode 100644 libc/include/llvm-libc-types/pthread_barrier_t.h create mode 100644 libc/include/llvm-libc-types/pthread_barrierattr_t.h create mode 100644 libc/src/__support/threads/barrier.cpp create mode 100644 libc/src/__support/threads/barrier.h create mode 100644 libc/src/pthread/pthread_barrier_destroy.cpp create mode 100644 libc/src/pthread/pthread_barrier_destroy.h create mode 100644 libc/src/pthread/pthread_barrier_init.cpp create mode 100644 libc/src/pthread/pthread_barrier_init.h create mode 100644 libc/src/pthread/pthread_barrier_wait.cpp create mode 100644 libc/src/pthread/pthread_barrier_wait.h create mode 100644 libc/test/integration/src/pthread/pthread_barrier_test.cpp diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index b24c97301668a..405c2cd26b863 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -53,6 +53,8 @@ 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) add_header(pthread_mutexattr_t HDR pthread_mutexattr_t.h) +add_header(pthread_barrier_t HDR pthread_barrier_t.h) +add_header(pthread_barrierattr_t HDR pthread_barrierattr_t.h) add_header(pthread_once_t HDR pthread_once_t.h DEPENDS .__futex_word) add_header(pthread_rwlock_t HDR pthread_rwlock_t.h DEPENDS .__futex_word .pid_t) add_header(pthread_rwlockattr_t HDR pthread_rwlockattr_t.h) diff --git a/libc/include/llvm-libc-types/pthread_barrier_t.h b/libc/include/llvm-libc-types/pthread_barrier_t.h new file mode 100644 index 0000000000000..d95477afb226c --- /dev/null +++ b/libc/include/llvm-libc-types/pthread_barrier_t.h @@ -0,0 +1,16 @@ +//===-- Definition of pthread_barrier_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_BARRIER_T_H +#define LLVM_LIBC_TYPES_PTHREAD_BARRIER_T_H + +typedef struct { + char padding[88]; +} pthread_barrier_t; + +#endif // LLVM_LIBC_TYPES_PTHREAD_BARRIER_T_H diff --git a/libc/include/llvm-libc-types/pthread_barrierattr_t.h b/libc/include/llvm-libc-types/pthread_barrierattr_t.h new file mode 100644 index 0000000000000..064be5bfb6721 --- /dev/null +++ b/libc/include/llvm-libc-types/pthread_barrierattr_t.h @@ -0,0 +1,16 @@ +//===-- Definition of pthread_barrierattr_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_BARRIERATTR_T_H +#define LLVM_LIBC_TYPES_PTHREAD_BARRIERATTR_T_H + +typedef struct { + bool pshared; +} pthread_barrierattr_t; + +#endif // LLVM_LIBC_TYPES_PTHREAD_BARRIERATTR_T_H diff --git a/libc/src/__support/threads/barrier.cpp b/libc/src/__support/threads/barrier.cpp new file mode 100644 index 0000000000000..db0e38e9eb71e --- /dev/null +++ b/libc/src/__support/threads/barrier.cpp @@ -0,0 +1,70 @@ +//===-- Linux implementation of the callonce 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/__support/threads/barrier.h" +#include "src/__support/threads/mutex.h" +#include "hdr/errno_macros.h" + +namespace LIBC_NAMESPACE_DECL { + +int Barrier::init(Barrier *b, const pthread_barrierattr_t* attr, unsigned count) { + if (count == 0) + return EINVAL; + + b->expected = count; + b->waiting = 0; + b->blocking = true; + + int err; + err = CndVar::init(&b->entering); + if (err != 0) + return err; + + err = CndVar::init(&b->exiting); + if (err != 0) + return err; + + Mutex::init(&b->m, false, false, false, false); + return 0; +} + +int Barrier::wait() { + m.lock(); + + // if the barrier is emptying out threads, wait until it finishes + while (!blocking) { + entering.wait(&m); + } + waiting++; + + if (waiting == expected) { + // this is the last thread to call wait(), so lets wake everyone up + blocking = false; + waiting--; + exiting.broadcast(); + } else { + // block threads until waiting = expected + while (blocking) { + exiting.wait(&m); + } + } + + // all threads have exited the barrier, lets let the ones waiting to enter + // continue + if (waiting == 0) { + blocking = true; + entering.broadcast(); + } + m.unlock(); +} + +int Barrier::destroy(Barrier *b) { + +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/threads/barrier.h b/libc/src/__support/threads/barrier.h new file mode 100644 index 0000000000000..e46d5b9773a4f --- /dev/null +++ b/libc/src/__support/threads/barrier.h @@ -0,0 +1,39 @@ +//===-- A platform independent abstraction layer for barriers --*- 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___SUPPORT_SRC_THREADS_LINUX_BARRIER_H +#define LLVM_LIBC___SUPPORT_SRC_THREADS_LINUX_BARRIER_H + +#include "src/__support/macros/config.h" +#include "src/__support/threads/CndVar.h" +#include "src/__support/threads/mutex.h" + +namespace LIBC_NAMESPACE_DECL { + +// NOTE: if the size of this class changes, you must ensure that the size of +// pthread_barrier_t (found in include/llvm-libc/types/pthread_barrier_t.h) is +// the same size + +class Barrier { +private: + unsigned expected; + unsigned waiting; + bool blocking; + CndVar entering; + CndVar exiting; + Mutex m; + +public: + static int init(Barrier *b, const pthread_barrierattr_t* attr, unsigned count); + static int destroy(Barrier *b); + int wait(); +}; + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC___SUPPORT_SRC_THREADS_LINUX_BARRIER_H diff --git a/libc/src/pthread/pthread_barrier_destroy.cpp b/libc/src/pthread/pthread_barrier_destroy.cpp new file mode 100644 index 0000000000000..00863f8d6ff6b --- /dev/null +++ b/libc/src/pthread/pthread_barrier_destroy.cpp @@ -0,0 +1,24 @@ +//===-- Linux implementation of the pthread_barrier_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_mutex_init.h" +#include "pthread_mutexattr.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" +#include "src/__support/threads/barrier.h" + +#include + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, pthread_barrier_destroy, (pthread_barrier_t * b)) { + return Barrier::destroy(reinterpret_cast(b)); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/pthread/pthread_barrier_destroy.h b/libc/src/pthread/pthread_barrier_destroy.h new file mode 100644 index 0000000000000..0b1d0f090ec26 --- /dev/null +++ b/libc/src/pthread/pthread_barrier_destroy.h @@ -0,0 +1,21 @@ +//===-- Implementation header for pthread_barrier_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_BARRIER_DESTROY_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_DESTROY_H + +#include "src/__support/macros/config.h" +#include + +namespace LIBC_NAMESPACE_DECL { + +int pthread_barrier_destroy(pthread_barrier_t *b); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_DESTROY_H diff --git a/libc/src/pthread/pthread_barrier_init.cpp b/libc/src/pthread/pthread_barrier_init.cpp new file mode 100644 index 0000000000000..234f58a6c7d62 --- /dev/null +++ b/libc/src/pthread/pthread_barrier_init.cpp @@ -0,0 +1,32 @@ +//===-- Linux implementation of the pthread_barrier_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_mutex_init.h" +#include "pthread_mutexattr.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" +#include "src/__support/threads/barrier.h" + +#include + +namespace LIBC_NAMESPACE_DECL { + +static_assert( + sizeof(Barrier) <= sizeof(pthread_barrier_t), + "The public pthread_barrier_t type cannot accommodate the internal " + "barrier type."); + +LLVM_LIBC_FUNCTION(int, pthread_barrier_init, + (pthread_barrier_t * b, + const pthread_barrierattr_t *__restrict attr, + unsigned count)) { + return Barrier::init(reinterpret_cast(b), attr, count); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/pthread/pthread_barrier_init.h b/libc/src/pthread/pthread_barrier_init.h new file mode 100644 index 0000000000000..ea79df6da7ea9 --- /dev/null +++ b/libc/src/pthread/pthread_barrier_init.h @@ -0,0 +1,23 @@ +//===-- Implementation header for pthread_barrier_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_BARRIER_INIT_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_INIT_H + +#include "src/__support/macros/config.h" +#include + +namespace LIBC_NAMESPACE_DECL { + +int pthread_barrier_init(pthread_barrier_t *b, + const pthread_barrierattr_t *__restrict attr, + unsigned count); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_INIT_H diff --git a/libc/src/pthread/pthread_barrier_wait.cpp b/libc/src/pthread/pthread_barrier_wait.cpp new file mode 100644 index 0000000000000..ba23cc0f4e072 --- /dev/null +++ b/libc/src/pthread/pthread_barrier_wait.cpp @@ -0,0 +1,27 @@ +//===-- Linux implementation of the pthread_barrier_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_mutex_init.h" +#include "pthread_mutexattr.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" +#include "src/__support/threads/barrier.h" + +#include + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, pthread_barrier_wait, + (pthread_barrier_t * b, + const pthread_barrierattr_t *__restrict attr, + unsigned count)) { + return reinterpret_cast(b)->wait(); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/pthread/pthread_barrier_wait.h b/libc/src/pthread/pthread_barrier_wait.h new file mode 100644 index 0000000000000..738ca56bd53e4 --- /dev/null +++ b/libc/src/pthread/pthread_barrier_wait.h @@ -0,0 +1,21 @@ +//===-- Implementation header for pthread_barrier_wait ----------*- 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_BARRIER_WAIT_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_WAIT_H + +#include "src/__support/macros/config.h" +#include + +namespace LIBC_NAMESPACE_DECL { + +int pthread_barrier_wait(pthread_barrier_t *b); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_WAIT_H diff --git a/libc/test/integration/src/pthread/pthread_barrier_test.cpp b/libc/test/integration/src/pthread/pthread_barrier_test.cpp new file mode 100644 index 0000000000000..33d5945a6687d --- /dev/null +++ b/libc/test/integration/src/pthread/pthread_barrier_test.cpp @@ -0,0 +1,35 @@ +//===-- Tests for pthread_barrier_t ---------------------------------------===// +// +// 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_barrier_destroy.h" +#include "src/pthread/pthread_barrier_init.h" +#include "src/pthread/pthread_barrier_wait.h" + +#include "src/pthread/pthread_create.h" + +#include "test/IntegrationTest/test.h" + +#include +#include // uintptr_t + +constexpr int START = 0; +constexpr int MAX = 10000; + +pthread_barrier_t barrier; +static int shared_int = START; + +void increment_shared_counter() { + +} + + + +TEST_MAIN() { + + return 0; +} From cefd7de20b8877741b89c0410e4109e34f454ca7 Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Tue, 15 Jul 2025 17:00:56 +0000 Subject: [PATCH 02/16] pthread test + public function --- libc/config/linux/x86_64/entrypoints.txt | 3 + libc/include/CMakeLists.txt | 2 + libc/include/pthread.yaml | 22 +++++++ libc/src/__support/threads/CMakeLists.txt | 11 ++++ libc/src/__support/threads/barrier.cpp | 14 +++-- libc/src/__support/threads/barrier.h | 5 +- libc/src/pthread/CMakeLists.txt | 34 ++++++++++ libc/src/pthread/pthread_barrier_destroy.cpp | 3 +- libc/src/pthread/pthread_barrier_init.cpp | 3 +- libc/src/pthread/pthread_barrier_wait.cpp | 7 +-- .../integration/src/pthread/CMakeLists.txt | 17 +++++ .../src/pthread/pthread_barrier_test.cpp | 63 +++++++++++++++++-- 12 files changed, 164 insertions(+), 20 deletions(-) diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 59c248871f83a..3a631c9056163 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -1039,6 +1039,9 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.pthread.pthread_join libc.src.pthread.pthread_key_create libc.src.pthread.pthread_key_delete + libc.src.pthread.pthread_barrier_init + libc.src.pthread.pthread_barrier_wait + libc.src.pthread.pthread_barrier_destroy libc.src.pthread.pthread_mutex_destroy libc.src.pthread.pthread_mutex_init libc.src.pthread.pthread_mutex_lock diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index 55268d19529c7..3c16468b8110e 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -390,6 +390,8 @@ add_header_macro( .llvm-libc-types.pthread_attr_t .llvm-libc-types.pthread_condattr_t .llvm-libc-types.pthread_key_t + .llvm-libc-types.pthread_barrier_t + .llvm-libc-types.pthread_barrierattr_t .llvm-libc-types.pthread_mutex_t .llvm-libc-types.pthread_mutexattr_t .llvm-libc-types.pthread_once_t diff --git a/libc/include/pthread.yaml b/libc/include/pthread.yaml index 5b27e68d2f2d8..8afce2098adde 100644 --- a/libc/include/pthread.yaml +++ b/libc/include/pthread.yaml @@ -6,6 +6,8 @@ types: - type_name: pthread_once_t - type_name: pthread_mutex_t - type_name: pthread_mutexattr_t + - type_name: pthread_barrier_t + - type_name: pthread_barrierattr_t - type_name: pthread_key_t - type_name: pthread_condattr_t - type_name: __pthread_tss_dtor_t @@ -277,6 +279,26 @@ functions: arguments: - type: pthread_mutexattr_t *__restrict - type: int + - name: pthread_barrier_init + standards: + - POSIX + return_type: int + arguments: + - type: pthread_barrier_t *__restrict + - type: const pthread_barrierattr_t *__restrict + - type: int + - name: pthread_barrier_wait + standards: + - POSIX + return_type: int + arguments: + - type: pthread_barrier_t * + - name: pthread_barrier_destroy + standards: + - POSIX + return_type: int + arguments: + - type: pthread_barrier_t * - name: pthread_once standards: - POSIX diff --git a/libc/src/__support/threads/CMakeLists.txt b/libc/src/__support/threads/CMakeLists.txt index bd49bbb5ad2fe..3cf50b6d3f8a9 100644 --- a/libc/src/__support/threads/CMakeLists.txt +++ b/libc/src/__support/threads/CMakeLists.txt @@ -90,6 +90,17 @@ if(TARGET libc.src.__support.threads.${LIBC_TARGET_OS}.CndVar) ) endif() +add_object_library( + barrier + HDRS + barrier.h + SRCS + barrier.cpp + DEPENDS + .CndVar + .mutex +) + if (LLVM_LIBC_FULL_BUILD) set(identifier_dependency_on_thread libc.src.__support.threads.thread) endif() diff --git a/libc/src/__support/threads/barrier.cpp b/libc/src/__support/threads/barrier.cpp index db0e38e9eb71e..809898ac17ccf 100644 --- a/libc/src/__support/threads/barrier.cpp +++ b/libc/src/__support/threads/barrier.cpp @@ -7,12 +7,15 @@ //===----------------------------------------------------------------------===// #include "src/__support/threads/barrier.h" -#include "src/__support/threads/mutex.h" +#include "barrier.h" #include "hdr/errno_macros.h" +#include "src/__support/threads/mutex.h" namespace LIBC_NAMESPACE_DECL { -int Barrier::init(Barrier *b, const pthread_barrierattr_t* attr, unsigned count) { +int Barrier::init(Barrier *b, const pthread_barrierattr_t *attr, + unsigned count) { + LIBC_ASSERT(attr == nullptr); // TODO implement barrierattr if (count == 0) return EINVAL; @@ -45,7 +48,6 @@ int Barrier::wait() { if (waiting == expected) { // this is the last thread to call wait(), so lets wake everyone up blocking = false; - waiting--; exiting.broadcast(); } else { // block threads until waiting = expected @@ -53,6 +55,7 @@ int Barrier::wait() { exiting.wait(&m); } } + waiting--; // all threads have exited the barrier, lets let the ones waiting to enter // continue @@ -61,10 +64,13 @@ int Barrier::wait() { entering.broadcast(); } m.unlock(); + + return 0; } int Barrier::destroy(Barrier *b) { - + Mutex::destroy(&b->m); + return 0; } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/threads/barrier.h b/libc/src/__support/threads/barrier.h index e46d5b9773a4f..d97aafe56d2cd 100644 --- a/libc/src/__support/threads/barrier.h +++ b/libc/src/__support/threads/barrier.h @@ -9,6 +9,8 @@ #ifndef LLVM_LIBC___SUPPORT_SRC_THREADS_LINUX_BARRIER_H #define LLVM_LIBC___SUPPORT_SRC_THREADS_LINUX_BARRIER_H +#include "include/llvm-libc-types/pthread_barrier_t.h" +#include "include/llvm-libc-types/pthread_barrierattr_t.h" #include "src/__support/macros/config.h" #include "src/__support/threads/CndVar.h" #include "src/__support/threads/mutex.h" @@ -29,7 +31,8 @@ class Barrier { Mutex m; public: - static int init(Barrier *b, const pthread_barrierattr_t* attr, unsigned count); + static int init(Barrier *b, const pthread_barrierattr_t *attr, + unsigned count); static int destroy(Barrier *b); int wait(); }; diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt index c8c66805667fa..e5a0a34cf46a6 100644 --- a/libc/src/pthread/CMakeLists.txt +++ b/libc/src/pthread/CMakeLists.txt @@ -271,6 +271,40 @@ add_entrypoint_object( libc.src.errno.errno ) +add_entrypoint_object( + pthread_barrier_init + SRCS + pthread_barrier_init.cpp + HDRS + pthread_barrier_init.h + DEPENDS + libc.src.errno.errno + libc.include.pthread + libc.src.__support.threads.barrier +) + +add_entrypoint_object( + pthread_barrier_destroy + SRCS + pthread_barrier_destroy.cpp + HDRS + pthread_barrier_destroy.h + DEPENDS + libc.include.pthread + libc.src.__support.threads.barrier +) + +add_entrypoint_object( + pthread_barrier_wait + SRCS + pthread_barrier_wait.cpp + HDRS + pthread_barrier_wait.h + DEPENDS + libc.include.pthread + libc.src.__support.threads.barrier +) + add_entrypoint_object( pthread_mutex_init SRCS diff --git a/libc/src/pthread/pthread_barrier_destroy.cpp b/libc/src/pthread/pthread_barrier_destroy.cpp index 00863f8d6ff6b..389e1751ed3ee 100644 --- a/libc/src/pthread/pthread_barrier_destroy.cpp +++ b/libc/src/pthread/pthread_barrier_destroy.cpp @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "pthread_mutex_init.h" -#include "pthread_mutexattr.h" +#include "pthread_barrier_destroy.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" diff --git a/libc/src/pthread/pthread_barrier_init.cpp b/libc/src/pthread/pthread_barrier_init.cpp index 234f58a6c7d62..1d0d87342d823 100644 --- a/libc/src/pthread/pthread_barrier_init.cpp +++ b/libc/src/pthread/pthread_barrier_init.cpp @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "pthread_mutex_init.h" -#include "pthread_mutexattr.h" +#include "pthread_barrier_init.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" diff --git a/libc/src/pthread/pthread_barrier_wait.cpp b/libc/src/pthread/pthread_barrier_wait.cpp index ba23cc0f4e072..75bba94ba438f 100644 --- a/libc/src/pthread/pthread_barrier_wait.cpp +++ b/libc/src/pthread/pthread_barrier_wait.cpp @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "pthread_mutex_init.h" -#include "pthread_mutexattr.h" +#include "pthread_barrier_wait.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" @@ -18,9 +17,7 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, pthread_barrier_wait, - (pthread_barrier_t * b, - const pthread_barrierattr_t *__restrict attr, - unsigned count)) { + (pthread_barrier_t * b)) { return reinterpret_cast(b)->wait(); } diff --git a/libc/test/integration/src/pthread/CMakeLists.txt b/libc/test/integration/src/pthread/CMakeLists.txt index 208ba3fd43507..ce3bb9da9d58e 100644 --- a/libc/test/integration/src/pthread/CMakeLists.txt +++ b/libc/test/integration/src/pthread/CMakeLists.txt @@ -17,6 +17,23 @@ add_integration_test( libc.src.pthread.pthread_join ) +add_integration_test( + pthread_barrier_test + SUITE + libc-pthread-integration-tests + SRCS + pthread_barrier_test.cpp + DEPENDS + libc.include.pthread + libc.src.errno.errno + libc.src.pthread.pthread_barrier_destroy + libc.src.pthread.pthread_barrier_wait + libc.src.pthread.pthread_barrier_init + libc.src.pthread.pthread_create + libc.src.pthread.pthread_join + libc.src.stdio.printf +) + add_integration_test( pthread_rwlock_test SUITE diff --git a/libc/test/integration/src/pthread/pthread_barrier_test.cpp b/libc/test/integration/src/pthread/pthread_barrier_test.cpp index 33d5945a6687d..b87f21a2a2c51 100644 --- a/libc/test/integration/src/pthread/pthread_barrier_test.cpp +++ b/libc/test/integration/src/pthread/pthread_barrier_test.cpp @@ -10,26 +10,77 @@ #include "src/pthread/pthread_barrier_init.h" #include "src/pthread/pthread_barrier_wait.h" +#include "src/__support/CPP/atomic.h" #include "src/pthread/pthread_create.h" +#include "src/pthread/pthread_join.h" +#include "src/pthread/pthread_mutex_destroy.h" +#include "src/pthread/pthread_mutex_init.h" +#include "src/pthread/pthread_mutex_lock.h" +#include "src/pthread/pthread_mutex_unlock.h" +#include "src/stdio/printf.h" #include "test/IntegrationTest/test.h" #include #include // uintptr_t -constexpr int START = 0; -constexpr int MAX = 10000; - pthread_barrier_t barrier; -static int shared_int = START; -void increment_shared_counter() { +void smoke_test() { + ASSERT_EQ(LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, 1), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_barrier_wait(&barrier), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_barrier_destroy(&barrier), 0); +} +LIBC_NAMESPACE::cpp::Atomic counter; +void *increment_counter_and_wait(void *args) { + counter.fetch_add(1); + LIBC_NAMESPACE::pthread_barrier_wait(&barrier); + return 0; } +void shared_counter() { + counter.set(0); + const int NUM_THREADS = 30; + pthread_t threads[NUM_THREADS]; + ASSERT_EQ( + LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, NUM_THREADS + 1), + 0); + for (int i = 0; i < NUM_THREADS; ++i) + LIBC_NAMESPACE::pthread_create(&threads[i], nullptr, + increment_counter_and_wait, nullptr); + + LIBC_NAMESPACE::pthread_barrier_wait(&barrier); + ASSERT_EQ(counter.load(), NUM_THREADS); +} + +void reusable_shared_counter() { + counter.set(0); + const int NUM_THREADS = 30; + const int REPEAT = 10; + pthread_t threads[NUM_THREADS * REPEAT]; + ASSERT_EQ( + LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, NUM_THREADS + 1), + 0); + + for (int i = 0; i < REPEAT; ++i) { + for (int j = 0; j < NUM_THREADS; ++j) { + LIBC_NAMESPACE::pthread_create(&threads[NUM_THREADS * i + j], nullptr, + increment_counter_and_wait, nullptr); + } + LIBC_NAMESPACE::pthread_barrier_wait(&barrier); + ASSERT_EQ(counter.load(), NUM_THREADS * (i + 1)); + } + + for (int i = 0; i < NUM_THREADS * REPEAT; ++i) { + LIBC_NAMESPACE::pthread_join(threads[i], nullptr); + } +} TEST_MAIN() { - + smoke_test(); + shared_counter(); + reusable_shared_counter(); return 0; } From d645f954d8374d3cf3b4ba61dc18b16724c21717 Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Tue, 15 Jul 2025 17:20:06 +0000 Subject: [PATCH 03/16] fix test to join threads --- .../src/pthread/pthread_barrier_test.cpp | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/libc/test/integration/src/pthread/pthread_barrier_test.cpp b/libc/test/integration/src/pthread/pthread_barrier_test.cpp index b87f21a2a2c51..8cf2aaf16acbe 100644 --- a/libc/test/integration/src/pthread/pthread_barrier_test.cpp +++ b/libc/test/integration/src/pthread/pthread_barrier_test.cpp @@ -22,7 +22,6 @@ #include "test/IntegrationTest/test.h" #include -#include // uintptr_t pthread_barrier_t barrier; @@ -39,7 +38,7 @@ void *increment_counter_and_wait(void *args) { return 0; } -void shared_counter() { +void single_use_barrier() { counter.set(0); const int NUM_THREADS = 30; pthread_t threads[NUM_THREADS]; @@ -53,34 +52,36 @@ void shared_counter() { LIBC_NAMESPACE::pthread_barrier_wait(&barrier); ASSERT_EQ(counter.load(), NUM_THREADS); + + for (int i = 0; i < NUM_THREADS; ++i) + LIBC_NAMESPACE::pthread_join(threads[i], nullptr); } -void reusable_shared_counter() { +void reusable_barrier() { counter.set(0); const int NUM_THREADS = 30; - const int REPEAT = 10; + const int REPEAT = 20; pthread_t threads[NUM_THREADS * REPEAT]; ASSERT_EQ( LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, NUM_THREADS + 1), 0); for (int i = 0; i < REPEAT; ++i) { - for (int j = 0; j < NUM_THREADS; ++j) { + for (int j = 0; j < NUM_THREADS; ++j) LIBC_NAMESPACE::pthread_create(&threads[NUM_THREADS * i + j], nullptr, increment_counter_and_wait, nullptr); - } + LIBC_NAMESPACE::pthread_barrier_wait(&barrier); ASSERT_EQ(counter.load(), NUM_THREADS * (i + 1)); } - for (int i = 0; i < NUM_THREADS * REPEAT; ++i) { + for (int i = 0; i < NUM_THREADS * REPEAT; ++i) LIBC_NAMESPACE::pthread_join(threads[i], nullptr); - } } TEST_MAIN() { smoke_test(); - shared_counter(); - reusable_shared_counter(); + single_use_barrier(); + reusable_barrier(); return 0; } From 8cad8c0a4533c525c1a41b13821c41edaa2e3359 Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Tue, 15 Jul 2025 18:00:24 +0000 Subject: [PATCH 04/16] implemented return value for barrier wait --- .../include/llvm-libc-macros/pthread-macros.h | 2 ++ libc/src/__support/threads/barrier.cpp | 6 ++++ libc/src/__support/threads/barrier.h | 2 ++ libc/src/pthread/pthread_barrier_wait.cpp | 9 ++++-- .../src/pthread/pthread_barrier_test.cpp | 32 ++++++++++++++++++- 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/libc/include/llvm-libc-macros/pthread-macros.h b/libc/include/llvm-libc-macros/pthread-macros.h index fcc6ef925e3f4..ce467b7cc4d07 100644 --- a/libc/include/llvm-libc-macros/pthread-macros.h +++ b/libc/include/llvm-libc-macros/pthread-macros.h @@ -22,6 +22,8 @@ #define PTHREAD_MUTEX_STALLED 0 #define PTHREAD_MUTEX_ROBUST 1 +#define PTHREAD_BARRIER_SERIAL_THREAD -1 + #define PTHREAD_ONCE_INIT {0} #define PTHREAD_PROCESS_PRIVATE 0 diff --git a/libc/src/__support/threads/barrier.cpp b/libc/src/__support/threads/barrier.cpp index 809898ac17ccf..298cb17cb8d00 100644 --- a/libc/src/__support/threads/barrier.cpp +++ b/libc/src/__support/threads/barrier.cpp @@ -13,6 +13,8 @@ namespace LIBC_NAMESPACE_DECL { +const int BARRIER_FIRST_EXITED = -1; + int Barrier::init(Barrier *b, const pthread_barrierattr_t *attr, unsigned count) { LIBC_ASSERT(attr == nullptr); // TODO implement barrierattr @@ -62,6 +64,8 @@ int Barrier::wait() { if (waiting == 0) { blocking = true; entering.broadcast(); + m.unlock(); + return BARRIER_FIRST_EXITED; } m.unlock(); @@ -69,6 +73,8 @@ int Barrier::wait() { } int Barrier::destroy(Barrier *b) { + CndVar::destroy(&b->entering); + CndVar::destroy(&b->exiting); Mutex::destroy(&b->m); return 0; } diff --git a/libc/src/__support/threads/barrier.h b/libc/src/__support/threads/barrier.h index d97aafe56d2cd..b8b410ec1b35e 100644 --- a/libc/src/__support/threads/barrier.h +++ b/libc/src/__support/threads/barrier.h @@ -21,6 +21,8 @@ namespace LIBC_NAMESPACE_DECL { // pthread_barrier_t (found in include/llvm-libc/types/pthread_barrier_t.h) is // the same size +extern const int BARRIER_FIRST_EXITED; + class Barrier { private: unsigned expected; diff --git a/libc/src/pthread/pthread_barrier_wait.cpp b/libc/src/pthread/pthread_barrier_wait.cpp index 75bba94ba438f..617d91dd16f77 100644 --- a/libc/src/pthread/pthread_barrier_wait.cpp +++ b/libc/src/pthread/pthread_barrier_wait.cpp @@ -16,9 +16,12 @@ namespace LIBC_NAMESPACE_DECL { -LLVM_LIBC_FUNCTION(int, pthread_barrier_wait, - (pthread_barrier_t * b)) { - return reinterpret_cast(b)->wait(); +LLVM_LIBC_FUNCTION(int, pthread_barrier_wait, (pthread_barrier_t * b)) { + int out = reinterpret_cast(b)->wait(); + if (out == BARRIER_FIRST_EXITED) + return PTHREAD_BARRIER_SERIAL_THREAD; + + return out; } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/integration/src/pthread/pthread_barrier_test.cpp b/libc/test/integration/src/pthread/pthread_barrier_test.cpp index 8cf2aaf16acbe..d4d696ec82507 100644 --- a/libc/test/integration/src/pthread/pthread_barrier_test.cpp +++ b/libc/test/integration/src/pthread/pthread_barrier_test.cpp @@ -27,7 +27,8 @@ pthread_barrier_t barrier; void smoke_test() { ASSERT_EQ(LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, 1), 0); - ASSERT_EQ(LIBC_NAMESPACE::pthread_barrier_wait(&barrier), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_barrier_wait(&barrier), + PTHREAD_BARRIER_SERIAL_THREAD); ASSERT_EQ(LIBC_NAMESPACE::pthread_barrier_destroy(&barrier), 0); } @@ -55,6 +56,8 @@ void single_use_barrier() { for (int i = 0; i < NUM_THREADS; ++i) LIBC_NAMESPACE::pthread_join(threads[i], nullptr); + + LIBC_NAMESPACE::pthread_barrier_destroy(&barrier); } void reusable_barrier() { @@ -77,11 +80,38 @@ void reusable_barrier() { for (int i = 0; i < NUM_THREADS * REPEAT; ++i) LIBC_NAMESPACE::pthread_join(threads[i], nullptr); + + LIBC_NAMESPACE::pthread_barrier_destroy(&barrier); +} + +void *barrier_wait(void* in) { + return reinterpret_cast( + LIBC_NAMESPACE::pthread_barrier_wait(&barrier)); +} + +// verify that only one of the wait() calls return PTHREAD_BARRIER_SERIAL_THREAD +// with the rest returning 0 +void one_nonzero_wait_returnval() { + const int NUM_THREADS = 30; + pthread_t threads[NUM_THREADS]; + LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, NUM_THREADS + 1); + for (int i = 0; i < NUM_THREADS; ++i) + LIBC_NAMESPACE::pthread_create(&threads[i], nullptr, barrier_wait, nullptr); + + uintptr_t retsum = LIBC_NAMESPACE::pthread_barrier_wait(&barrier); + for (int i = 0; i < NUM_THREADS; ++i) { + void* ret; + LIBC_NAMESPACE::pthread_join(threads[i], &ret); + retsum += reinterpret_cast(ret); + } + + ASSERT_EQ(static_cast(retsum), PTHREAD_BARRIER_SERIAL_THREAD); } TEST_MAIN() { smoke_test(); single_use_barrier(); reusable_barrier(); + one_nonzero_wait_returnval(); return 0; } From 7adf56a5ed4705dca4816e7c889d42df6478a8d9 Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Tue, 15 Jul 2025 20:13:06 +0000 Subject: [PATCH 05/16] formatting --- libc/src/__support/threads/barrier.cpp | 2 +- libc/src/pthread/pthread_barrier_destroy.h | 2 +- libc/src/pthread/pthread_barrier_wait.cpp | 2 +- libc/test/integration/src/pthread/pthread_barrier_test.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libc/src/__support/threads/barrier.cpp b/libc/src/__support/threads/barrier.cpp index 298cb17cb8d00..050abb3391446 100644 --- a/libc/src/__support/threads/barrier.cpp +++ b/libc/src/__support/threads/barrier.cpp @@ -1,4 +1,4 @@ -//===-- Linux implementation of the callonce function ---------------------===// +//===-- Implementation of Barrier class ------------- ---------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/libc/src/pthread/pthread_barrier_destroy.h b/libc/src/pthread/pthread_barrier_destroy.h index 0b1d0f090ec26..58ac08862d90c 100644 --- a/libc/src/pthread/pthread_barrier_destroy.h +++ b/libc/src/pthread/pthread_barrier_destroy.h @@ -1,4 +1,4 @@ -//===-- Implementation header for pthread_barrier_destroy ----------*- C++ -*-===// +//===-- Implementation header for pthread_barrier_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. diff --git a/libc/src/pthread/pthread_barrier_wait.cpp b/libc/src/pthread/pthread_barrier_wait.cpp index 617d91dd16f77..7b12c907f4fb1 100644 --- a/libc/src/pthread/pthread_barrier_wait.cpp +++ b/libc/src/pthread/pthread_barrier_wait.cpp @@ -20,7 +20,7 @@ LLVM_LIBC_FUNCTION(int, pthread_barrier_wait, (pthread_barrier_t * b)) { int out = reinterpret_cast(b)->wait(); if (out == BARRIER_FIRST_EXITED) return PTHREAD_BARRIER_SERIAL_THREAD; - + return out; } diff --git a/libc/test/integration/src/pthread/pthread_barrier_test.cpp b/libc/test/integration/src/pthread/pthread_barrier_test.cpp index d4d696ec82507..bde1230f5b86d 100644 --- a/libc/test/integration/src/pthread/pthread_barrier_test.cpp +++ b/libc/test/integration/src/pthread/pthread_barrier_test.cpp @@ -84,7 +84,7 @@ void reusable_barrier() { LIBC_NAMESPACE::pthread_barrier_destroy(&barrier); } -void *barrier_wait(void* in) { +void *barrier_wait(void *in) { return reinterpret_cast( LIBC_NAMESPACE::pthread_barrier_wait(&barrier)); } @@ -100,7 +100,7 @@ void one_nonzero_wait_returnval() { uintptr_t retsum = LIBC_NAMESPACE::pthread_barrier_wait(&barrier); for (int i = 0; i < NUM_THREADS; ++i) { - void* ret; + void *ret; LIBC_NAMESPACE::pthread_join(threads[i], &ret); retsum += reinterpret_cast(ret); } From a349e6f20cb8d4058c8f0247d48bd8e837129420 Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Tue, 15 Jul 2025 20:22:42 +0000 Subject: [PATCH 06/16] mark attr param as unused --- libc/src/__support/threads/barrier.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libc/src/__support/threads/barrier.cpp b/libc/src/__support/threads/barrier.cpp index 050abb3391446..e63467d88b2bf 100644 --- a/libc/src/__support/threads/barrier.cpp +++ b/libc/src/__support/threads/barrier.cpp @@ -15,7 +15,8 @@ namespace LIBC_NAMESPACE_DECL { const int BARRIER_FIRST_EXITED = -1; -int Barrier::init(Barrier *b, const pthread_barrierattr_t *attr, +int Barrier::init(Barrier *b, + const pthread_barrierattr_t *attr __attribute__((unused)), unsigned count) { LIBC_ASSERT(attr == nullptr); // TODO implement barrierattr if (count == 0) From d901a3712e797e8a464e967cb99209e3fd000e62 Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Fri, 18 Jul 2025 16:47:38 +0000 Subject: [PATCH 07/16] reorganized for readability --- libc/src/__support/threads/barrier.cpp | 17 +++++++++-------- libc/src/__support/threads/barrier.h | 9 +++++++++ libc/src/pthread/pthread_barrier_init.cpp | 5 ----- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/libc/src/__support/threads/barrier.cpp b/libc/src/__support/threads/barrier.cpp index e63467d88b2bf..a9253d8c91611 100644 --- a/libc/src/__support/threads/barrier.cpp +++ b/libc/src/__support/threads/barrier.cpp @@ -9,6 +9,7 @@ #include "src/__support/threads/barrier.h" #include "barrier.h" #include "hdr/errno_macros.h" +#include "src/__support/threads/CndVar.h" #include "src/__support/threads/mutex.h" namespace LIBC_NAMESPACE_DECL { @@ -16,7 +17,7 @@ namespace LIBC_NAMESPACE_DECL { const int BARRIER_FIRST_EXITED = -1; int Barrier::init(Barrier *b, - const pthread_barrierattr_t *attr __attribute__((unused)), + [[maybe_unused]] const pthread_barrierattr_t *attr, unsigned count) { LIBC_ASSERT(attr == nullptr); // TODO implement barrierattr if (count == 0) @@ -48,21 +49,21 @@ int Barrier::wait() { } waiting++; - if (waiting == expected) { - // this is the last thread to call wait(), so lets wake everyone up - blocking = false; - exiting.broadcast(); - } else { + if (waiting < expected) { // block threads until waiting = expected while (blocking) { exiting.wait(&m); } + } else { + // this is the last thread to call wait(), so lets wake everyone up + blocking = false; + exiting.broadcast(); } waiting--; - // all threads have exited the barrier, lets let the ones waiting to enter - // continue if (waiting == 0) { + // all threads have exited the barrier, let's let the ones waiting to enter + // continue blocking = true; entering.broadcast(); m.unlock(); diff --git a/libc/src/__support/threads/barrier.h b/libc/src/__support/threads/barrier.h index b8b410ec1b35e..5aa99fe405cda 100644 --- a/libc/src/__support/threads/barrier.h +++ b/libc/src/__support/threads/barrier.h @@ -39,6 +39,15 @@ class Barrier { int wait(); }; +static_assert( + sizeof(Barrier) <= sizeof(pthread_barrier_t), + "The public pthread_barrier_t type cannot accommodate the internal " + "barrier type."); + +static_assert(alignof(Barrier) == alignof(pthread_barrier_t), + "The public pthread_barrier_t type has a different alignment " + "than the internal barrier type."); + } // namespace LIBC_NAMESPACE_DECL #endif // LLVM_LIBC___SUPPORT_SRC_THREADS_LINUX_BARRIER_H diff --git a/libc/src/pthread/pthread_barrier_init.cpp b/libc/src/pthread/pthread_barrier_init.cpp index 1d0d87342d823..f17885432bf31 100644 --- a/libc/src/pthread/pthread_barrier_init.cpp +++ b/libc/src/pthread/pthread_barrier_init.cpp @@ -16,11 +16,6 @@ namespace LIBC_NAMESPACE_DECL { -static_assert( - sizeof(Barrier) <= sizeof(pthread_barrier_t), - "The public pthread_barrier_t type cannot accommodate the internal " - "barrier type."); - LLVM_LIBC_FUNCTION(int, pthread_barrier_init, (pthread_barrier_t * b, const pthread_barrierattr_t *__restrict attr, From 0512e7f596583298f89bd702c9d45b34f2554ea6 Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Fri, 18 Jul 2025 19:23:06 +0000 Subject: [PATCH 08/16] used internal pthread header --- libc/hdr/types/pthread_barrier_t.h | 22 ++++++++++++++++++++ libc/hdr/types/pthread_barrierattr_t.h | 22 ++++++++++++++++++++ libc/src/pthread/pthread_barrier_destroy.cpp | 3 +-- libc/src/pthread/pthread_barrier_destroy.h | 2 +- libc/src/pthread/pthread_barrier_init.cpp | 4 ++-- libc/src/pthread/pthread_barrier_init.h | 3 ++- libc/src/pthread/pthread_barrier_wait.cpp | 3 +-- libc/src/pthread/pthread_barrier_wait.h | 2 +- 8 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 libc/hdr/types/pthread_barrier_t.h create mode 100644 libc/hdr/types/pthread_barrierattr_t.h diff --git a/libc/hdr/types/pthread_barrier_t.h b/libc/hdr/types/pthread_barrier_t.h new file mode 100644 index 0000000000000..57bcdfc6a9901 --- /dev/null +++ b/libc/hdr/types/pthread_barrier_t.h @@ -0,0 +1,22 @@ +//===-- Definition of macros from pthread_barrier_t.h ---------------------===// +// +// 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_HDR_TYPES_PTHREAD_BARRIER_T_H +#define LLVM_LIBC_HDR_TYPES_PTHREAD_BARRIER_T_H + +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-types/pthread_barrier_t.h" + +#else // Overlay mode + +#error "Cannot overlay pthread_barrier_t" + +#endif // LLVM_LIBC_FULL_BUILD + +#endif // LLVM_LIBC_HDR_TYPES_PTHREAD_BARRIER_T_H diff --git a/libc/hdr/types/pthread_barrierattr_t.h b/libc/hdr/types/pthread_barrierattr_t.h new file mode 100644 index 0000000000000..d08dda1c2f36d --- /dev/null +++ b/libc/hdr/types/pthread_barrierattr_t.h @@ -0,0 +1,22 @@ +//===-- Definition of macros from pthread_barrier_t.h ---------------------===// +// +// 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_HDR_TYPES_PTHREAD_BARRIERATTR_T_H +#define LLVM_LIBC_HDR_TYPES_PTHREAD_BARRIERATTR_T_H + +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-types/pthread_barrierattr_t.h" + +#else // Overlay mode + +#error "Cannot overlay pthread_barrierattr_t" + +#endif // LLVM_LIBC_FULL_BUILD + +#endif // LLVM_LIBC_HDR_TYPES_PTHREAD_BARRIERATTR_T_H diff --git a/libc/src/pthread/pthread_barrier_destroy.cpp b/libc/src/pthread/pthread_barrier_destroy.cpp index 389e1751ed3ee..6c9ae8d57ab2f 100644 --- a/libc/src/pthread/pthread_barrier_destroy.cpp +++ b/libc/src/pthread/pthread_barrier_destroy.cpp @@ -8,12 +8,11 @@ #include "pthread_barrier_destroy.h" +#include "hdr/types/pthread_barrier_t.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/__support/threads/barrier.h" -#include - namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, pthread_barrier_destroy, (pthread_barrier_t * b)) { diff --git a/libc/src/pthread/pthread_barrier_destroy.h b/libc/src/pthread/pthread_barrier_destroy.h index 58ac08862d90c..e27552ce7e5ae 100644 --- a/libc/src/pthread/pthread_barrier_destroy.h +++ b/libc/src/pthread/pthread_barrier_destroy.h @@ -9,8 +9,8 @@ #ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_DESTROY_H #define LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_DESTROY_H +#include "hdr/types/pthread_barrier_t.h" #include "src/__support/macros/config.h" -#include namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/pthread/pthread_barrier_init.cpp b/libc/src/pthread/pthread_barrier_init.cpp index f17885432bf31..4317d82bc935f 100644 --- a/libc/src/pthread/pthread_barrier_init.cpp +++ b/libc/src/pthread/pthread_barrier_init.cpp @@ -8,12 +8,12 @@ #include "pthread_barrier_init.h" +#include "hdr/types/pthread_barrier_t.h" +#include "hdr/types/pthread_barrierattr_t.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/__support/threads/barrier.h" -#include - namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, pthread_barrier_init, diff --git a/libc/src/pthread/pthread_barrier_init.h b/libc/src/pthread/pthread_barrier_init.h index ea79df6da7ea9..bb17f3f5664da 100644 --- a/libc/src/pthread/pthread_barrier_init.h +++ b/libc/src/pthread/pthread_barrier_init.h @@ -9,8 +9,9 @@ #ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_INIT_H #define LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_INIT_H +#include "hdr/types/pthread_barrier_t.h" +#include "hdr/types/pthread_barrierattr_t.h" #include "src/__support/macros/config.h" -#include namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/pthread/pthread_barrier_wait.cpp b/libc/src/pthread/pthread_barrier_wait.cpp index 7b12c907f4fb1..7e34babdb2579 100644 --- a/libc/src/pthread/pthread_barrier_wait.cpp +++ b/libc/src/pthread/pthread_barrier_wait.cpp @@ -8,12 +8,11 @@ #include "pthread_barrier_wait.h" +#include "hdr/types/pthread_barrier_t.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/__support/threads/barrier.h" -#include - namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, pthread_barrier_wait, (pthread_barrier_t * b)) { diff --git a/libc/src/pthread/pthread_barrier_wait.h b/libc/src/pthread/pthread_barrier_wait.h index 738ca56bd53e4..52eb172d6264c 100644 --- a/libc/src/pthread/pthread_barrier_wait.h +++ b/libc/src/pthread/pthread_barrier_wait.h @@ -10,7 +10,7 @@ #define LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_WAIT_H #include "src/__support/macros/config.h" -#include +#include "hdr/types/pthread_barrier_t.h" namespace LIBC_NAMESPACE_DECL { From ecf9f6c5ddcda1a717eca30286d103f394ed7c4b Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Tue, 22 Jul 2025 21:40:56 +0000 Subject: [PATCH 09/16] fix pthread_barrier_t public struct opaqueness/alignment + test cleanup --- libc/hdr/CMakeLists.txt | 9 ++ libc/hdr/pthread_macros.h | 22 ++++ libc/hdr/types/CMakeLists.txt | 16 +++ libc/include/llvm-libc-types/CMakeLists.txt | 1 + libc/include/llvm-libc-types/__barrier_type.h | 21 ++++ .../llvm-libc-types/pthread_barrier_t.h | 7 +- libc/src/__support/threads/barrier.cpp | 12 +- libc/src/__support/threads/barrier.h | 5 +- libc/src/pthread/pthread_barrier_wait.cpp | 6 +- .../src/pthread/pthread_barrier_test.cpp | 107 +++++++++--------- 10 files changed, 136 insertions(+), 70 deletions(-) create mode 100644 libc/hdr/pthread_macros.h create mode 100644 libc/include/llvm-libc-types/__barrier_type.h diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt index 052a773a4fcec..0aa79e98446c1 100644 --- a/libc/hdr/CMakeLists.txt +++ b/libc/hdr/CMakeLists.txt @@ -72,6 +72,15 @@ add_proxy_header_library( libc.include.fenv ) +add_proxy_header_library( + pthread_macros + HDRS + pthread_macros.h + FULL_BUILD_DEPENDS + libc.include.llvm-libc-macros.pthread_macros + libc.include.pthread +) + add_proxy_header_library( sched_macros HDRS diff --git a/libc/hdr/pthread_macros.h b/libc/hdr/pthread_macros.h new file mode 100644 index 0000000000000..b0bab73687e3b --- /dev/null +++ b/libc/hdr/pthread_macros.h @@ -0,0 +1,22 @@ +//===-- Definition of macros from pthread.h ----------------------------------===// +// +// 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_HDR_PTHREAD_MACROS_H +#define LLVM_LIBC_HDR_PTHREAD_MACROS_H + +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-macros/pthread-macros.h" + +#else // Overlay mode + +#include + +#endif // LLVM_LIBC_FULL_BUILD + +#endif // LLVM_LIBC_HDR_PTHREAD_MACROS_H diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt index e4b3cb0faa820..2f2d6e8f0f985 100644 --- a/libc/hdr/types/CMakeLists.txt +++ b/libc/hdr/types/CMakeLists.txt @@ -237,6 +237,22 @@ add_proxy_header_library( libc.include.llvm-libc-types.pid_t ) +add_proxy_header_library( + pthread_barrier_t + HDRS + pthread_barrier_t.h + FULL_BUILD_DEPENDS + libc.include.llvm-libc-types.pthread_barrier_t +) + +add_proxy_header_library( + pthread_barrierattr_t + HDRS + pthread_barrierattr_t.h + FULL_BUILD_DEPENDS + libc.include.llvm-libc-types.pthread_barrierattr_t +) + add_proxy_header_library( atexithandler_t HDRS diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index 405c2cd26b863..ba621757a31ed 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -10,6 +10,7 @@ add_header(__exec_envp_t HDR __exec_envp_t.h) add_header(__futex_word HDR __futex_word.h) add_header(pid_t HDR pid_t.h) add_header(__mutex_type HDR __mutex_type.h DEPENDS .__futex_word .pid_t) +add_header(__barrier_type HDR __barrier_type.h) add_header(__pthread_once_func_t HDR __pthread_once_func_t.h) add_header(__pthread_start_t HDR __pthread_start_t.h) add_header(__pthread_tss_dtor_t HDR __pthread_tss_dtor_t.h) diff --git a/libc/include/llvm-libc-types/__barrier_type.h b/libc/include/llvm-libc-types/__barrier_type.h new file mode 100644 index 0000000000000..97406b8843ee5 --- /dev/null +++ b/libc/include/llvm-libc-types/__barrier_type.h @@ -0,0 +1,21 @@ +//===-- Definition of pthread_barrier_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__BARRIER_TYPE_H +#define LLVM_LIBC_TYPES__BARRIER_TYPE_H + +typedef struct __attribute__((aligned(8 /* alignof (Barrier) */))) { + unsigned expected; + unsigned waiting; + bool blocking; + char entering[24 /* sizeof (CndVar) */]; + char exiting[24 /* sizeof (CndVar) */]; + char mutex[24 /* sizeof (Mutex) */]; +} __barrier_type; + +#endif // LLVM_LIBC_TYPES__BARRIER_TYPE_H diff --git a/libc/include/llvm-libc-types/pthread_barrier_t.h b/libc/include/llvm-libc-types/pthread_barrier_t.h index d95477afb226c..3a3d4706d43e6 100644 --- a/libc/include/llvm-libc-types/pthread_barrier_t.h +++ b/libc/include/llvm-libc-types/pthread_barrier_t.h @@ -1,4 +1,4 @@ -//===-- Definition of pthread_barrier_t type ------------------------------===// +//===-- Definition of pthread_barrier_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. @@ -9,8 +9,7 @@ #ifndef LLVM_LIBC_TYPES_PTHREAD_BARRIER_T_H #define LLVM_LIBC_TYPES_PTHREAD_BARRIER_T_H -typedef struct { - char padding[88]; -} pthread_barrier_t; +#include "include/llvm-libc-types/__barrier_type.h" +typedef __barrier_type pthread_barrier_t; #endif // LLVM_LIBC_TYPES_PTHREAD_BARRIER_T_H diff --git a/libc/src/__support/threads/barrier.cpp b/libc/src/__support/threads/barrier.cpp index a9253d8c91611..e39fb17637633 100644 --- a/libc/src/__support/threads/barrier.cpp +++ b/libc/src/__support/threads/barrier.cpp @@ -14,8 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -const int BARRIER_FIRST_EXITED = -1; - int Barrier::init(Barrier *b, [[maybe_unused]] const pthread_barrierattr_t *attr, unsigned count) { @@ -36,7 +34,10 @@ int Barrier::init(Barrier *b, if (err != 0) return err; - Mutex::init(&b->m, false, false, false, false); + auto mutex_err = Mutex::init(&b->m, false, false, false, false); + if (mutex_err != MutexError::NONE) + return EAGAIN; + return 0; } @@ -67,7 +68,10 @@ int Barrier::wait() { blocking = true; entering.broadcast(); m.unlock(); - return BARRIER_FIRST_EXITED; + + // POSIX dictates that the barrier should return a special value to just one + // thread, so we can arbitrarily choose this thread + return PTHREAD_BARRIER_SERIAL_THREAD; } m.unlock(); diff --git a/libc/src/__support/threads/barrier.h b/libc/src/__support/threads/barrier.h index 5aa99fe405cda..aae811a70e41c 100644 --- a/libc/src/__support/threads/barrier.h +++ b/libc/src/__support/threads/barrier.h @@ -9,9 +9,9 @@ #ifndef LLVM_LIBC___SUPPORT_SRC_THREADS_LINUX_BARRIER_H #define LLVM_LIBC___SUPPORT_SRC_THREADS_LINUX_BARRIER_H +#include "hdr/pthread_macros.h" #include "include/llvm-libc-types/pthread_barrier_t.h" #include "include/llvm-libc-types/pthread_barrierattr_t.h" -#include "src/__support/macros/config.h" #include "src/__support/threads/CndVar.h" #include "src/__support/threads/mutex.h" @@ -20,9 +20,6 @@ namespace LIBC_NAMESPACE_DECL { // NOTE: if the size of this class changes, you must ensure that the size of // pthread_barrier_t (found in include/llvm-libc/types/pthread_barrier_t.h) is // the same size - -extern const int BARRIER_FIRST_EXITED; - class Barrier { private: unsigned expected; diff --git a/libc/src/pthread/pthread_barrier_wait.cpp b/libc/src/pthread/pthread_barrier_wait.cpp index 7e34babdb2579..3d68c4f8938c9 100644 --- a/libc/src/pthread/pthread_barrier_wait.cpp +++ b/libc/src/pthread/pthread_barrier_wait.cpp @@ -16,11 +16,7 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, pthread_barrier_wait, (pthread_barrier_t * b)) { - int out = reinterpret_cast(b)->wait(); - if (out == BARRIER_FIRST_EXITED) - return PTHREAD_BARRIER_SERIAL_THREAD; - - return out; + return reinterpret_cast(b)->wait(); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/integration/src/pthread/pthread_barrier_test.cpp b/libc/test/integration/src/pthread/pthread_barrier_test.cpp index bde1230f5b86d..2ba4d3ac22897 100644 --- a/libc/test/integration/src/pthread/pthread_barrier_test.cpp +++ b/libc/test/integration/src/pthread/pthread_barrier_test.cpp @@ -18,68 +18,87 @@ #include "src/pthread/pthread_mutex_lock.h" #include "src/pthread/pthread_mutex_unlock.h" #include "src/stdio/printf.h" +#include "src/string/memset.h" #include "test/IntegrationTest/test.h" #include pthread_barrier_t barrier; - -void smoke_test() { - ASSERT_EQ(LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, 1), 0); - ASSERT_EQ(LIBC_NAMESPACE::pthread_barrier_wait(&barrier), - PTHREAD_BARRIER_SERIAL_THREAD); - ASSERT_EQ(LIBC_NAMESPACE::pthread_barrier_destroy(&barrier), 0); -} - LIBC_NAMESPACE::cpp::Atomic counter; + void *increment_counter_and_wait(void *args) { counter.fetch_add(1); - LIBC_NAMESPACE::pthread_barrier_wait(&barrier); - return 0; + return reinterpret_cast( + LIBC_NAMESPACE::pthread_barrier_wait(&barrier)); } -void single_use_barrier() { +void single_use_barrier_test(int num_threads) { counter.set(0); - const int NUM_THREADS = 30; - pthread_t threads[NUM_THREADS]; + // create n - 1 ADDITIONAL threads since the current thread will also wait at + // the barrier + pthread_t threads[num_threads - 1]; + LIBC_NAMESPACE::memset(&barrier, 0, sizeof(pthread_barrier_t)); ASSERT_EQ( - LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, NUM_THREADS + 1), - 0); + LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, num_threads), 0); - for (int i = 0; i < NUM_THREADS; ++i) + for (int i = 0; i < num_threads - 1; ++i) LIBC_NAMESPACE::pthread_create(&threads[i], nullptr, increment_counter_and_wait, nullptr); - LIBC_NAMESPACE::pthread_barrier_wait(&barrier); - ASSERT_EQ(counter.load(), NUM_THREADS); + uintptr_t return_val_sum = + reinterpret_cast(increment_counter_and_wait(nullptr)); + ASSERT_EQ(counter.load(), num_threads); - for (int i = 0; i < NUM_THREADS; ++i) - LIBC_NAMESPACE::pthread_join(threads[i], nullptr); + // verify only one thread got the PTHREAD_BARRIER_SERIAL_THREAD return value + for (int i = 0; i < num_threads - 1; ++i) { + void *ret; + LIBC_NAMESPACE::pthread_join(threads[i], &ret); + if (reinterpret_cast(ret) == + static_cast(PTHREAD_BARRIER_SERIAL_THREAD)) { + return_val_sum += reinterpret_cast(ret); + } else { + ASSERT_EQ(ret, 0); + } + } + ASSERT_EQ(return_val_sum, + static_cast(PTHREAD_BARRIER_SERIAL_THREAD)); LIBC_NAMESPACE::pthread_barrier_destroy(&barrier); } -void reusable_barrier() { +void reused_barrier_test() { counter.set(0); const int NUM_THREADS = 30; const int REPEAT = 20; - pthread_t threads[NUM_THREADS * REPEAT]; + pthread_t threads[NUM_THREADS - 1]; // subtract 1 for main thread + LIBC_NAMESPACE::memset(&barrier, 0, sizeof(pthread_barrier_t)); ASSERT_EQ( - LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, NUM_THREADS + 1), - 0); + LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, NUM_THREADS), 0); for (int i = 0; i < REPEAT; ++i) { - for (int j = 0; j < NUM_THREADS; ++j) - LIBC_NAMESPACE::pthread_create(&threads[NUM_THREADS * i + j], nullptr, + for (int j = 0; j < NUM_THREADS - 1; ++j) + LIBC_NAMESPACE::pthread_create(&threads[j], nullptr, increment_counter_and_wait, nullptr); - LIBC_NAMESPACE::pthread_barrier_wait(&barrier); + uintptr_t return_val_sum = + reinterpret_cast(increment_counter_and_wait(nullptr)); ASSERT_EQ(counter.load(), NUM_THREADS * (i + 1)); - } - for (int i = 0; i < NUM_THREADS * REPEAT; ++i) - LIBC_NAMESPACE::pthread_join(threads[i], nullptr); + // verify only one thread got the PTHREAD_BARRIER_SERIAL_THREAD return value + for (int i = 0; i < NUM_THREADS - 1; ++i) { + void *ret; + LIBC_NAMESPACE::pthread_join(threads[i], &ret); + if (reinterpret_cast(ret) == + static_cast(PTHREAD_BARRIER_SERIAL_THREAD)) { + return_val_sum += reinterpret_cast(ret); + } else { + ASSERT_EQ(ret, 0); + } + } + ASSERT_EQ(return_val_sum, + static_cast(PTHREAD_BARRIER_SERIAL_THREAD)); + } LIBC_NAMESPACE::pthread_barrier_destroy(&barrier); } @@ -89,29 +108,11 @@ void *barrier_wait(void *in) { LIBC_NAMESPACE::pthread_barrier_wait(&barrier)); } -// verify that only one of the wait() calls return PTHREAD_BARRIER_SERIAL_THREAD -// with the rest returning 0 -void one_nonzero_wait_returnval() { - const int NUM_THREADS = 30; - pthread_t threads[NUM_THREADS]; - LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, NUM_THREADS + 1); - for (int i = 0; i < NUM_THREADS; ++i) - LIBC_NAMESPACE::pthread_create(&threads[i], nullptr, barrier_wait, nullptr); - - uintptr_t retsum = LIBC_NAMESPACE::pthread_barrier_wait(&barrier); - for (int i = 0; i < NUM_THREADS; ++i) { - void *ret; - LIBC_NAMESPACE::pthread_join(threads[i], &ret); - retsum += reinterpret_cast(ret); - } - - ASSERT_EQ(static_cast(retsum), PTHREAD_BARRIER_SERIAL_THREAD); -} - TEST_MAIN() { - smoke_test(); - single_use_barrier(); - reusable_barrier(); - one_nonzero_wait_returnval(); + // don't create any additional threads; only use main thread + single_use_barrier_test(1); + + single_use_barrier_test(30); + reused_barrier_test(); return 0; } From 1a828f403477d63b986bae8fd1deb9c3f269270b Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Tue, 22 Jul 2025 21:46:16 +0000 Subject: [PATCH 10/16] formatting --- libc/hdr/pthread_macros.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/hdr/pthread_macros.h b/libc/hdr/pthread_macros.h index b0bab73687e3b..f913015abd31c 100644 --- a/libc/hdr/pthread_macros.h +++ b/libc/hdr/pthread_macros.h @@ -1,4 +1,4 @@ -//===-- Definition of macros from pthread.h ----------------------------------===// +//===-- Definition of macros from pthread.h -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. From 31224391c08a0d2acfebf6454b439527917d14da Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Tue, 22 Jul 2025 21:48:54 +0000 Subject: [PATCH 11/16] header typo --- libc/include/llvm-libc-types/__barrier_type.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/include/llvm-libc-types/__barrier_type.h b/libc/include/llvm-libc-types/__barrier_type.h index 97406b8843ee5..59712619e917d 100644 --- a/libc/include/llvm-libc-types/__barrier_type.h +++ b/libc/include/llvm-libc-types/__barrier_type.h @@ -1,4 +1,4 @@ -//===-- Definition of pthread_barrier_t type ------------------------------===// +//===-- Definition of __barrier_type type ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. From e20d45090672bc07dee6c41eb035d9d73566585c Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Tue, 22 Jul 2025 21:58:52 +0000 Subject: [PATCH 12/16] more header typos --- libc/hdr/types/pthread_barrierattr_t.h | 2 +- libc/src/pthread/pthread_barrier_destroy.cpp | 2 +- libc/src/pthread/pthread_barrier_init.cpp | 2 +- libc/src/pthread/pthread_barrier_wait.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libc/hdr/types/pthread_barrierattr_t.h b/libc/hdr/types/pthread_barrierattr_t.h index d08dda1c2f36d..d9d14c12e4de6 100644 --- a/libc/hdr/types/pthread_barrierattr_t.h +++ b/libc/hdr/types/pthread_barrierattr_t.h @@ -1,4 +1,4 @@ -//===-- Definition of macros from pthread_barrier_t.h ---------------------===// +//===-- Definition of macros from pthread_barrierattr_t.h -----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/libc/src/pthread/pthread_barrier_destroy.cpp b/libc/src/pthread/pthread_barrier_destroy.cpp index 6c9ae8d57ab2f..edf1513ed0a3f 100644 --- a/libc/src/pthread/pthread_barrier_destroy.cpp +++ b/libc/src/pthread/pthread_barrier_destroy.cpp @@ -1,4 +1,4 @@ -//===-- Linux implementation of the pthread_barrier_init function ---------===// +//===-- Implementation of the pthread_barrier_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. diff --git a/libc/src/pthread/pthread_barrier_init.cpp b/libc/src/pthread/pthread_barrier_init.cpp index 4317d82bc935f..01b4cb3c3fe6b 100644 --- a/libc/src/pthread/pthread_barrier_init.cpp +++ b/libc/src/pthread/pthread_barrier_init.cpp @@ -1,4 +1,4 @@ -//===-- Linux implementation of the pthread_barrier_init function ---------===// +//===-- Implementation of the pthread_barrier_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. diff --git a/libc/src/pthread/pthread_barrier_wait.cpp b/libc/src/pthread/pthread_barrier_wait.cpp index 3d68c4f8938c9..141d13a0e52d5 100644 --- a/libc/src/pthread/pthread_barrier_wait.cpp +++ b/libc/src/pthread/pthread_barrier_wait.cpp @@ -1,4 +1,4 @@ -//===-- Linux implementation of the pthread_barrier_init function ---------===// +//===-- Implementation of the pthread_barrier_wait function ---------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. From 4373ef77363c199826f9ebdadf9339988ed890fc Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Tue, 22 Jul 2025 22:59:42 +0000 Subject: [PATCH 13/16] formatting --- libc/src/pthread/pthread_barrier_wait.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/src/pthread/pthread_barrier_wait.h b/libc/src/pthread/pthread_barrier_wait.h index 52eb172d6264c..16ddc06f5be6d 100644 --- a/libc/src/pthread/pthread_barrier_wait.h +++ b/libc/src/pthread/pthread_barrier_wait.h @@ -9,8 +9,8 @@ #ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_WAIT_H #define LLVM_LIBC_SRC_PTHREAD_PTHREAD_BARRIER_WAIT_H -#include "src/__support/macros/config.h" #include "hdr/types/pthread_barrier_t.h" +#include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { From 7bbd476fe64fe397d4992b587ad1f3b913d36ac2 Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Thu, 24 Jul 2025 20:32:33 +0000 Subject: [PATCH 14/16] make barrier linux-only for now as mutex/cndvars are only defined for it --- libc/src/__support/threads/CMakeLists.txt | 11 ----------- libc/src/__support/threads/linux/CMakeLists.txt | 11 +++++++++++ libc/src/__support/threads/{ => linux}/barrier.cpp | 3 +-- libc/src/__support/threads/{ => linux}/barrier.h | 0 libc/src/pthread/CMakeLists.txt | 6 +++--- libc/src/pthread/pthread_barrier_destroy.cpp | 2 +- libc/src/pthread/pthread_barrier_init.cpp | 2 +- libc/src/pthread/pthread_barrier_wait.cpp | 2 +- 8 files changed, 18 insertions(+), 19 deletions(-) rename libc/src/__support/threads/{ => linux}/barrier.cpp (97%) rename libc/src/__support/threads/{ => linux}/barrier.h (100%) diff --git a/libc/src/__support/threads/CMakeLists.txt b/libc/src/__support/threads/CMakeLists.txt index 3cf50b6d3f8a9..bd49bbb5ad2fe 100644 --- a/libc/src/__support/threads/CMakeLists.txt +++ b/libc/src/__support/threads/CMakeLists.txt @@ -90,17 +90,6 @@ if(TARGET libc.src.__support.threads.${LIBC_TARGET_OS}.CndVar) ) endif() -add_object_library( - barrier - HDRS - barrier.h - SRCS - barrier.cpp - DEPENDS - .CndVar - .mutex -) - if (LLVM_LIBC_FULL_BUILD) set(identifier_dependency_on_thread libc.src.__support.threads.thread) endif() diff --git a/libc/src/__support/threads/linux/CMakeLists.txt b/libc/src/__support/threads/linux/CMakeLists.txt index 364e7e2b90585..a59efb62fdc41 100644 --- a/libc/src/__support/threads/linux/CMakeLists.txt +++ b/libc/src/__support/threads/linux/CMakeLists.txt @@ -121,3 +121,14 @@ add_object_library( libc.src.__support.threads.linux.raw_mutex libc.src.__support.CPP.mutex ) + +add_object_library( + barrier + HDRS + barrier.h + SRCS + barrier.cpp + DEPENDS + libc.src.__support.threads.CndVar + libc.src.__support.threads.mutex +) diff --git a/libc/src/__support/threads/barrier.cpp b/libc/src/__support/threads/linux/barrier.cpp similarity index 97% rename from libc/src/__support/threads/barrier.cpp rename to libc/src/__support/threads/linux/barrier.cpp index e39fb17637633..ff40775b06ee7 100644 --- a/libc/src/__support/threads/barrier.cpp +++ b/libc/src/__support/threads/linux/barrier.cpp @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/__support/threads/barrier.h" -#include "barrier.h" +#include "src/__support/threads/linux/barrier.h" #include "hdr/errno_macros.h" #include "src/__support/threads/CndVar.h" #include "src/__support/threads/mutex.h" diff --git a/libc/src/__support/threads/barrier.h b/libc/src/__support/threads/linux/barrier.h similarity index 100% rename from libc/src/__support/threads/barrier.h rename to libc/src/__support/threads/linux/barrier.h diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt index e5a0a34cf46a6..4db6e3e85fe71 100644 --- a/libc/src/pthread/CMakeLists.txt +++ b/libc/src/pthread/CMakeLists.txt @@ -280,7 +280,7 @@ add_entrypoint_object( DEPENDS libc.src.errno.errno libc.include.pthread - libc.src.__support.threads.barrier + libc.src.__support.threads.linux.barrier ) add_entrypoint_object( @@ -291,7 +291,7 @@ add_entrypoint_object( pthread_barrier_destroy.h DEPENDS libc.include.pthread - libc.src.__support.threads.barrier + libc.src.__support.threads.linux.barrier ) add_entrypoint_object( @@ -302,7 +302,7 @@ add_entrypoint_object( pthread_barrier_wait.h DEPENDS libc.include.pthread - libc.src.__support.threads.barrier + libc.src.__support.threads.linux.barrier ) add_entrypoint_object( diff --git a/libc/src/pthread/pthread_barrier_destroy.cpp b/libc/src/pthread/pthread_barrier_destroy.cpp index edf1513ed0a3f..82de8f2741862 100644 --- a/libc/src/pthread/pthread_barrier_destroy.cpp +++ b/libc/src/pthread/pthread_barrier_destroy.cpp @@ -11,7 +11,7 @@ #include "hdr/types/pthread_barrier_t.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" -#include "src/__support/threads/barrier.h" +#include "src/__support/threads/linux/barrier.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/pthread/pthread_barrier_init.cpp b/libc/src/pthread/pthread_barrier_init.cpp index 01b4cb3c3fe6b..2e92238a49243 100644 --- a/libc/src/pthread/pthread_barrier_init.cpp +++ b/libc/src/pthread/pthread_barrier_init.cpp @@ -12,7 +12,7 @@ #include "hdr/types/pthread_barrierattr_t.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" -#include "src/__support/threads/barrier.h" +#include "src/__support/threads/linux/barrier.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/pthread/pthread_barrier_wait.cpp b/libc/src/pthread/pthread_barrier_wait.cpp index 141d13a0e52d5..dbd1333a2aa3b 100644 --- a/libc/src/pthread/pthread_barrier_wait.cpp +++ b/libc/src/pthread/pthread_barrier_wait.cpp @@ -11,7 +11,7 @@ #include "hdr/types/pthread_barrier_t.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" -#include "src/__support/threads/barrier.h" +#include "src/__support/threads/linux/barrier.h" namespace LIBC_NAMESPACE_DECL { From 1e8006377d5b4a730c1fd1924278f2e567fd7a8c Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Fri, 25 Jul 2025 19:50:21 +0000 Subject: [PATCH 15/16] remove unnecesary braces --- libc/src/__support/threads/linux/barrier.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libc/src/__support/threads/linux/barrier.cpp b/libc/src/__support/threads/linux/barrier.cpp index ff40775b06ee7..cf7207b53094b 100644 --- a/libc/src/__support/threads/linux/barrier.cpp +++ b/libc/src/__support/threads/linux/barrier.cpp @@ -44,16 +44,14 @@ int Barrier::wait() { m.lock(); // if the barrier is emptying out threads, wait until it finishes - while (!blocking) { + while (!blocking) entering.wait(&m); - } waiting++; if (waiting < expected) { // block threads until waiting = expected - while (blocking) { + while (blocking) exiting.wait(&m); - } } else { // this is the last thread to call wait(), so lets wake everyone up blocking = false; From 86b9074f95de14cc0717370a62d256b603501f18 Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Mon, 28 Jul 2025 16:40:33 +0000 Subject: [PATCH 16/16] remove extra header + force size of public barrier type to be exactly equal to internal class --- libc/src/__support/threads/linux/barrier.h | 2 +- libc/test/integration/src/pthread/pthread_barrier_test.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libc/src/__support/threads/linux/barrier.h b/libc/src/__support/threads/linux/barrier.h index aae811a70e41c..f0655bfc52a10 100644 --- a/libc/src/__support/threads/linux/barrier.h +++ b/libc/src/__support/threads/linux/barrier.h @@ -37,7 +37,7 @@ class Barrier { }; static_assert( - sizeof(Barrier) <= sizeof(pthread_barrier_t), + sizeof(Barrier) == sizeof(pthread_barrier_t), "The public pthread_barrier_t type cannot accommodate the internal " "barrier type."); diff --git a/libc/test/integration/src/pthread/pthread_barrier_test.cpp b/libc/test/integration/src/pthread/pthread_barrier_test.cpp index 2ba4d3ac22897..c8e11047e1d80 100644 --- a/libc/test/integration/src/pthread/pthread_barrier_test.cpp +++ b/libc/test/integration/src/pthread/pthread_barrier_test.cpp @@ -17,7 +17,6 @@ #include "src/pthread/pthread_mutex_init.h" #include "src/pthread/pthread_mutex_lock.h" #include "src/pthread/pthread_mutex_unlock.h" -#include "src/stdio/printf.h" #include "src/string/memset.h" #include "test/IntegrationTest/test.h"