summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-18 13:44:02 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-19 11:50:35 +0200
commita7668b2a881a54c04de43e3f7b9c5ea5ee2b14c8 (patch)
tree1c60a5aecb64606758caceab1f6ca9d3656d38bc /cpukit
parentSMP: Move lock stats to separate header file (diff)
downloadrtems-a7668b2a881a54c04de43e3f7b9c5ea5ee2b14c8.tar.bz2
SMP: Move ticket lock to separate header file
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/score/Makefile.am1
-rw-r--r--cpukit/score/include/rtems/score/smplock.h161
-rw-r--r--cpukit/score/include/rtems/score/smplockticket.h202
-rw-r--r--cpukit/score/preinstall.am4
4 files changed, 208 insertions, 160 deletions
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 0e7ee35e59..80eafc4085 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -130,6 +130,7 @@ include_rtems_score_HEADERS += include/rtems/score/schedulerpriorityaffinitysmp.
include_rtems_score_HEADERS += include/rtems/score/schedulersimplesmp.h
include_rtems_score_HEADERS += include/rtems/score/schedulerstrongapa.h
include_rtems_score_HEADERS += include/rtems/score/smplockstats.h
+include_rtems_score_HEADERS += include/rtems/score/smplockticket.h
endif
## src
diff --git a/cpukit/score/include/rtems/score/smplock.h b/cpukit/score/include/rtems/score/smplock.h
index f4196fe1f7..173df18754 100644
--- a/cpukit/score/include/rtems/score/smplock.h
+++ b/cpukit/score/include/rtems/score/smplock.h
@@ -25,7 +25,7 @@
#if defined(RTEMS_SMP)
#include <rtems/score/smplockstats.h>
-#include <rtems/score/atomic.h>
+#include <rtems/score/smplockticket.h>
#include <rtems/score/isrlevel.h>
#if defined(RTEMS_PROFILING) || defined(RTEMS_DEBUG)
@@ -55,165 +55,6 @@ extern "C" {
*/
/**
- * @brief SMP ticket lock control.
- */
-typedef struct {
- Atomic_Uint next_ticket;
- Atomic_Uint now_serving;
-} SMP_ticket_lock_Control;
-
-/**
- * @brief SMP ticket lock control initializer for static initialization.
- */
-#define SMP_TICKET_LOCK_INITIALIZER \
- { \
- ATOMIC_INITIALIZER_UINT( 0U ), \
- ATOMIC_INITIALIZER_UINT( 0U ) \
- }
-
-/**
- * @brief Initializes an SMP ticket lock.
- *
- * Concurrent initialization leads to unpredictable results.
- *
- * @param[in] lock The SMP ticket lock control.
- * @param[in] name The name for the SMP ticket lock. This name must be
- * persistent throughout the life time of this lock.
- */
-static inline void _SMP_ticket_lock_Initialize(
- SMP_ticket_lock_Control *lock
-)
-{
- _Atomic_Init_uint( &lock->next_ticket, 0U );
- _Atomic_Init_uint( &lock->now_serving, 0U );
-}
-
-/**
- * @brief Destroys an SMP ticket lock.
- *
- * Concurrent destruction leads to unpredictable results.
- *
- * @param[in] lock The SMP ticket lock control.
- */
-static inline void _SMP_ticket_lock_Destroy( SMP_ticket_lock_Control *lock )
-{
- (void) lock;
-}
-
-static inline void _SMP_ticket_lock_Do_acquire(
- SMP_ticket_lock_Control *lock
-#if defined(RTEMS_PROFILING)
- ,
- SMP_lock_Stats *stats,
- SMP_lock_Stats_context *stats_context
-#endif
-)
-{
- unsigned int my_ticket;
- unsigned int now_serving;
-
-#if defined(RTEMS_PROFILING)
- CPU_Counter_ticks first;
- CPU_Counter_ticks second;
- CPU_Counter_ticks delta;
- unsigned int initial_queue_length;
-
- first = _CPU_Counter_read();
-#endif
-
- my_ticket =
- _Atomic_Fetch_add_uint( &lock->next_ticket, 1U, ATOMIC_ORDER_RELAXED );
-
-#if defined(RTEMS_PROFILING)
- now_serving =
- _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_ACQUIRE );
- initial_queue_length = my_ticket - now_serving;
-
- if ( initial_queue_length > 0 ) {
-#endif
-
- do {
- now_serving =
- _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_ACQUIRE );
- } while ( now_serving != my_ticket );
-
-#if defined(RTEMS_PROFILING)
- }
-
- second = _CPU_Counter_read();
- stats_context->acquire_instant = second;
- delta = _CPU_Counter_difference( second, first );
-
- ++stats->usage_count;
-
- stats->total_acquire_time += delta;
-
- if ( stats->max_acquire_time < delta ) {
- stats->max_acquire_time = delta;
- }
-
- if ( initial_queue_length >= SMP_LOCK_STATS_CONTENTION_COUNTS ) {
- initial_queue_length = SMP_LOCK_STATS_CONTENTION_COUNTS - 1;
- }
- ++stats->contention_counts[initial_queue_length];
-
- stats_context->stats = stats;
-#endif
-}
-
-/**
- * @brief Acquires an SMP ticket lock.
- *
- * This function will not disable interrupts. The caller must ensure that the
- * current thread of execution is not interrupted indefinite once it obtained
- * the SMP ticket lock.
- *
- * @param[in] lock The SMP ticket lock control.
- * @param[in] stats The SMP lock statistics.
- * @param[out] stats_context The SMP lock statistics context.
- */
-#if defined(RTEMS_PROFILING)
- #define _SMP_ticket_lock_Acquire( lock, stats, stats_context ) \
- _SMP_ticket_lock_Do_acquire( lock, stats, stats_context )
-#else
- #define _SMP_ticket_lock_Acquire( lock, stats, stats_context ) \
- _SMP_ticket_lock_Do_acquire( lock )
-#endif
-
-static inline void _SMP_ticket_lock_Do_release(
- SMP_ticket_lock_Control *lock
-#if defined(RTEMS_PROFILING)
- ,
- const SMP_lock_Stats_context *stats_context
-#endif
-)
-{
- unsigned int current_ticket =
- _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_RELAXED );
- unsigned int next_ticket = current_ticket + 1U;
-
-#if defined(RTEMS_PROFILING)
- _SMP_lock_Stats_release_update( stats_context );
-#endif
-
- _Atomic_Store_uint( &lock->now_serving, next_ticket, ATOMIC_ORDER_RELEASE );
-}
-
-/**
- * @brief Releases an SMP ticket lock.
- *
- * @param[in] lock The SMP ticket lock control.
- * @param[in] stats_context The SMP lock statistics context.
- */
-#if defined(RTEMS_PROFILING)
- #define _SMP_ticket_lock_Release( lock, stats_context ) \
- _SMP_ticket_lock_Do_release( lock, stats_context )
-#else
- #define _SMP_ticket_lock_Release( lock, stats_context ) \
- _SMP_ticket_lock_Do_release( lock )
-#endif
-
-/**
* @brief SMP lock control.
*/
typedef struct {
diff --git a/cpukit/score/include/rtems/score/smplockticket.h b/cpukit/score/include/rtems/score/smplockticket.h
new file mode 100644
index 0000000000..57d541161e
--- /dev/null
+++ b/cpukit/score/include/rtems/score/smplockticket.h
@@ -0,0 +1,202 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSMPLock
+ *
+ * @brief SMP Lock API
+ */
+
+/*
+ * Copyright (c) 2013, 2016 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.
+ */
+
+#ifndef _RTEMS_SCORE_SMPLOCKTICKET_H
+#define _RTEMS_SCORE_SMPLOCKTICKET_H
+
+#include <rtems/score/cpuopts.h>
+
+#if defined(RTEMS_SMP)
+
+#include <rtems/score/atomic.h>
+#include <rtems/score/smplockstats.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreSMPLock
+ *
+ * @{
+ */
+
+/**
+ * @brief SMP ticket lock control.
+ */
+typedef struct {
+ Atomic_Uint next_ticket;
+ Atomic_Uint now_serving;
+} SMP_ticket_lock_Control;
+
+/**
+ * @brief SMP ticket lock control initializer for static initialization.
+ */
+#define SMP_TICKET_LOCK_INITIALIZER \
+ { \
+ ATOMIC_INITIALIZER_UINT( 0U ), \
+ ATOMIC_INITIALIZER_UINT( 0U ) \
+ }
+
+/**
+ * @brief Initializes an SMP ticket lock.
+ *
+ * Concurrent initialization leads to unpredictable results.
+ *
+ * @param[in] lock The SMP ticket lock control.
+ */
+static inline void _SMP_ticket_lock_Initialize(
+ SMP_ticket_lock_Control *lock
+)
+{
+ _Atomic_Init_uint( &lock->next_ticket, 0U );
+ _Atomic_Init_uint( &lock->now_serving, 0U );
+}
+
+/**
+ * @brief Destroys an SMP ticket lock.
+ *
+ * Concurrent destruction leads to unpredictable results.
+ *
+ * @param[in] lock The SMP ticket lock control.
+ */
+static inline void _SMP_ticket_lock_Destroy( SMP_ticket_lock_Control *lock )
+{
+ (void) lock;
+}
+
+static inline void _SMP_ticket_lock_Do_acquire(
+ SMP_ticket_lock_Control *lock
+#if defined(RTEMS_PROFILING)
+ ,
+ SMP_lock_Stats *stats,
+ SMP_lock_Stats_context *stats_context
+#endif
+)
+{
+ unsigned int my_ticket;
+ unsigned int now_serving;
+
+#if defined(RTEMS_PROFILING)
+ CPU_Counter_ticks first;
+ CPU_Counter_ticks second;
+ CPU_Counter_ticks delta;
+ unsigned int initial_queue_length;
+
+ first = _CPU_Counter_read();
+#endif
+
+ my_ticket =
+ _Atomic_Fetch_add_uint( &lock->next_ticket, 1U, ATOMIC_ORDER_RELAXED );
+
+#if defined(RTEMS_PROFILING)
+ now_serving =
+ _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_ACQUIRE );
+ initial_queue_length = my_ticket - now_serving;
+
+ if ( initial_queue_length > 0 ) {
+#endif
+
+ do {
+ now_serving =
+ _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_ACQUIRE );
+ } while ( now_serving != my_ticket );
+
+#if defined(RTEMS_PROFILING)
+ }
+
+ second = _CPU_Counter_read();
+ stats_context->acquire_instant = second;
+ delta = _CPU_Counter_difference( second, first );
+
+ ++stats->usage_count;
+
+ stats->total_acquire_time += delta;
+
+ if ( stats->max_acquire_time < delta ) {
+ stats->max_acquire_time = delta;
+ }
+
+ if ( initial_queue_length >= SMP_LOCK_STATS_CONTENTION_COUNTS ) {
+ initial_queue_length = SMP_LOCK_STATS_CONTENTION_COUNTS - 1;
+ }
+ ++stats->contention_counts[initial_queue_length];
+
+ stats_context->stats = stats;
+#endif
+}
+
+/**
+ * @brief Acquires an SMP ticket lock.
+ *
+ * This function will not disable interrupts. The caller must ensure that the
+ * current thread of execution is not interrupted indefinite once it obtained
+ * the SMP ticket lock.
+ *
+ * @param[in] lock The SMP ticket lock control.
+ * @param[in] stats The SMP lock statistics.
+ * @param[out] stats_context The SMP lock statistics context.
+ */
+#if defined(RTEMS_PROFILING)
+ #define _SMP_ticket_lock_Acquire( lock, stats, stats_context ) \
+ _SMP_ticket_lock_Do_acquire( lock, stats, stats_context )
+#else
+ #define _SMP_ticket_lock_Acquire( lock, stats, stats_context ) \
+ _SMP_ticket_lock_Do_acquire( lock )
+#endif
+
+static inline void _SMP_ticket_lock_Do_release(
+ SMP_ticket_lock_Control *lock
+#if defined(RTEMS_PROFILING)
+ ,
+ const SMP_lock_Stats_context *stats_context
+#endif
+)
+{
+ unsigned int current_ticket =
+ _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_RELAXED );
+ unsigned int next_ticket = current_ticket + 1U;
+
+#if defined(RTEMS_PROFILING)
+ _SMP_lock_Stats_release_update( stats_context );
+#endif
+
+ _Atomic_Store_uint( &lock->now_serving, next_ticket, ATOMIC_ORDER_RELEASE );
+}
+
+/**
+ * @brief Releases an SMP ticket lock.
+ *
+ * @param[in] lock The SMP ticket lock control.
+ * @param[in] stats_context The SMP lock statistics context.
+ */
+#if defined(RTEMS_PROFILING)
+ #define _SMP_ticket_lock_Release( lock, stats_context ) \
+ _SMP_ticket_lock_Do_release( lock, stats_context )
+#else
+ #define _SMP_ticket_lock_Release( lock, stats_context ) \
+ _SMP_ticket_lock_Do_release( lock )
+#endif
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_SMP */
+
+#endif /* _RTEMS_SCORE_SMPLOCKTICKET_H */
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
index 59c8269f07..2e89f7a981 100644
--- a/cpukit/score/preinstall.am
+++ b/cpukit/score/preinstall.am
@@ -454,4 +454,8 @@ PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerstrongapa.h
$(PROJECT_INCLUDE)/rtems/score/smplockstats.h: include/rtems/score/smplockstats.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/smplockstats.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/smplockstats.h
+
+$(PROJECT_INCLUDE)/rtems/score/smplockticket.h: include/rtems/score/smplockticket.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/smplockticket.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/smplockticket.h
endif