[PATCH 2/2] add smprwlock implementation based on phase-fairness lock

WeiY wei.a.yang at gmail.com
Sat Aug 31 01:49:18 UTC 2013


---
 cpukit/score/Makefile.am                     |    1 +
 cpukit/score/include/rtems/score/smprwlock.h |  219 ++++++++++++++++++++++++++
 cpukit/score/preinstall.am                   |    4 +
 3 files changed, 224 insertions(+)
 create mode 100644 cpukit/score/include/rtems/score/smprwlock.h

diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index c9d2d47..c0b7939 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -86,6 +86,7 @@ include_rtems_score_HEADERS += include/rtems/score/basedefs.h
 if ATOMIC
 include_rtems_score_HEADERS += include/rtems/score/atomic.h
 include_rtems_score_HEADERS += include/rtems/score/cpustdatomic.h
+include_rtems_score_HEADERS += include/rtems/score/smprwlock.h
 endif
 
 if HAS_PTHREADS
diff --git a/cpukit/score/include/rtems/score/smprwlock.h b/cpukit/score/include/rtems/score/smprwlock.h
new file mode 100644
index 0000000..0781f80
--- /dev/null
+++ b/cpukit/score/include/rtems/score/smprwlock.h
@@ -0,0 +1,219 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSMPRWlock
+ *
+ * @brief SMP Lock API
+ */
+
+/*
+ * COPYRIGHT (c) 2012-2013 Deng Hengyi.
+ *
+ * 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_SMPRWLOCK_H
+#define _RTEMS_SCORE_SMPRWLOCK_H
+
+#include <rtems/score/cpuopts.h>
+
+#if defined( RTEMS_SMP )
+
+#include <rtems/rtems/atomic.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreSMPRWlock SMP Locks
+ *
+ * @ingroup Score
+ *
+ * The SMP rw lock implementation is architecture dependent. Now the rw lock
+ * is based on the implementation of phase-fairness lock. The phase-fairness
+ * lock use atomic ops to implement. So the architectures which do not support
+ * atomic ops will not use it.
+ *
+ * Phase-fair reader writer locks is a new class of reader-writer locks.
+ * Phase-fair rw lock has the following properties:
+ * 1.  Reader phases and writer phases alternate.
+ * 2.  Writers are subject to FIFO ordering, but only with regard to other
+ *     writers.
+ * 3.  At the start of each reader phase, all currently-unsatisfied read
+ *     requests are satisfied (exactly one write request is satisfied at
+ *     the start of a writer phase)
+ * 4.  And during a reader phase, newly-issued read requests are satisfied
+ *     only if there are no unsatisfied write requests pending.
+ *
+ * In some sense, phase-fair locks can be understood as being a reader
+ * preference lock when held by a writer, and being a writer preference
+ * lock when held by readers, i.e., readers and writers are “polite” and
+ * yield to each other. For example:
+ *
+ * 1.  T1-> thread1 issues a read request then satisfied.
+ * 2.  T2-> thread2 issues a write request then unsatisfied(because thread1
+ *     in read phase).
+ * 3.  T3-> thread3 issues a read request then unsatisfied(because thread2
+ *     writer already wait).
+ * 4.  T4-> thread4 issues a write request then unsatisfied(wait in FIFO order
+ *     regard to thread2)
+ * 5.  T5-> thread1 releases read lock and then thread2 write request satisfied.
+ * 6.  T6-> thread5 issues a read request then unsatisfied.
+ * 7.  T7-> thread2 releases write lock and then thread3 and thread5 read
+ *     request satisfied at the same time.
+ * 8.  T8-> thread3 and thread5 release their read lock, then thread1 write
+ *     request satisfied.
+ *
+ * Reference:
+ *
+ * 1: http://www.mpi-sws.org/~bbb/papers/pdf/rtsj11.pdf
+ *    Brandenburg, B. and Anderson, J. 2010. Spin-Based
+ *    Reader-Writer Synchronization for Multiprocessor Real-Time Systems
+ *
+ * 2: http://concurrencykit.org/cgit/cgit.cgi/ck/tree/include/ck_pflock.h
+ *
+ * @{
+ */
+
+/**
+ * @brief SMP rw lock control.
+ *
+ * This is used by phase-fairness lock.
+ */
+typedef struct {
+	Atomic_Uint rin;
+	Atomic_Uint rout;
+	Atomic_Uint win;
+	Atomic_Uint wout;
+} SMP_rwlock_Control;
+
+/**
+ * @brief SMP rw lock control macro.
+ */
+#define SMP_RWLOCK_LSB   0xFFFFFFF0
+#define SMP_RWLOCK_RINC  0x100 /* Reader increment value. */
+#define SMP_RWLOCK_WBITS 0x3   /* Writer bits in reader. */
+#define SMP_RWLOCK_PRES  0x2   /* Writer present bit. */
+#define SMP_RWLOCK_PHID  0x1   /* Phase ID bit. */
+
+/**
+ * @brief SMP rwlock control initializer for static initialization.
+ */
+#define SMP_RWLOCK_INITIALIZER { ATOMIC_INITIALIZER_UINT( 0 ), \
+                                 ATOMIC_INITIALIZER_UINT( 0 ), \
+                                 ATOMIC_INITIALIZER_UINT( 0 ), \
+                                 ATOMIC_INITIALIZER_UINT( 0 ) }
+
+/**
+ * @brief Initializes a SMP rwlock control.
+ *
+ * Concurrent initialization leads to unpredictable results.
+ *
+ * @param[out] lock The SMP rwlock control.
+ */
+static inline void _SMP_rwlock_Initialize( SMP_rwlock_Control *lock )
+{
+  _Atomic_Init_uint( &(lock->rin), 0 );
+  _Atomic_Init_uint( &(lock->rout), 0 );
+  _Atomic_Init_uint( &(lock->win), 0 );
+  _Atomic_Init_uint( &(lock->wout), 0 );
+}
+
+/**
+ * @brief Acquires a SMP rwlock for read.
+ *
+ * This function will implementation phase-fairness read lock.
+ *
+ * @param[in,out] lock The SMP rwlock control.
+ */
+static inline void _SMP_rwlock_Acquire_read( SMP_rwlock_Control *lock )
+{
+  uint_fast32_t w;
+
+  /*
+   * If no writer is present, then the operation has completed
+   * successfully.
+   */
+  w = _Atomic_Fetch_add_uint(&lock->rin, SMP_RWLOCK_RINC, ATOMIC_ORDER_ACQUIRE)
+                             & SMP_RWLOCK_WBITS;
+  if (w == 0)
+    return;
+
+  /* Wait for current write phase to complete. */
+  while ((_Atomic_Load_uint(&lock->rin, ATOMIC_ORDER_ACQUIRE)
+  	     & SMP_RWLOCK_WBITS) == w);
+
+  return;
+}
+
+/**
+ * @brief Releases a SMP rwlock for read.
+ *
+ * @param[in,out] lock The SMP rwlock control.
+ */
+static inline void _SMP_rwlock_Release_read( SMP_rwlock_Control *lock )
+{
+  _Atomic_Fetch_add_uint(&lock->rout, SMP_RWLOCK_RINC, ATOMIC_ORDER_RELEASE);
+  
+  return;
+}
+
+/**
+ * @brief Acquires a SMP rwlock for write.
+ *
+ * This function will implementation phase-fairness write lock.
+ *
+ * @param[in,out] lock The SMP rwlock control.
+ */
+static inline void _SMP_rwlock_Acquire_write( SMP_rwlock_Control *lock )
+{
+  uint_fast32_t ticket;
+
+  /* Acquire ownership of write-phase. */
+  ticket = _Atomic_Fetch_add_uint(&lock->win, 1, ATOMIC_ORDER_RELEASE);
+
+  while (_Atomic_Load_uint(&lock->wout, ATOMIC_ORDER_ACQUIRE) != ticket);
+
+  /*
+   * Acquire ticket on read-side in order to allow them
+   * to flush. Indicates to any incoming reader that a
+   * write-phase is pending.
+   */
+  ticket = _Atomic_Fetch_add_uint(&lock->rin,
+                    (ticket & SMP_RWLOCK_PHID) | SMP_RWLOCK_PRES,
+                    ATOMIC_ORDER_RELEASE);
+
+  /* Wait for any pending readers to flush. */
+  while (_Atomic_Load_uint(&lock->rout, ATOMIC_ORDER_ACQUIRE) != ticket);
+
+  return;
+}
+
+/**
+ * @brief Releases a SMP rwlock for write.
+ *
+ * @param[in,out] lock The SMP rwlock control.
+ */
+static inline void _SMP_rwlock_Release_write( SMP_rwlock_Control *lock )
+{
+  /* Migrate from write phase to read phase. */
+  _Atomic_Fetch_and_uint(&lock->rin, SMP_RWLOCK_LSB, ATOMIC_ORDER_RELEASE);
+
+  /* Allow other writers to continue. */
+  _Atomic_Fetch_add_uint(&lock->wout, 1, ATOMIC_ORDER_RELEASE);
+
+  return;
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* defined( RTEMS_SMP ) */
+
+#endif /* _RTEMS_SCORE_SMPRWLOCK_H */
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
index 79a18b5..3c22c8e 100644
--- a/cpukit/score/preinstall.am
+++ b/cpukit/score/preinstall.am
@@ -323,6 +323,10 @@ PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/atomic.h
 $(PROJECT_INCLUDE)/rtems/score/cpustdatomic.h: include/rtems/score/cpustdatomic.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpustdatomic.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpustdatomic.h
+
+$(PROJECT_INCLUDE)/rtems/score/smprwlock.h: include/rtems/score/smprwlock.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/smprwlock.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/smprwlock.h
 endif
 if HAS_PTHREADS
 $(PROJECT_INCLUDE)/rtems/score/corespinlock.h: include/rtems/score/corespinlock.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
-- 
1.7.9.5




More information about the devel mailing list