[PATCH 4/5] score: Use atomic API for SMP lock

Gedare Bloom gedare at rtems.org
Fri Feb 14 14:32:59 UTC 2014


Looks OK but I did not think my way through the ordering constraints.
I guess the existing test cases are good enough for now?

On Fri, Feb 14, 2014 at 8:07 AM, Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
> 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
>
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel



More information about the devel mailing list