summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-14 12:57:53 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-17 08:46:38 +0100
commitad7292f26465027cb8fd5494e613f5bd63607623 (patch)
tree0ccca5c00bc4ca1a4494486f52c5d30f04f7a961 /cpukit
parentscore: Use atomic API for SMP lock (diff)
downloadrtems-ad7292f26465027cb8fd5494e613f5bd63607623.tar.bz2
score: Add SMP barrier
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/score/Makefile.am2
-rw-r--r--cpukit/score/include/rtems/score/smpbarrier.h127
-rw-r--r--cpukit/score/preinstall.am4
-rw-r--r--cpukit/score/src/smpbarrierwait.c48
4 files changed, 181 insertions, 0 deletions
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 267e8b2556..482e78de12 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 0000000000..549887d0ae
--- /dev/null
+++ b/cpukit/score/include/rtems/score/smpbarrier.h
@@ -0,0 +1,127 @@
+/**
+ * @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
+ * <rtems@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, see also Herlihy and
+ * Shavit, "The Art of Multiprocessor Programming", 17.3 Sense-Reversing
+ * 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 a3c9685dc5..ceefbe7e6e 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 0000000000..0a3cedba00
--- /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
+ * <rtems@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 */
+ }
+ }
+}