summaryrefslogtreecommitdiffstats
path: root/cpukit/posix/src/pbarrierwait.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-09-21 14:13:16 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-10-05 14:29:01 +0200
commite67929c4c0025ef46053523be4c8736dd178cbec (patch)
tree09fca2c6ff8369031b9e76d97872da12236e155a /cpukit/posix/src/pbarrierwait.c
parentposix: Implement self-contained POSIX semaphores (diff)
downloadrtems-e67929c4c0025ef46053523be4c8736dd178cbec.tar.bz2
posix: Implement self-contained POSIX barriers
POSIX barriers are now available in all configurations and no longer depend on --enable-posix. Update #2514. Update #3114.
Diffstat (limited to 'cpukit/posix/src/pbarrierwait.c')
-rw-r--r--cpukit/posix/src/pbarrierwait.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/cpukit/posix/src/pbarrierwait.c b/cpukit/posix/src/pbarrierwait.c
index 117beac553..9719112256 100644
--- a/cpukit/posix/src/pbarrierwait.c
+++ b/cpukit/posix/src/pbarrierwait.c
@@ -9,6 +9,8 @@
* COPYRIGHT (c) 1989-2007.
* On-Line Applications Research Corporation (OAR).
*
+ * Copyright (c) 2017 embedded brains GmbH
+ *
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
@@ -21,32 +23,44 @@
#include <rtems/posix/barrierimpl.h>
#include <rtems/posix/posixapi.h>
-THREAD_QUEUE_OBJECT_ASSERT( POSIX_Barrier_Control, Barrier.Wait_queue );
-
-int pthread_barrier_wait(
- pthread_barrier_t *barrier
-)
+int pthread_barrier_wait( pthread_barrier_t *_barrier )
{
- POSIX_Barrier_Control *the_barrier;
+ POSIX_Barrier_Control *barrier;
Thread_queue_Context queue_context;
- Status_Control status;
+ Thread_Control *executing;
+ unsigned int waiting_threads;
- if ( barrier == NULL ) {
- return EINVAL;
- }
+ POSIX_BARRIER_VALIDATE_OBJECT( _barrier );
- the_barrier = _POSIX_Barrier_Get( barrier, &queue_context );
+ barrier = _POSIX_Barrier_Get( _barrier );
- if ( the_barrier == NULL ) {
- return EINVAL;
- }
+ executing = _POSIX_Barrier_Queue_acquire( barrier, &queue_context );
+ waiting_threads = barrier->waiting_threads;
+ ++waiting_threads;
- _Thread_queue_Context_set_no_timeout( &queue_context );
- status = _CORE_barrier_Seize(
- &the_barrier->Barrier,
- _Thread_Executing,
- true,
- &queue_context
- );
- return _POSIX_Get_error( status );
+ if ( waiting_threads == barrier->count ) {
+ barrier->waiting_threads = 0;
+ _Thread_queue_Flush_critical(
+ &barrier->Queue.Queue,
+ POSIX_BARRIER_TQ_OPERATIONS,
+ _Thread_queue_Flush_default_filter,
+ &queue_context
+ );
+ return PTHREAD_BARRIER_SERIAL_THREAD;
+ } else {
+ barrier->waiting_threads = waiting_threads;
+ _Thread_queue_Context_set_thread_state(
+ &queue_context,
+ STATES_WAITING_FOR_BARRIER
+ );
+ _Thread_queue_Context_set_do_nothing_enqueue_callout( &queue_context );
+ _Thread_queue_Context_set_no_timeout( &queue_context );
+ _Thread_queue_Enqueue(
+ &barrier->Queue.Queue,
+ POSIX_BARRIER_TQ_OPERATIONS,
+ executing,
+ &queue_context
+ );
+ return 0;
+ }
}