diff --git a/sys/posix/pthread/include/pthread_barrier.h b/sys/posix/pthread/include/pthread_barrier.h index f452405e1a..bb6fa86479 100644 --- a/sys/posix/pthread/include/pthread_barrier.h +++ b/sys/posix/pthread/include/pthread_barrier.h @@ -1,25 +1,99 @@ /* Functions to handle barriers. */ -/* Initialize BARRIER with the attributes in ATTR. The barrier is - opened when COUNT waiters arrived. */ -int pthread_barrier_init(pthread_barrier_t *barrier, - const pthread_barrierattr_t *attr, unsigned int count); +#include "mutex.h" -/* Destroy a previously dynamically initialized barrier BARRIER. */ +#define PTHREAD_PROCESS_SHARED (0) /**< Share the barrier with child processes (default). */ +#define PTHREAD_PROCESS_PRIVATE (1) /**< Do not share the barrier with child processes. */ + +/** + * @brief Internal structure to store the list of waiting threads. + */ +typedef struct pthread_barrier_waiting_node +{ + struct pthread_barrier_waiting_node *next; /**< The next waiting thread. */ + int pid; /**< The current thread to wake up. */ + volatile int cont; /**< 0 = spurious wake up, 1 = wake up */ +} pthread_barrier_waiting_node_t; + +/** + * @brief A synchronization barrier. + * @details Initialize with pthread_barrier_init(). + * For a zeroed out datum you do not need to call the initializer, it is enough to set `count`. + */ +typedef struct pthread_barrier +{ + struct pthread_barrier_waiting_node *next; /**< The first waiting thread. */ + mutex_t mutex; /**< Mutex to unlock to wake the thread up. */ + volatile int count; /**< Wait to N more threads before waking everyone up. */ +} pthread_barrier_t; + +/** + * @brief Details for a pthread_barrier_t. + * @details RIOT does not need this structure, because it is a single process OS. + * This is only here to POSIX compatibility. + */ +typedef struct pthread_barrierattr +{ + int pshared; /**< Set pthread_barrierattr_setpshared() and pthread_barrierattr_getpshared(). */ +} pthread_barrierattr_t; + +/** + * @brief Initializes a pthread_barrier_t + * @param barrier Datum to initialize + * @param attr (unused) + * @param count Number of thread to wait for + * @returns 0, the invocation cannot fail + */ +int pthread_barrier_init(pthread_barrier_t *barrier, + const pthread_barrierattr_t *attr, + unsigned int count); + +/** + * @brief Destroys a pthread_barrier_t + * @details To use the barrier again you will need to call pthread_barrier_init() again. + * Destroying a barrier while threads are currently waiting for it causes indefined behavior. + * @param barrier Barrier to destoy + * @returns 0, the invocation cannot fail + */ int pthread_barrier_destroy(pthread_barrier_t *barrier); -/* Wait on barrier BARRIER. */ +/** + * @brief Waiting on a synchronization barrier + * @details The barrier need to be initialized with pthread_barrier_init(). + * @param barrier Barrier to wait for + * @returns 0, the invocation cannot fail + */ int pthread_barrier_wait(pthread_barrier_t *barrier); -/* Initialize barrier attribute ATTR. */ +/** + * @brief Initialize a pthread_barrierattr_t + * @details A zeroed out datum is initialized. + * @param attr Datum to initialize. + * @returns 0, the invocation cannot fail + */ int pthread_barrierattr_init(pthread_barrierattr_t *attr); -/* Destroy previously dynamically initialized barrier attribute ATTR. */ +/** + * @brief Destroy a pthread_barrierattr_t + * @details This function does nothing. + * @param attr Datum to destroy + * @returns 0, the invocation cannot fail + */ int pthread_barrierattr_destroy(pthread_barrierattr_t *attr); -/* Get the process-shared flag of the barrier attribute ATTR. */ -int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, - int *pshared); +/** + * @brief Returns whether the barrier attribute was set to be shared + * @param attr Barrier attribute to read + * @param pshared The value previously stored with pthread_barrierattr_setpshared(). + * @returns 0, the invocation cannot fail + */ +int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshared); -/* Set the process-shared flag of the barrier attribute ATTR. */ +/** + * @brief Set if the barrier should be shared with child processes + * @details Since RIOT is a single process OS, pthread_barrier_init() wil ignore the value. + * @param attr Attribute set for pthread_barrier_init() + * @param pshared Either PTHREAD_PROCESS_PRIVATE or PTHREAD_PROCESS_SHARED + * @returns 0, the invocation cannot fail + */ int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared); diff --git a/sys/posix/pthread/include/pthreadtypes.h b/sys/posix/pthread/include/pthreadtypes.h index e0b92dd9b3..082acb53ce 100644 --- a/sys/posix/pthread/include/pthreadtypes.h +++ b/sys/posix/pthread/include/pthreadtypes.h @@ -19,25 +19,6 @@ typedef int pthread_once_t; /* Single execution handling. */ #define PTHREAD_ONCE_INIT 0 -typedef struct pthread_barrier_waiting_node -{ - struct pthread_barrier_waiting_node *next; - int pid; - volatile int cont; -} pthread_barrier_waiting_node_t; - -typedef struct pthread_barrier -{ - struct pthread_barrier_waiting_node *next; - mutex_t mutex; - volatile int count; -} pthread_barrier_t; - -typedef struct pthread_barrierattr -{ - int pshared; -} pthread_barrierattr_t; - typedef unsigned long int pthread_cond_t; typedef unsigned long int pthread_condattr_t;