I glanced, nothing looks wrong.. is there any reference/documentation for the barrier implementation?
On Fri, Feb 14, 2014 at 8:07 AM, Sebastian Huber <sebastian.hu...@embedded-brains.de> wrote: > --- > cpukit/score/Makefile.am | 2 + > cpukit/score/include/rtems/score/smpbarrier.h | 125 > +++++++++++++++++++++++++ > cpukit/score/preinstall.am | 4 + > cpukit/score/src/smpbarrierwait.c | 48 ++++++++++ > testsuites/smptests/smpatomic01/init.c | 48 +--------- > testsuites/smptests/smplock01/init.c | 66 +++---------- > 6 files changed, 195 insertions(+), 98 deletions(-) > create mode 100644 cpukit/score/include/rtems/score/smpbarrier.h > create mode 100644 cpukit/score/src/smpbarrierwait.c > > diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am > index 267e8b2..482e78d 100644 > --- a/cpukit/score/Makefile.am > +++ b/cpukit/score/Makefile.am > @@ -59,6 +59,7 @@ include_rtems_score_HEADERS += > include/rtems/score/schedulersimpleimpl.h > include_rtems_score_HEADERS += include/rtems/score/schedulersmp.h > include_rtems_score_HEADERS += include/rtems/score/schedulersmpimpl.h > include_rtems_score_HEADERS += include/rtems/score/smp.h > +include_rtems_score_HEADERS += include/rtems/score/smpbarrier.h > include_rtems_score_HEADERS += include/rtems/score/smplock.h > include_rtems_score_HEADERS += include/rtems/score/stack.h > include_rtems_score_HEADERS += include/rtems/score/stackimpl.h > @@ -276,6 +277,7 @@ libscore_a_SOURCES += src/thread.c > src/threadchangepriority.c \ > src/threadblockingoperationcancel.c > > if HAS_SMP > +libscore_a_SOURCES += src/smpbarrierwait.c > libscore_a_SOURCES += src/threaddispatchdisablelevel.c > endif > > diff --git a/cpukit/score/include/rtems/score/smpbarrier.h > b/cpukit/score/include/rtems/score/smpbarrier.h > new file mode 100644 > index 0000000..fe9a1cf > --- /dev/null > +++ b/cpukit/score/include/rtems/score/smpbarrier.h > @@ -0,0 +1,125 @@ > +/** > + * @file > + * > + * @ingroup ScoreSMPBarrier > + * > + * @brief SMP Barrier API > + */ > + > +/* > + * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. > + * > + * embedded brains GmbH > + * Dornierstr. 4 > + * 82178 Puchheim > + * Germany > + * <rt...@embedded-brains.de> > + * > + * The license and distribution terms for this file may be > + * found in the file LICENSE in this distribution or at > + * http://www.rtems.com/license/LICENSE. > + */ > + > +#ifndef _RTEMS_SCORE_SMPBARRIER_H > +#define _RTEMS_SCORE_SMPBARRIER_H > + > +#include <rtems/score/cpuopts.h> > + > +#if defined( RTEMS_SMP ) > + > +#include <rtems/score/atomic.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif /* __cplusplus */ > + > +/** > + * @defgroup ScoreSMPBarrier SMP Barriers > + * > + * @ingroup Score > + * > + * @brief The SMP barrier provides barrier synchronization for SMP systems at > + * the lowest level. > + * > + * The SMP barrier is implemented as a sense barrier. > + * > + * @{ > + */ > + > +/** > + * @brief SMP barrier control. > + */ > +typedef struct { > + Atomic_Uint value; > + Atomic_Uint sense; > +} SMP_barrier_Control; > + > +/** > + * @brief SMP barrier per-thread state. > + * > + * Each user of the barrier must provide this per-thread state. > + */ > +typedef struct { > + unsigned int sense; > +} SMP_barrier_State; > + > +/** > + * @brief SMP barrier control initializer for static initialization. > + */ > +#define SMP_BARRIER_CONTROL_INITIALIZER \ > + { ATOMIC_INITIALIZER_UINT( 0U ), ATOMIC_INITIALIZER_UINT( 0U ) } > + > +/** > + * @brief SMP barrier per-thread state initializer for static initialization. > + */ > +#define SMP_BARRIER_STATE_INITIALIZER { 0U } > + > +/** > + * @brief Initializes a SMP barrier control. > + * > + * Concurrent initialization leads to unpredictable results. > + * > + * @param[out] control The SMP barrier control. > + */ > +static inline void _SMP_barrier_Control_initialize( > + SMP_barrier_Control *control > +) > +{ > + _Atomic_Init_uint( &control->value, 0U ); > + _Atomic_Init_uint( &control->sense, 0U ); > +} > + > +/** > + * @brief Initializes a SMP barrier per-thread state. > + * > + * @param[out] state The SMP barrier control. > + */ > +static inline void _SMP_barrier_State_initialize( > + SMP_barrier_State *state > +) > +{ > + state->sense = 0U; > +} > + > +/** > + * @brief Waits on the SMP barrier until count threads rendezvoused. > + * > + * @param[in, out] control The SMP barrier control. > + * @param[in, out] state The SMP barrier per-thread state. > + * @param[in] count The thread count bound to rendezvous. > + */ > +void _SMP_barrier_Wait( > + SMP_barrier_Control *control, > + SMP_barrier_State *state, > + unsigned int count > +); > + > +/**@}*/ > + > +#ifdef __cplusplus > +} > +#endif /* __cplusplus */ > + > +#endif /* defined( RTEMS_SMP ) */ > + > +#endif /* _RTEMS_SCORE_SMPBARRIER_H */ > diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am > index a3c9685..ceefbe7 100644 > --- a/cpukit/score/preinstall.am > +++ b/cpukit/score/preinstall.am > @@ -219,6 +219,10 @@ $(PROJECT_INCLUDE)/rtems/score/smp.h: > include/rtems/score/smp.h $(PROJECT_INCLUD > $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/smp.h > PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/smp.h > > +$(PROJECT_INCLUDE)/rtems/score/smpbarrier.h: > include/rtems/score/smpbarrier.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) > + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/smpbarrier.h > +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/smpbarrier.h > + > $(PROJECT_INCLUDE)/rtems/score/smplock.h: include/rtems/score/smplock.h > $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) > $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/smplock.h > PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/smplock.h > diff --git a/cpukit/score/src/smpbarrierwait.c > b/cpukit/score/src/smpbarrierwait.c > new file mode 100644 > index 0000000..0a3cedb > --- /dev/null > +++ b/cpukit/score/src/smpbarrierwait.c > @@ -0,0 +1,48 @@ > +/* > + * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. > + * > + * embedded brains GmbH > + * Dornierstr. 4 > + * 82178 Puchheim > + * Germany > + * <rt...@embedded-brains.de> > + * > + * The license and distribution terms for this file may be > + * found in the file LICENSE in this distribution or at > + * http://www.rtems.com/license/LICENSE. > + */ > + > +#if HAVE_CONFIG_H > + #include "config.h" > +#endif > + > +#include <rtems/score/smpbarrier.h> > + > +void _SMP_barrier_Wait( > + SMP_barrier_Control *control, > + SMP_barrier_State *state, > + unsigned int count > +) > +{ > + unsigned int sense = ~state->sense; > + unsigned int previous_value; > + > + state->sense = sense; > + > + previous_value = _Atomic_Fetch_add_uint( > + &control->value, > + 1U, > + ATOMIC_ORDER_RELAXED > + ); > + > + if ( previous_value + 1U == count ) { > + _Atomic_Store_uint( &control->value, 0U, ATOMIC_ORDER_RELAXED ); > + _Atomic_Store_uint( &control->sense, sense, ATOMIC_ORDER_RELEASE ); > + } else { > + while ( > + _Atomic_Load_uint( &control->sense, ATOMIC_ORDER_ACQUIRE ) != sense > + ) { > + /* Wait */ > + } > + } > +} > diff --git a/testsuites/smptests/smpatomic01/init.c > b/testsuites/smptests/smpatomic01/init.c > index 2901a98..792a17b 100644 > --- a/testsuites/smptests/smpatomic01/init.c > +++ b/testsuites/smptests/smpatomic01/init.c > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. > + * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. > * > * embedded brains GmbH > * Dornierstr. 4 > @@ -19,56 +19,12 @@ > #endif > > #include <rtems/score/atomic.h> > +#include <rtems/score/smpbarrier.h> > #include <rtems.h> > #include <string.h> > > #include "tmacros.h" > > -/* FIXME: Add barrier to Score */ > - > -typedef struct { > - Atomic_Ulong value; > - Atomic_Ulong sense; > -} SMP_barrier_Control; > - > -typedef struct { > - unsigned long sense; > -} SMP_barrier_State; > - > -#define SMP_BARRIER_CONTROL_INITIALIZER \ > - { ATOMIC_INITIALIZER_ULONG( 0 ), ATOMIC_INITIALIZER_ULONG( 0 ) } > - > -#define SMP_BARRIER_STATE_INITIALIZER { 0 } > - > -static void _SMP_barrier_Wait( > - SMP_barrier_Control *control, > - SMP_barrier_State *state, > - unsigned long count > -) > -{ > - unsigned long sense = ~state->sense; > - unsigned long previous_value; > - > - state->sense = sense; > - > - previous_value = _Atomic_Fetch_add_ulong( > - &control->value, > - 1, > - ATOMIC_ORDER_RELAXED > - ); > - > - if ( previous_value + 1 == count ) { > - _Atomic_Store_ulong( &control->value, 0, ATOMIC_ORDER_RELAXED ); > - _Atomic_Store_ulong( &control->sense, sense, ATOMIC_ORDER_RELEASE ); > - } else { > - while ( > - _Atomic_Load_ulong( &control->sense, ATOMIC_ORDER_ACQUIRE ) != sense > - ) { > - /* Wait */ > - } > - } > -} > - > #define MASTER_PRIORITY 1 > > #define WORKER_PRIORITY 2 > diff --git a/testsuites/smptests/smplock01/init.c > b/testsuites/smptests/smplock01/init.c > index 6257ee1..d454487 100644 > --- a/testsuites/smptests/smplock01/init.c > +++ b/testsuites/smptests/smplock01/init.c > @@ -17,50 +17,12 @@ > #endif > > #include <rtems/score/smplock.h> > +#include <rtems/score/smpbarrier.h> > #include <rtems/score/atomic.h> > #include <rtems.h> > > #include "tmacros.h" > > -/* FIXME: Add barrier to Score */ > - > -typedef struct { > - Atomic_Uint value; > - Atomic_Uint sense; > -} barrier_control; > - > -typedef struct { > - unsigned int sense; > -} barrier_state; > - > -#define BARRIER_CONTROL_INITIALIZER \ > - { ATOMIC_INITIALIZER_UINT(0), ATOMIC_INITIALIZER_UINT(0) } > - > -#define BARRIER_STATE_INITIALIZER { 0 } > - > -static void barrier_wait( > - barrier_control *control, > - barrier_state *state, > - unsigned int cpu_count > -) > -{ > - unsigned int sense = ~state->sense; > - unsigned int value; > - > - state->sense = sense; > - > - value = _Atomic_Fetch_add_uint(&control->value, 1, ATOMIC_ORDER_RELAXED); > - > - if (value + 1 == cpu_count) { > - _Atomic_Store_uint(&control->value, 0, ATOMIC_ORDER_RELAXED); > - _Atomic_Store_uint(&control->sense, sense, ATOMIC_ORDER_RELEASE); > - } else { > - while (_Atomic_Load_uint(&control->sense, ATOMIC_ORDER_ACQUIRE) != > sense) { > - /* Wait */ > - } > - } > -} > - > #define TASK_PRIORITY 1 > > #define CPU_COUNT 32 > @@ -75,7 +37,7 @@ typedef enum { > > typedef struct { > Atomic_Uint state; > - barrier_control barrier; > + SMP_barrier_Control barrier; > rtems_id timer_id; > rtems_interval timeout; > unsigned long counter[TEST_COUNT]; > @@ -85,7 +47,7 @@ typedef struct { > > static global_context context = { > .state = ATOMIC_INITIALIZER_UINT(INITIAL), > - .barrier = BARRIER_CONTROL_INITIALIZER, > + .barrier = SMP_BARRIER_CONTROL_INITIALIZER, > .lock = SMP_LOCK_INITIALIZER > }; > > @@ -121,7 +83,7 @@ static bool assert_state(global_context *ctx, int > desired_state) > typedef void (*test_body)( > int test, > global_context *ctx, > - barrier_state *bs, > + SMP_barrier_State *bs, > unsigned int cpu_count, > unsigned int cpu_self > ); > @@ -129,7 +91,7 @@ typedef void (*test_body)( > static void test_0_body( > int test, > global_context *ctx, > - barrier_state *bs, > + SMP_barrier_State *bs, > unsigned int cpu_count, > unsigned int cpu_self > ) > @@ -148,7 +110,7 @@ static void test_0_body( > static void test_1_body( > int test, > global_context *ctx, > - barrier_state *bs, > + SMP_barrier_State *bs, > unsigned int cpu_count, > unsigned int cpu_self > ) > @@ -168,7 +130,7 @@ static void test_1_body( > static void test_2_body( > int test, > global_context *ctx, > - barrier_state *bs, > + SMP_barrier_State *bs, > unsigned int cpu_count, > unsigned int cpu_self > ) > @@ -188,7 +150,7 @@ static void test_2_body( > static void test_3_body( > int test, > global_context *ctx, > - barrier_state *bs, > + SMP_barrier_State *bs, > unsigned int cpu_count, > unsigned int cpu_self > ) > @@ -221,7 +183,7 @@ static void busy_section(void) > static void test_4_body( > int test, > global_context *ctx, > - barrier_state *bs, > + SMP_barrier_State *bs, > unsigned int cpu_count, > unsigned int cpu_self > ) > @@ -248,7 +210,7 @@ static const test_body test_bodies[TEST_COUNT] = { > > static void run_tests( > global_context *ctx, > - barrier_state *bs, > + SMP_barrier_State *bs, > unsigned int cpu_count, > unsigned int cpu_self, > bool master > @@ -257,7 +219,7 @@ static void run_tests( > int test; > > for (test = 0; test < TEST_COUNT; ++test) { > - barrier_wait(&ctx->barrier, bs, cpu_count); > + _SMP_barrier_Wait(&ctx->barrier, bs, cpu_count); > > if (master) { > rtems_status_code sc = rtems_timer_fire_after( > @@ -276,7 +238,7 @@ static void run_tests( > (*test_bodies[test])(test, ctx, bs, cpu_count, cpu_self); > } > > - barrier_wait(&ctx->barrier, bs, cpu_count); > + _SMP_barrier_Wait(&ctx->barrier, bs, cpu_count); > } > > static void task(rtems_task_argument arg) > @@ -285,7 +247,7 @@ static void task(rtems_task_argument arg) > uint32_t cpu_count = rtems_smp_get_processor_count(); > uint32_t cpu_self = rtems_smp_get_current_processor(); > rtems_status_code sc; > - barrier_state bs = BARRIER_STATE_INITIALIZER; > + SMP_barrier_State bs = SMP_BARRIER_STATE_INITIALIZER; > > run_tests(ctx, &bs, cpu_count, cpu_self, false); > > @@ -301,7 +263,7 @@ static void test(void) > uint32_t cpu; > int test; > rtems_status_code sc; > - barrier_state bs = BARRIER_STATE_INITIALIZER; > + SMP_barrier_State bs = SMP_BARRIER_STATE_INITIALIZER; > > for (cpu = 0; cpu < cpu_count; ++cpu) { > if (cpu != cpu_self) { > -- > 1.7.7 > > _______________________________________________ > rtems-devel mailing list > rtems-devel@rtems.org > http://www.rtems.org/mailman/listinfo/rtems-devel _______________________________________________ rtems-devel mailing list rtems-devel@rtems.org http://www.rtems.org/mailman/listinfo/rtems-devel