From 58d4007c829d4e9961cf709eb37bce5d8bfff95b Mon Sep 17 00:00:00 2001 From: ligr Date: Thu, 21 Nov 2024 10:50:29 +0800 Subject: [PATCH 1/3] [components/libc/posix]add comments for barrier APIs. --- .../libc/posix/pthreads/pthread_barrier.c | 86 ++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/components/libc/posix/pthreads/pthread_barrier.c b/components/libc/posix/pthreads/pthread_barrier.c index bebd25a4551..823a2158e06 100644 --- a/components/libc/posix/pthreads/pthread_barrier.c +++ b/components/libc/posix/pthreads/pthread_barrier.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2021, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -51,6 +51,31 @@ int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared) } RTM_EXPORT(pthread_barrierattr_setpshared); +/** + * @brief Destroys a barrier object. + * + * The `pthread_barrier_destroy` function releases any resources associated + * with the specified barrier object. After a barrier has been destroyed, + * it cannot be used again unless it is reinitialized using `pthread_barrier_init`. + * + * @param[in] barrier + * A pointer to an initialized `pthread_barrier_t` object to be destroyed. + * + * @return + * - `0` on success. + * - `EINVAL` if the `barrier` is invalid or uninitialized. + * - `EBUSY` if there are threads currently blocked on the barrier. + * + * @note + * - Ensure that no threads are blocked on the barrier before calling this function. + * - Attempting to destroy a barrier that is still in use results in undefined behavior. + * + * @warning + * Destroying a barrier without ensuring it is no longer in use can lead to + * resource leaks or undefined program behavior. + * + * @see pthread_barrier_init, pthread_barrier_wait + */ int pthread_barrier_destroy(pthread_barrier_t *barrier) { rt_err_t result; @@ -64,6 +89,38 @@ int pthread_barrier_destroy(pthread_barrier_t *barrier) } RTM_EXPORT(pthread_barrier_destroy); +/** + * @brief Initializes a barrier for synchronizing threads. + * + * The `pthread_barrier_init` function initializes a barrier object + * that allows a specified number of threads to synchronize at a barrier point. + * Each thread waits at the barrier until the required number of threads have called + * `pthread_barrier_wait`. + * + * @param[out] barrier + * A pointer to the `pthread_barrier_t` object to be initialized. + * This object must not already be initialized. + * + * @param[in] attr + * A pointer to a `pthread_barrierattr_t` object that specifies + * attributes for the barrier (e.g., process-shared or process-private). + * If NULL, the default attributes are used. + * + * @param[in] count + * The number of threads that must call `pthread_barrier_wait` + * before any of them successfully return from the barrier. + * + * @return + * - `0` on success. + * - `EINVAL` if the `count` is zero or `barrier` is invalid. + * + * @note The barrier must be destroyed using `pthread_barrier_destroy` + * when it is no longer needed. + * + * @warning If `count` is set to zero, the behavior is undefined. + * + * @see pthread_barrier_wait, pthread_barrier_destroy + */ int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned count) @@ -83,6 +140,33 @@ int pthread_barrier_init(pthread_barrier_t *barrier, } RTM_EXPORT(pthread_barrier_init); +/** + * @brief Synchronizes threads at a barrier. + * + * The `pthread_barrier_wait` function blocks the calling thread at the specified + * barrier until the required number of threads have reached the barrier. Once + * the required number of threads have called this function, all threads are + * unblocked and can proceed. + * + * @param[in] barrier + * A pointer to an initialized `pthread_barrier_t` object representing the barrier + * at which threads will synchronize. + * + * @return + * - `0` for all threads except one. + * - `EINVAL` - The `barrier` is invalid or uninitialized. + * + * @note + * - All threads participating in the barrier must call `pthread_barrier_wait` + * before any of them are released. + * + * @warning + * Ensure that the number of threads specified during the barrier's initialization + * matches the number of threads calling this function, otherwise the program + * may hang indefinitely. + * + * @see pthread_barrier_init, pthread_barrier_destroy + */ int pthread_barrier_wait(pthread_barrier_t *barrier) { rt_err_t result; From bd35bb1cb3f309e0ea137a7e6fd108deba9f5d59 Mon Sep 17 00:00:00 2001 From: ligr Date: Thu, 21 Nov 2024 10:54:52 +0800 Subject: [PATCH 2/3] [components/libc/posix]fix the errors that assigning an integer to a pointer and always return EINVAL. --- components/libc/posix/pthreads/pthread_barrier.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/libc/posix/pthreads/pthread_barrier.c b/components/libc/posix/pthreads/pthread_barrier.c index 823a2158e06..f2c0e2d1c3d 100644 --- a/components/libc/posix/pthreads/pthread_barrier.c +++ b/components/libc/posix/pthreads/pthread_barrier.c @@ -45,7 +45,10 @@ int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared) if (!attr) return EINVAL; if (pshared == PTHREAD_PROCESS_PRIVATE) - attr = PTHREAD_PROCESS_PRIVATE; + { + *attr = PTHREAD_PROCESS_PRIVATE; + return 0; + } return EINVAL; } From 303b575c86485e6784cfdeaea849f42cdc82c4ff Mon Sep 17 00:00:00 2001 From: ligr Date: Thu, 21 Nov 2024 11:16:21 +0800 Subject: [PATCH 3/3] [components/libc/posix]fix the problem that it doesn't check if barrier still in use and dosen't destory the mutex either. --- .../libc/posix/pthreads/pthread_barrier.c | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/components/libc/posix/pthreads/pthread_barrier.c b/components/libc/posix/pthreads/pthread_barrier.c index f2c0e2d1c3d..8802aaedbda 100644 --- a/components/libc/posix/pthreads/pthread_barrier.c +++ b/components/libc/posix/pthreads/pthread_barrier.c @@ -86,6 +86,30 @@ int pthread_barrier_destroy(pthread_barrier_t *barrier) if (!barrier) return EINVAL; + /* Lock the internal mutex to safely check the barrier's state*/ + result = pthread_mutex_lock(&(barrier->mutex)); + if (result != 0) + return result; + + /* Check if any threads are currently waiting on the barrier*/ + if (barrier->count != 0) + { + pthread_mutex_unlock(&(barrier->mutex)); + return EBUSY; /* Threads are still waiting*/ + } + + /* Free resources associated with the barrier*/ + result = pthread_mutex_unlock(&(barrier->mutex)); + if (result != 0) + { + return result; /* Return mutex unlock error*/ + } + + result = pthread_mutex_destroy(&(barrier->mutex)); + if (result != 0) + { + return result; /* Return mutex destroy error*/ + } result = pthread_cond_destroy(&(barrier->cond)); return result;