[PATCH 4/5] score: Use atomic API for SMP lock
Sebastian Huber
sebastian.huber at embedded-brains.de
Fri Feb 14 13:07:27 UTC 2014
Use a ticket lock implementation based on atomic operations. Delete CPU
port specific SMP lock implementations.
---
cpukit/score/cpu/arm/Makefile.am | 1 -
cpukit/score/cpu/arm/preinstall.am | 4 -
cpukit/score/cpu/arm/rtems/score/cpusmplock.h | 101 ------------------
cpukit/score/cpu/i386/Makefile.am | 1 -
cpukit/score/cpu/i386/preinstall.am | 4 -
cpukit/score/cpu/i386/rtems/score/cpusmplock.h | 100 -----------------
cpukit/score/cpu/no_cpu/Makefile.am | 1 -
cpukit/score/cpu/no_cpu/preinstall.am | 4 -
cpukit/score/cpu/no_cpu/rtems/score/cpusmplock.h | 118 ---------------------
cpukit/score/cpu/powerpc/Makefile.am | 1 -
cpukit/score/cpu/powerpc/preinstall.am | 4 -
cpukit/score/cpu/powerpc/rtems/score/cpusmplock.h | 95 -----------------
cpukit/score/cpu/sparc/Makefile.am | 1 -
cpukit/score/cpu/sparc/preinstall.am | 4 -
cpukit/score/cpu/sparc/rtems/score/cpusmplock.h | 105 ------------------
cpukit/score/include/rtems/score/smplock.h | 51 ++++++---
16 files changed, 36 insertions(+), 559 deletions(-)
delete mode 100644 cpukit/score/cpu/arm/rtems/score/cpusmplock.h
delete mode 100644 cpukit/score/cpu/i386/rtems/score/cpusmplock.h
delete mode 100644 cpukit/score/cpu/no_cpu/rtems/score/cpusmplock.h
delete mode 100644 cpukit/score/cpu/powerpc/rtems/score/cpusmplock.h
delete mode 100644 cpukit/score/cpu/sparc/rtems/score/cpusmplock.h
diff --git a/cpukit/score/cpu/arm/Makefile.am b/cpukit/score/cpu/arm/Makefile.am
index fe97e03..c051a48 100644
--- a/cpukit/score/cpu/arm/Makefile.am
+++ b/cpukit/score/cpu/arm/Makefile.am
@@ -10,7 +10,6 @@ include_rtems_score_HEADERS += rtems/score/armv4.h
include_rtems_score_HEADERS += rtems/score/armv7m.h
include_rtems_score_HEADERS += rtems/score/types.h
include_rtems_score_HEADERS += rtems/score/cpuatomic.h
-include_rtems_score_HEADERS += rtems/score/cpusmplock.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/cpukit/score/cpu/arm/preinstall.am b/cpukit/score/cpu/arm/preinstall.am
index 5c9c821..4213c55 100644
--- a/cpukit/score/cpu/arm/preinstall.am
+++ b/cpukit/score/cpu/arm/preinstall.am
@@ -55,7 +55,3 @@ $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h: rtems/score/cpuatomic.h $(PROJECT_IN
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h
-$(PROJECT_INCLUDE)/rtems/score/cpusmplock.h: rtems/score/cpusmplock.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
- $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h
-
diff --git a/cpukit/score/cpu/arm/rtems/score/cpusmplock.h b/cpukit/score/cpu/arm/rtems/score/cpusmplock.h
deleted file mode 100644
index 46592f4..0000000
--- a/cpukit/score/cpu/arm/rtems/score/cpusmplock.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * @file
- *
- * @ingroup ScoreSMPLockARM
- *
- * @brief ARM SMP Lock Implementation
- */
-
-/*
- * Copyright (c) 2013 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.com/license/LICENSE.
- */
-
-#ifndef _RTEMS_SCORE_ARM_SMPLOCK_H
-#define _RTEMS_SCORE_ARM_SMPLOCK_H
-
-#include <rtems/score/cpu.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/**
- * @defgroup ScoreSMPLockARM ARM SMP Locks
- *
- * @ingroup ScoreSMPLock
- *
- * A ticket lock implementation is used.
- *
- * @{
- */
-
-typedef struct {
- uint32_t next_ticket;
- uint32_t now_serving;
-} CPU_SMP_lock_Control;
-
-#define CPU_SMP_LOCK_INITIALIZER { 0, 0 }
-
-static inline void _CPU_SMP_lock_Initialize( CPU_SMP_lock_Control *lock )
-{
- lock->next_ticket = 0;
- lock->now_serving = 0;
-}
-
-static inline void _CPU_SMP_lock_Acquire( CPU_SMP_lock_Control *lock )
-{
- uint32_t my_ticket;
- uint32_t next_ticket;
- uint32_t status;
-
- __asm__ volatile (
- "1: ldrex %[my_ticket], [%[next_ticket_addr]]\n"
- "add %[next_ticket], %[my_ticket], #1\n"
- "strex %[status], %[next_ticket], [%[next_ticket_addr]]\n"
- "teq %[status], #0\n"
- "bne 1b"
- : [my_ticket] "=&r" (my_ticket),
- [next_ticket] "=&r" (next_ticket),
- [status] "=&r" (status)
- : [next_ticket_addr] "r" (&lock->next_ticket)
- : "cc", "memory"
- );
-
- while ( my_ticket != lock->now_serving ) {
- _ARM_Wait_for_event();
- }
-
- _ARM_Data_memory_barrier();
-}
-
-static inline void _CPU_SMP_lock_Release( CPU_SMP_lock_Control *lock )
-{
- _ARM_Data_memory_barrier();
- ++lock->now_serving;
- _ARM_Data_synchronization_barrier();
- _ARM_Send_event();
-}
-
-#define _CPU_SMP_lock_ISR_disable_and_acquire( lock, isr_cookie ) \
- do { \
- _CPU_ISR_Disable( isr_cookie ); \
- _CPU_SMP_lock_Acquire( lock ); \
- } while (0)
-
-#define _CPU_SMP_lock_Release_and_ISR_enable( lock, isr_cookie ) \
- do { \
- _CPU_SMP_lock_Release( lock ); \
- _CPU_ISR_Enable( isr_cookie ); \
- } while (0)
-
-/**@}*/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _RTEMS_SCORE_ARM_SMPLOCK_H */
diff --git a/cpukit/score/cpu/i386/Makefile.am b/cpukit/score/cpu/i386/Makefile.am
index bfc45c5..494cd67 100644
--- a/cpukit/score/cpu/i386/Makefile.am
+++ b/cpukit/score/cpu/i386/Makefile.am
@@ -11,7 +11,6 @@ include_rtems_score_HEADERS += rtems/score/interrupts.h
include_rtems_score_HEADERS += rtems/score/registers.h
include_rtems_score_HEADERS += rtems/score/idtr.h
include_rtems_score_HEADERS += rtems/score/cpuatomic.h
-include_rtems_score_HEADERS += rtems/score/cpusmplock.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.S
diff --git a/cpukit/score/cpu/i386/preinstall.am b/cpukit/score/cpu/i386/preinstall.am
index f9faf87..060176b 100644
--- a/cpukit/score/cpu/i386/preinstall.am
+++ b/cpukit/score/cpu/i386/preinstall.am
@@ -55,7 +55,3 @@ $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h: rtems/score/cpuatomic.h $(PROJECT_IN
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h
-$(PROJECT_INCLUDE)/rtems/score/cpusmplock.h: rtems/score/cpusmplock.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
- $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h
-
diff --git a/cpukit/score/cpu/i386/rtems/score/cpusmplock.h b/cpukit/score/cpu/i386/rtems/score/cpusmplock.h
deleted file mode 100644
index f9d36e6..0000000
--- a/cpukit/score/cpu/i386/rtems/score/cpusmplock.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * @file
- *
- * @ingroup ScoreSMPLockI386
- *
- * @brief i386 SMP Lock Implementation
- */
-
-/*
- * COPYRIGHT (c) 1989-2011.
- * On-Line Applications Research Corporation (OAR).
- *
- * Copyright (c) 2013 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.com/license/LICENSE.
- */
-
-#ifndef _RTEMS_SCORE_I386_SMPLOCK_H
-#define _RTEMS_SCORE_I386_SMPLOCK_H
-
-#include <rtems/score/cpu.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/**
- * @defgroup ScoreSMPLockI386 i386 SMP Locks
- *
- * @ingroup ScoreSMPLock
- *
- * The implementation is Test and Swap.
- *
- * @{
- */
-
-typedef struct {
- uint32_t locked;
-} CPU_SMP_lock_Control;
-
-#define CPU_SMP_LOCK_INITIALIZER { 0 }
-
-static inline void _CPU_SMP_lock_Initialize( CPU_SMP_lock_Control *lock )
-{
- lock->locked = 0;
-}
-
-static inline uint32_t _I386_Atomic_swap(
- volatile uint32_t *address,
- uint32_t value
-)
-{
- uint32_t previous;
-
- asm volatile(
- "lock; xchgl %0, %1"
- : "+m" (*address), "=a" (previous)
- : "1" (value)
- : "cc"
- );
-
- return previous;
-}
-
-static inline void _CPU_SMP_lock_Acquire( CPU_SMP_lock_Control *lock )
-{
- do {
- while ( lock->locked ) {
- RTEMS_COMPILER_MEMORY_BARRIER();
- }
- } while ( _I386_Atomic_swap( &lock->locked, 1 ) );
-}
-
-static inline void _CPU_SMP_lock_Release( CPU_SMP_lock_Control *lock )
-{
- RTEMS_COMPILER_MEMORY_BARRIER();
- lock->locked = 0;
-}
-
-#define _CPU_SMP_lock_ISR_disable_and_acquire( lock, isr_cookie ) \
- do { \
- _CPU_ISR_Disable( isr_cookie ); \
- _CPU_SMP_lock_Acquire( lock ); \
- } while (0)
-
-#define _CPU_SMP_lock_Release_and_ISR_enable( lock, isr_cookie ) \
- do { \
- _CPU_SMP_lock_Release( lock ); \
- _CPU_ISR_Enable( isr_cookie ); \
- } while (0)
-
-/**@}*/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _RTEMS_SCORE_I386_SMPLOCK_H */
diff --git a/cpukit/score/cpu/no_cpu/Makefile.am b/cpukit/score/cpu/no_cpu/Makefile.am
index 4c81257..9d89bc8 100644
--- a/cpukit/score/cpu/no_cpu/Makefile.am
+++ b/cpukit/score/cpu/no_cpu/Makefile.am
@@ -8,7 +8,6 @@ include_rtems_score_HEADERS = rtems/score/cpu.h
include_rtems_score_HEADERS += rtems/score/no_cpu.h
include_rtems_score_HEADERS += rtems/score/cpu_asm.h
include_rtems_score_HEADERS += rtems/score/types.h
-include_rtems_score_HEADERS += rtems/score/cpusmplock.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.c
diff --git a/cpukit/score/cpu/no_cpu/preinstall.am b/cpukit/score/cpu/no_cpu/preinstall.am
index a46f8b0..a56caea 100644
--- a/cpukit/score/cpu/no_cpu/preinstall.am
+++ b/cpukit/score/cpu/no_cpu/preinstall.am
@@ -43,7 +43,3 @@ $(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/r
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
-$(PROJECT_INCLUDE)/rtems/score/cpusmplock.h: rtems/score/cpusmplock.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
- $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h
-
diff --git a/cpukit/score/cpu/no_cpu/rtems/score/cpusmplock.h b/cpukit/score/cpu/no_cpu/rtems/score/cpusmplock.h
deleted file mode 100644
index 41e68af..0000000
--- a/cpukit/score/cpu/no_cpu/rtems/score/cpusmplock.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- * @file
- *
- * @ingroup ScoreSMPLockCPU
- *
- * @brief CPU SMP Lock Implementation
- */
-
-/*
- * Copyright (c) 2013 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.com/license/LICENSE.
- */
-
-#ifndef _RTEMS_SCORE_NO_CPU_SMPLOCK_H
-#define _RTEMS_SCORE_NO_CPU_SMPLOCK_H
-
-#include <rtems/score/cpu.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/**
- * @defgroup ScoreSMPLockCPU CPU SMP Locks
- *
- * @ingroup ScoreSMPLock
- *
- * This example will implement a ticket lock.
- *
- * @{
- */
-
-/**
- * @brief CPU SMP lock control.
- */
-typedef struct {
- unsigned int next_ticket;
- unsigned int now_serving;
-} CPU_SMP_lock_Control;
-
-/**
- * @brief CPU SMP lock control initializer for static initialization.
- */
-#define CPU_SMP_LOCK_INITIALIZER { 0, 0 }
-
-/**
- * @brief Initializes a CPU SMP lock control.
- *
- * @param[out] lock The CPU SMP lock control.
- */
-static inline void _CPU_SMP_lock_Initialize( CPU_SMP_lock_Control *lock )
-{
- lock->next_ticket = 0;
- lock->now_serving = 0;
-}
-
-/**
- * @brief Acquires a CPU SMP lock.
- *
- * @param[in,out] lock The CPU SMP lock control.
- */
-static inline void _CPU_SMP_lock_Acquire( CPU_SMP_lock_Control *lock )
-{
-#if 0
- unsigned int my_ticket = _Atomic_Fetch_and_increment( &lock->next_ticket );
-
- while ( _Atomic_Load_and_acquire( &lock->now_serving ) != my_ticket ) {
- _Wait_some_time();
- }
-#endif
-}
-
-/**
- * @brief Releases a CPU SMP lock.
- *
- * @param[in,out] lock The CPU SMP lock control.
- */
-static inline void _CPU_SMP_lock_Release( CPU_SMP_lock_Control *lock )
-{
-#if 0
- _Atomic_Store_and_release( &lock->now_serving, lock->now_serving + 1 );
-#endif
-}
-
-/**
- * @brief Disables interrupts and acquires the CPU SMP lock.
- *
- * @param[in,out] lock The CPU SMP lock control.
- * @param[out] isr_cookie The ISR cookie.
- */
-#define _CPU_SMP_lock_ISR_disable_and_acquire( lock, isr_cookie ) \
- do { \
- _CPU_ISR_Disable( isr_cookie ); \
- _CPU_SMP_lock_Acquire( lock ); \
- } while (0)
-
-/**
- * @brief Releases the CPU SMP lock and enables interrupts.
- *
- * @param[in,out] lock The CPU SMP lock control.
- * @param[in] isr_cookie The ISR cookie.
- */
-#define _CPU_SMP_lock_Release_and_ISR_enable( lock, isr_cookie ) \
- do { \
- _CPU_SMP_lock_Release( lock ); \
- _CPU_ISR_Enable( isr_cookie ); \
- } while (0)
-
-/**@}*/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _RTEMS_SCORE_NO_CPU_SMPLOCK_H */
diff --git a/cpukit/score/cpu/powerpc/Makefile.am b/cpukit/score/cpu/powerpc/Makefile.am
index f5664a3..b205762 100644
--- a/cpukit/score/cpu/powerpc/Makefile.am
+++ b/cpukit/score/cpu/powerpc/Makefile.am
@@ -8,7 +8,6 @@ include_rtems_score_HEADERS = rtems/score/powerpc.h
include_rtems_score_HEADERS += rtems/score/cpu.h
include_rtems_score_HEADERS += rtems/score/types.h
include_rtems_score_HEADERS += rtems/score/cpuatomic.h
-include_rtems_score_HEADERS += rtems/score/cpusmplock.h
include_rtems_powerpcdir = $(includedir)/rtems/powerpc
include_rtems_powerpc_HEADERS = rtems/powerpc/registers.h
diff --git a/cpukit/score/cpu/powerpc/preinstall.am b/cpukit/score/cpu/powerpc/preinstall.am
index 1d7fd8b..3293498 100644
--- a/cpukit/score/cpu/powerpc/preinstall.am
+++ b/cpukit/score/cpu/powerpc/preinstall.am
@@ -43,10 +43,6 @@ $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h: rtems/score/cpuatomic.h $(PROJECT_IN
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h
-$(PROJECT_INCLUDE)/rtems/score/cpusmplock.h: rtems/score/cpusmplock.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
- $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h
-
$(PROJECT_INCLUDE)/rtems/powerpc/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/rtems/powerpc
@: > $(PROJECT_INCLUDE)/rtems/powerpc/$(dirstamp)
diff --git a/cpukit/score/cpu/powerpc/rtems/score/cpusmplock.h b/cpukit/score/cpu/powerpc/rtems/score/cpusmplock.h
deleted file mode 100644
index f5ff962..0000000
--- a/cpukit/score/cpu/powerpc/rtems/score/cpusmplock.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file
- *
- * @ingroup ScoreSMPLockPowerPC
- *
- * @brief PowerPC SMP Lock Implementation
- */
-
-/*
- * Copyright (c) 2013 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.com/license/LICENSE.
- */
-
-#ifndef _RTEMS_SCORE_POWERPC_SMPLOCK_H
-#define _RTEMS_SCORE_POWERPC_SMPLOCK_H
-
-#include <rtems/score/cpu.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/**
- * @defgroup ScoreSMPLockPowerPC PowerPC SMP Locks
- *
- * @ingroup ScoreSMPLock
- *
- * A ticket lock implementation is used.
- *
- * @{
- */
-
-typedef struct {
- uint32_t next_ticket;
- uint32_t now_serving;
-} CPU_SMP_lock_Control;
-
-#define CPU_SMP_LOCK_INITIALIZER { 0, 0 }
-
-static inline void _CPU_SMP_lock_Initialize( CPU_SMP_lock_Control *lock )
-{
- lock->next_ticket = 0;
- lock->now_serving = 0;
-}
-
-static inline void _CPU_SMP_lock_Acquire( CPU_SMP_lock_Control *lock )
-{
- uint32_t my_ticket;
- uint32_t next_ticket;
-
- __asm__ volatile (
- "1: lwarx %[my_ticket], 0, %[next_ticket_addr]\n"
- "addi %[next_ticket], %[my_ticket], 1\n"
- "stwcx. %[next_ticket], 0, [%[next_ticket_addr]]\n"
- "bne 1b\n"
- "isync"
- : [my_ticket] "=&r" (my_ticket),
- [next_ticket] "=&r" (next_ticket)
- : [next_ticket_addr] "r" (&lock->next_ticket)
- : "cc", "memory"
- );
-
- while ( my_ticket != lock->now_serving ) {
- __asm__ volatile ( "" : : : "memory" );
- }
-}
-
-static inline void _CPU_SMP_lock_Release( CPU_SMP_lock_Control *lock )
-{
- __asm__ volatile ( "msync" : : : "memory" );
- ++lock->now_serving;
-}
-
-#define _CPU_SMP_lock_ISR_disable_and_acquire( lock, isr_cookie ) \
- do { \
- _CPU_ISR_Disable( isr_cookie ); \
- _CPU_SMP_lock_Acquire( lock ); \
- } while (0)
-
-#define _CPU_SMP_lock_Release_and_ISR_enable( lock, isr_cookie ) \
- do { \
- _CPU_SMP_lock_Release( lock ); \
- _CPU_ISR_Enable( isr_cookie ); \
- } while (0)
-
-/**@}*/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _RTEMS_SCORE_POWERPC_SMPLOCK_H */
diff --git a/cpukit/score/cpu/sparc/Makefile.am b/cpukit/score/cpu/sparc/Makefile.am
index 6e248a2..504a575 100644
--- a/cpukit/score/cpu/sparc/Makefile.am
+++ b/cpukit/score/cpu/sparc/Makefile.am
@@ -8,7 +8,6 @@ include_rtems_score_HEADERS = rtems/score/sparc.h
include_rtems_score_HEADERS += rtems/score/cpu.h
include_rtems_score_HEADERS += rtems/score/types.h
include_rtems_score_HEADERS += rtems/score/cpuatomic.h
-include_rtems_score_HEADERS += rtems/score/cpusmplock.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.S
diff --git a/cpukit/score/cpu/sparc/preinstall.am b/cpukit/score/cpu/sparc/preinstall.am
index e497b48..a2bb01b 100644
--- a/cpukit/score/cpu/sparc/preinstall.am
+++ b/cpukit/score/cpu/sparc/preinstall.am
@@ -43,7 +43,3 @@ $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h: rtems/score/cpuatomic.h $(PROJECT_IN
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpuatomic.h
-$(PROJECT_INCLUDE)/rtems/score/cpusmplock.h: rtems/score/cpusmplock.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
- $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpusmplock.h
-
diff --git a/cpukit/score/cpu/sparc/rtems/score/cpusmplock.h b/cpukit/score/cpu/sparc/rtems/score/cpusmplock.h
deleted file mode 100644
index 63b11b4..0000000
--- a/cpukit/score/cpu/sparc/rtems/score/cpusmplock.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * @file
- *
- * @ingroup ScoreSMPLockSPARC
- *
- * @brief SPARC SMP Lock Implementation
- */
-
-/*
- * COPYRIGHT (c) 1989-2011.
- * On-Line Applications Research Corporation (OAR).
- *
- * Copyright (c) 2013 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.com/license/LICENSE.
- */
-
-#ifndef _RTEMS_SCORE_SPARC_SMPLOCK_H
-#define _RTEMS_SCORE_SPARC_SMPLOCK_H
-
-#include <rtems/score/cpu.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/**
- * @defgroup ScoreSMPLockSPARC SPARC SMP Locks
- *
- * @ingroup ScoreSMPLock
- *
- * The implementation is Test and Swap.
- *
- * @{
- */
-
-typedef struct {
- uint32_t locked;
-} CPU_SMP_lock_Control;
-
-#define CPU_SMP_LOCK_INITIALIZER { 0 }
-
-static inline void _CPU_SMP_lock_Initialize( CPU_SMP_lock_Control *lock )
-{
- lock->locked = 0;
-}
-
-/*
- * Function to access memory and bypass the cache.
- *
- * NOTE: address space 1 is uncacheable
- *
- * FIXME: This implementation uses specific Leon features.
- */
-static inline uint32_t _SPARC_Atomic_swap(
- volatile uint32_t *address,
- uint32_t value
-)
-{
- asm volatile (
- "swapa [%2] %3, %0"
- : "=r" (value)
- : "0" (value), "r" (address), "i" (1)
- : "memory"
- );
-
- return value;
-}
-
-static inline void _CPU_SMP_lock_Acquire( CPU_SMP_lock_Control *lock )
-{
- do {
- while ( lock->locked ) {
- RTEMS_COMPILER_MEMORY_BARRIER();
- }
- } while ( _SPARC_Atomic_swap( &lock->locked, 1 ) );
-}
-
-static inline void _CPU_SMP_lock_Release( CPU_SMP_lock_Control *lock )
-{
- RTEMS_COMPILER_MEMORY_BARRIER();
- lock->locked = 0;
-}
-
-#define _CPU_SMP_lock_ISR_disable_and_acquire( lock, isr_cookie ) \
- do { \
- _CPU_ISR_Disable( isr_cookie ); \
- _CPU_SMP_lock_Acquire( lock ); \
- } while (0)
-
-#define _CPU_SMP_lock_Release_and_ISR_enable( lock, isr_cookie ) \
- do { \
- _CPU_SMP_lock_Release( lock ); \
- _CPU_ISR_Enable( isr_cookie ); \
- } while (0)
-
-/**@}*/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _RTEMS_SCORE_SPARC_SMPLOCK_H */
diff --git a/cpukit/score/include/rtems/score/smplock.h b/cpukit/score/include/rtems/score/smplock.h
index 6b77114..25efbfa 100644
--- a/cpukit/score/include/rtems/score/smplock.h
+++ b/cpukit/score/include/rtems/score/smplock.h
@@ -10,7 +10,7 @@
* COPYRIGHT (c) 1989-2011.
* On-Line Applications Research Corporation (OAR).
*
- * Copyright (c) 2013 embedded brains GmbH
+ * Copyright (c) 2013-2014 embedded brains GmbH
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -24,7 +24,7 @@
#if defined( RTEMS_SMP )
-#include <rtems/score/cpusmplock.h>
+#include <rtems/score/atomic.h>
#include <rtems/score/isrlevel.h>
#ifdef __cplusplus
@@ -36,9 +36,11 @@ extern "C" {
*
* @ingroup Score
*
- * The SMP lock implementation is architecture dependent. The implementation
- * should provide fairness in case of concurrent lock attempts. A ticket lock
- * is probably the most likely implementation.
+ * @brief The SMP lock provides mutual exclusion for SMP systems at the lowest
+ * level.
+ *
+ * The SMP lock is implemented as a ticket lock. This provides fairness in
+ * case of concurrent lock attempts.
*
* This SMP lock API has a flaw. It does not provide the ability to use a
* local context for acquire and release pairs. Such a context is necessary to
@@ -53,16 +55,17 @@ extern "C" {
/**
* @brief SMP lock control.
- *
- * This is an opaque type. The SMP lock implementation is architecture
- * dependent.
*/
-typedef CPU_SMP_lock_Control SMP_lock_Control;
+typedef struct {
+ Atomic_Uint next_ticket;
+ Atomic_Uint now_serving;
+} SMP_lock_Control;
/**
* @brief SMP lock control initializer for static initialization.
*/
-#define SMP_LOCK_INITIALIZER CPU_SMP_LOCK_INITIALIZER
+#define SMP_LOCK_INITIALIZER \
+ { ATOMIC_INITIALIZER_UINT( 0U ), ATOMIC_INITIALIZER_UINT( 0U ) }
/**
* @brief Initializes a SMP lock control.
@@ -73,7 +76,8 @@ typedef CPU_SMP_lock_Control SMP_lock_Control;
*/
static inline void _SMP_lock_Initialize( SMP_lock_Control *lock )
{
- _CPU_SMP_lock_Initialize( lock );
+ _Atomic_Init_uint( &lock->next_ticket, 0U );
+ _Atomic_Init_uint( &lock->now_serving, 0U );
}
/**
@@ -87,7 +91,14 @@ static inline void _SMP_lock_Initialize( SMP_lock_Control *lock )
*/
static inline void _SMP_lock_Acquire( SMP_lock_Control *lock )
{
- _CPU_SMP_lock_Acquire( lock );
+ unsigned int my_ticket =
+ _Atomic_Fetch_add_uint( &lock->next_ticket, 1U, ATOMIC_ORDER_RELAXED );
+ unsigned int now_serving;
+
+ do {
+ now_serving =
+ _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_ACQUIRE );
+ } while ( now_serving != my_ticket );
}
/**
@@ -97,7 +108,11 @@ static inline void _SMP_lock_Acquire( SMP_lock_Control *lock )
*/
static inline void _SMP_lock_Release( SMP_lock_Control *lock )
{
- _CPU_SMP_lock_Release( lock );
+ unsigned int current_ticket =
+ _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_RELAXED );
+ unsigned int next_ticket = current_ticket + 1U;
+
+ _Atomic_Store_uint( &lock->now_serving, next_ticket, ATOMIC_ORDER_RELEASE );
}
/**
@@ -107,7 +122,10 @@ static inline void _SMP_lock_Release( SMP_lock_Control *lock )
* @param[out] isr_cookie The ISR cookie.
*/
#define _SMP_lock_ISR_disable_and_acquire( lock, isr_cookie ) \
- _CPU_SMP_lock_ISR_disable_and_acquire( lock, isr_cookie )
+ do { \
+ _ISR_Disable_without_giant( isr_cookie ); \
+ _SMP_lock_Acquire( lock ); \
+ } while (0)
/**
* @brief Releases the SMP lock and enables interrupts.
@@ -116,7 +134,10 @@ static inline void _SMP_lock_Release( SMP_lock_Control *lock )
* @param[in] isr_cookie The ISR cookie.
*/
#define _SMP_lock_Release_and_ISR_enable( lock, isr_cookie ) \
- _CPU_SMP_lock_Release_and_ISR_enable( lock, isr_cookie )
+ do { \
+ _SMP_lock_Release( lock ); \
+ _ISR_Enable_without_giant( isr_cookie ); \
+ } while (0)
/**@}*/
--
1.7.7
More information about the devel
mailing list