[rtems commit] SMP: Move ticket lock to separate header file

Sebastian Huber sebh at rtems.org
Thu May 19 09:51:19 UTC 2016


Module:    rtems
Branch:    master
Commit:    a7668b2a881a54c04de43e3f7b9c5ea5ee2b14c8
Changeset: http://git.rtems.org/rtems/commit/?id=a7668b2a881a54c04de43e3f7b9c5ea5ee2b14c8

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed May 18 13:44:02 2016 +0200

SMP: Move ticket lock to separate header file

---

 cpukit/score/Makefile.am                         |   1 +
 cpukit/score/include/rtems/score/smplock.h       | 161 +-----------------
 cpukit/score/include/rtems/score/smplockticket.h | 202 +++++++++++++++++++++++
 cpukit/score/preinstall.am                       |   4 +
 4 files changed, 208 insertions(+), 160 deletions(-)

diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 0e7ee35..80eafc4 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 f4196fe..173df18 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 0000000..57d5411
--- /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 59c8269..2e89f7a 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




More information about the vc mailing list