score: Make <rtems/score/atomic.h> available

Make <rtems/score/atomic.h> available for all RTEMS configurations.  Use
inline functions instead of macros.  Use ISR disable/enable on
uni-processor configurations to ensure atomicity.

Update #2273.
This commit is contained in:
Sebastian Huber
2015-02-18 17:46:37 +01:00
parent fd144302a5
commit 4e3d9a4d6c
12 changed files with 877 additions and 381 deletions

View File

@@ -17,6 +17,7 @@ include_rtems_score_HEADERS = include/rtems/score/address.h
include_rtems_score_HEADERS += include/rtems/score/apiext.h
include_rtems_score_HEADERS += include/rtems/score/apimutex.h
include_rtems_score_HEADERS += include/rtems/score/assert.h
include_rtems_score_HEADERS += include/rtems/score/atomic.h
include_rtems_score_HEADERS += include/rtems/score/chain.h
include_rtems_score_HEADERS += include/rtems/score/chainimpl.h
include_rtems_score_HEADERS += include/rtems/score/context.h
@@ -31,6 +32,7 @@ include_rtems_score_HEADERS += include/rtems/score/coresem.h
include_rtems_score_HEADERS += include/rtems/score/coresemimpl.h
include_rtems_score_HEADERS += include/rtems/score/cpuset.h
include_rtems_score_HEADERS += include/rtems/score/cpusetimpl.h
include_rtems_score_HEADERS += include/rtems/score/cpustdatomic.h
include_rtems_score_HEADERS += include/rtems/score/heap.h
include_rtems_score_HEADERS += include/rtems/score/heapimpl.h
include_rtems_score_HEADERS += include/rtems/score/protectedheap.h
@@ -112,8 +114,6 @@ include_rtems_score_HEADERS += include/rtems/score/threadmp.h
endif
if HAS_SMP
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/schedulerprioritysmpimpl.h
include_rtems_score_HEADERS += include/rtems/score/schedulerpriorityaffinitysmp.h
include_rtems_score_HEADERS += include/rtems/score/schedulersimplesmp.h

View File

@@ -42,6 +42,8 @@ typedef CPU_atomic_Pointer Atomic_Pointer;
typedef CPU_atomic_Flag Atomic_Flag;
typedef CPU_atomic_Order Atomic_Order;
#define ATOMIC_ORDER_RELAXED CPU_ATOMIC_ORDER_RELAXED
#define ATOMIC_ORDER_ACQUIRE CPU_ATOMIC_ORDER_ACQUIRE

View File

@@ -6,6 +6,7 @@
/*
* COPYRIGHT (c) 2013 Deng Hengyi.
* Copyright (c) 2015 embedded brains GmbH.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -15,20 +16,29 @@
#ifndef _RTEMS_SCORE_CPUSTDATOMIC_H
#define _RTEMS_SCORE_CPUSTDATOMIC_H
#include <stdint.h>
#include <rtems/score/basedefs.h>
#if defined(__cplusplus) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 9
#ifdef RTEMS_SMP
#if defined(__cplusplus) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 9
/*
* The GCC 4.9 ships its own <stdatomic.h> which is not C++ compatible. The
* suggested solution was to include <atomic> in case C++ is used. This works
* at least with GCC 4.9. See also:
*
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60940
*/
#include <atomic>
#define _RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC
#else
#include <stdatomic.h>
#define _RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC
#endif
#else
#include <rtems/score/isrlevel.h>
#endif
/*
* The GCC 4.9 ships its own <stdatomic.h> which is not C++ compatible. The
* suggested solution was to include <atomic> in case C++ is used. This works
* at least with GCC 4.9. See also:
*
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60940
*/
#include <atomic>
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
typedef std::atomic_uint CPU_atomic_Uint;
@@ -38,6 +48,8 @@ typedef std::atomic_uintptr_t CPU_atomic_Pointer;
typedef std::atomic_flag CPU_atomic_Flag;
typedef std::memory_order CPU_atomic_Order;
#define CPU_ATOMIC_ORDER_RELAXED std::memory_order_relaxed
#define CPU_ATOMIC_ORDER_ACQUIRE std::memory_order_acquire
@@ -55,98 +67,7 @@ typedef std::atomic_flag CPU_atomic_Flag;
#define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT
#define _CPU_atomic_Fence( order ) atomic_thread_fence( order )
#define _CPU_atomic_Init_uint( obj, desired ) \
(obj)->store( desired )
#define _CPU_atomic_Init_ulong( obj, desired ) \
(obj)->store( desired )
#define _CPU_atomic_Init_ptr( obj, desired ) \
(obj)->store( desired )
#define _CPU_atomic_Load_uint( obj, order ) \
(obj)->load( order )
#define _CPU_atomic_Load_ulong( obj, order ) \
(obj)->load( order )
#define _CPU_atomic_Load_ptr( obj, order ) \
(void *) (obj)->load( order )
#define _CPU_atomic_Store_uint( obj, desr, order ) \
(obj)->store( desr, order )
#define _CPU_atomic_Store_ulong( obj, desr, order ) \
(obj)->store( desr, order )
#define _CPU_atomic_Store_ptr( obj, desr, order ) \
(obj)->store( (uintptr_t) desr, order )
#define _CPU_atomic_Fetch_add_uint( obj, arg, order ) \
(obj)->fetch_add( arg, order )
#define _CPU_atomic_Fetch_add_ulong( obj, arg, order ) \
(obj)->fetch_add( arg, order )
#define _CPU_atomic_Fetch_add_ptr( obj, arg, order ) \
(obj)->fetch_add( arg, (uintptr_t) order )
#define _CPU_atomic_Fetch_sub_uint( obj, arg, order ) \
(obj)->fetch_sub( arg, order )
#define _CPU_atomic_Fetch_sub_ulong( obj, arg, order ) \
(obj)->fetch_sub( arg, order )
#define _CPU_atomic_Fetch_sub_ptr( obj, arg, order ) \
(obj)->fetch_sub( arg, (uintptr_t) order )
#define _CPU_atomic_Fetch_or_uint( obj, arg, order ) \
(obj)->fetch_or( arg, order )
#define _CPU_atomic_Fetch_or_ulong( obj, arg, order ) \
(obj)->fetch_or( arg, order )
#define _CPU_atomic_Fetch_or_ptr( obj, arg, order ) \
(obj)->fetch_or( arg, (uintptr_t) order )
#define _CPU_atomic_Fetch_and_uint( obj, arg, order ) \
(obj)->fetch_and( arg, order )
#define _CPU_atomic_Fetch_and_ulong( obj, arg, order ) \
(obj)->fetch_and( arg, order )
#define _CPU_atomic_Fetch_and_ptr( obj, arg, order ) \
(obj)->fetch_and( arg, (uintptr_t) order )
#define _CPU_atomic_Exchange_uint( obj, desr, order ) \
(obj)->exchange( desr, order )
#define _CPU_atomic_Exchange_ulong( obj, desr, order ) \
(obj)->exchange( desr, order )
#define _CPU_atomic_Exchange_ptr( obj, desr, order ) \
(void *) (obj)->exchange( desr, (uintptr_t) order )
#define _CPU_atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) \
(obj)->compare_exchange_strong( expected, desired, succ, fail )
#define _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \
(obj)->compare_exchange_strong( expected, desired, succ, fail )
#define _CPU_atomic_Compare_exchange_ptr( obj, expected, desired, succ, fail ) \
(obj)->compare_exchange_strong( (void **) expected, (uintptr_t) desired, succ, fail )
#define _CPU_atomic_Flag_clear( obj, order ) \
(obj)->clear( order )
#define _CPU_atomic_Flag_test_and_set( obj, order ) \
(obj)->test_and_set( order )
#else /* __cplusplus */
#include <stdatomic.h>
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
typedef atomic_uint CPU_atomic_Uint;
@@ -156,6 +77,8 @@ typedef atomic_uintptr_t CPU_atomic_Pointer;
typedef atomic_flag CPU_atomic_Flag;
typedef memory_order CPU_atomic_Order;
#define CPU_ATOMIC_ORDER_RELAXED memory_order_relaxed
#define CPU_ATOMIC_ORDER_ACQUIRE memory_order_acquire
@@ -173,95 +96,552 @@ typedef atomic_flag CPU_atomic_Flag;
#define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT
#define _CPU_atomic_Fence( order ) atomic_thread_fence( order )
#else
#define _CPU_atomic_Init_uint( obj, desired ) \
atomic_init( obj, desired )
typedef unsigned int CPU_atomic_Uint;
#define _CPU_atomic_Init_ulong( obj, desired ) \
atomic_init( obj, desired )
typedef unsigned long CPU_atomic_Ulong;
#define _CPU_atomic_Init_ptr( obj, desired ) \
atomic_init( obj, (uintptr_t) desired )
typedef uintptr_t CPU_atomic_Pointer;
#define _CPU_atomic_Load_uint( obj, order ) \
atomic_load_explicit( obj, order )
typedef bool CPU_atomic_Flag;
#define _CPU_atomic_Load_ulong( obj, order ) \
atomic_load_explicit( obj, order )
typedef int CPU_atomic_Order;
#define _CPU_atomic_Load_ptr( obj, order ) \
(void *) atomic_load_explicit( obj, order )
#define CPU_ATOMIC_ORDER_RELAXED 0
#define _CPU_atomic_Store_uint( obj, desr, order ) \
atomic_store_explicit( obj, desr, order )
#define CPU_ATOMIC_ORDER_ACQUIRE 2
#define _CPU_atomic_Store_ulong( obj, desr, order ) \
atomic_store_explicit( obj, desr, order )
#define CPU_ATOMIC_ORDER_RELEASE 3
#define _CPU_atomic_Store_ptr( obj, desr, order ) \
atomic_store_explicit( obj, desr, order )
#define CPU_ATOMIC_ORDER_SEQ_CST 5
#define _CPU_atomic_Fetch_add_uint( obj, arg, order ) \
atomic_fetch_add_explicit( obj, arg, order )
#define CPU_ATOMIC_INITIALIZER_UINT( value ) ( value )
#define _CPU_atomic_Fetch_add_ulong( obj, arg, order ) \
atomic_fetch_add_explicit( obj, arg, order )
#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ( value )
#define _CPU_atomic_Fetch_add_ptr( obj, arg, order ) \
atomic_fetch_add_explicit( obj, arg, order )
#define CPU_ATOMIC_INITIALIZER_PTR( value ) ( (uintptr_t) (value) )
#define _CPU_atomic_Fetch_sub_uint( obj, arg, order ) \
atomic_fetch_sub_explicit( obj, arg, order )
#define CPU_ATOMIC_INITIALIZER_FLAG false
#define _CPU_atomic_Fetch_sub_ulong( obj, arg, order ) \
atomic_fetch_sub_explicit( obj, arg, order )
#endif
#define _CPU_atomic_Fetch_sub_ptr( obj, arg, order ) \
atomic_fetch_sub_explicit( obj, arg, order )
static inline void _CPU_atomic_Fence( CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
std::atomic_thread_fence( order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
atomic_thread_fence( order );
#else
(void) order;
RTEMS_COMPILER_MEMORY_BARRIER();
#endif
}
#define _CPU_atomic_Fetch_or_uint( obj, arg, order ) \
atomic_fetch_or_explicit( obj, arg, order )
static inline void _CPU_atomic_Init_uint( CPU_atomic_Uint *obj, unsigned int desired )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
obj->store( desired );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
atomic_init( obj, desired );
#else
*obj = desired;
#endif
}
#define _CPU_atomic_Fetch_or_ulong( obj, arg, order ) \
atomic_fetch_or_explicit( obj, arg, order )
static inline void _CPU_atomic_Init_ulong( CPU_atomic_Ulong *obj, unsigned long desired )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
obj->store( desired );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
atomic_init( obj, desired );
#else
*obj = desired;
#endif
}
#define _CPU_atomic_Fetch_or_ptr( obj, arg, order ) \
atomic_fetch_or_explicit( obj, arg, order )
static inline void _CPU_atomic_Init_ptr( CPU_atomic_Pointer *obj, void *desired )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
obj->store( (uintptr_t) desired );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
atomic_init( obj, (uintptr_t) desired );
#else
*obj = (uintptr_t) desired;
#endif
}
#define _CPU_atomic_Fetch_and_uint( obj, arg, order ) \
atomic_fetch_and_explicit( obj, arg, order )
static inline unsigned int _CPU_atomic_Load_uint( const CPU_atomic_Uint *obj, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->load( order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_load_explicit( obj, order );
#else
(void) order;
return *obj;
#endif
}
#define _CPU_atomic_Fetch_and_ulong( obj, arg, order ) \
atomic_fetch_and_explicit( obj, arg, order )
static inline unsigned long _CPU_atomic_Load_ulong( const CPU_atomic_Ulong *obj, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->load( order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_load_explicit( obj, order );
#else
(void) order;
return *obj;
#endif
}
#define _CPU_atomic_Fetch_and_ptr( obj, arg, order ) \
atomic_fetch_and_explicit( obj, arg, order )
static inline void *_CPU_atomic_Load_ptr( const CPU_atomic_Pointer *obj, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return (void *) obj->load( order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return (void *) atomic_load_explicit( obj, order );
#else
(void) order;
return (void *) *obj;
#endif
}
#define _CPU_atomic_Exchange_uint( obj, desr, order ) \
atomic_exchange_explicit( obj, desr, order )
static inline void _CPU_atomic_Store_uint( CPU_atomic_Uint *obj, unsigned int desired, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
obj->store( desired );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
atomic_store_explicit( obj, desired, order );
#else
(void) order;
*obj = desired;
#endif
}
#define _CPU_atomic_Exchange_ulong( obj, desr, order ) \
atomic_exchange_explicit( obj, desr, order )
static inline void _CPU_atomic_Store_ulong( CPU_atomic_Ulong *obj, unsigned long desired, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
obj->store( desired );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
atomic_store_explicit( obj, desired, order );
#else
(void) order;
*obj = desired;
#endif
}
#define _CPU_atomic_Exchange_ptr( obj, desr, order ) \
atomic_exchange_explicit( obj, desr, order )
static inline void _CPU_atomic_Store_ptr( CPU_atomic_Pointer *obj, void *desired, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
obj->store( (uintptr_t) desired );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
atomic_store_explicit( obj, (uintptr_t) desired, order );
#else
(void) order;
*obj = (uintptr_t) desired;
#endif
}
#define _CPU_atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) \
atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail )
static inline unsigned int _CPU_atomic_Fetch_add_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->fetch_add( arg, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_fetch_add_explicit( obj, arg, order );
#else
unsigned int val;
ISR_Level level;
#define _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \
atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail )
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = val + arg;
_ISR_Enable( level );
#define _CPU_atomic_Compare_exchange_ptr( obj, expected, desired, succ, fail ) \
atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail )
return val;
#endif
}
#define _CPU_atomic_Flag_clear( obj, order ) \
atomic_flag_clear_explicit( obj, order )
static inline unsigned long _CPU_atomic_Fetch_add_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->fetch_add( arg, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_fetch_add_explicit( obj, arg, order );
#else
unsigned long val;
ISR_Level level;
#define _CPU_atomic_Flag_test_and_set( obj, order ) \
atomic_flag_test_and_set_explicit( obj, order )
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = val + arg;
_ISR_Enable( level );
#endif /* __cplusplus */
return val;
#endif
}
static inline void *_CPU_atomic_Fetch_add_ptr( CPU_atomic_Pointer *obj, void *arg, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return (void *) obj->fetch_add( (uintptr_t) arg, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return (void *) atomic_fetch_add_explicit( obj, (uintptr_t) arg, order );
#else
uintptr_t val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = val + (uintptr_t) arg;
_ISR_Enable( level );
return (void *) val;
#endif
}
static inline unsigned int _CPU_atomic_Fetch_sub_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->fetch_sub( arg, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_fetch_sub_explicit( obj, arg, order );
#else
unsigned int val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = val - arg;
_ISR_Enable( level );
return val;
#endif
}
static inline unsigned long _CPU_atomic_Fetch_sub_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->fetch_sub( arg, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_fetch_sub_explicit( obj, arg, order );
#else
unsigned long val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = val - arg;
_ISR_Enable( level );
return val;
#endif
}
static inline void *_CPU_atomic_Fetch_sub_ptr( CPU_atomic_Pointer *obj, void *arg, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return (void *) obj->fetch_sub( (uintptr_t) arg, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return (void *) atomic_fetch_sub_explicit( obj, (uintptr_t) arg, order );
#else
unsigned int val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = val - (uintptr_t) arg;
_ISR_Enable( level );
return (void *) val;
#endif
}
static inline unsigned int _CPU_atomic_Fetch_or_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->fetch_or( arg, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_fetch_or_explicit( obj, arg, order );
#else
unsigned int val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = val | arg;
_ISR_Enable( level );
return val;
#endif
}
static inline unsigned long _CPU_atomic_Fetch_or_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->fetch_or( arg, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_fetch_or_explicit( obj, arg, order );
#else
unsigned long val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = val | arg;
_ISR_Enable( level );
return val;
#endif
}
static inline void *_CPU_atomic_Fetch_or_ptr( CPU_atomic_Pointer *obj, void *arg, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return (void *) obj->fetch_or( (uintptr_t) arg, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return (void *) atomic_fetch_or_explicit( obj, (uintptr_t) arg, order );
#else
uintptr_t val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = val | (uintptr_t) arg;
_ISR_Enable( level );
return (void *) val;
#endif
}
static inline unsigned int _CPU_atomic_Fetch_and_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->fetch_and( arg, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_fetch_and_explicit( obj, arg, order );
#else
unsigned int val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = val & arg;
_ISR_Enable( level );
return val;
#endif
}
static inline unsigned long _CPU_atomic_Fetch_and_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->fetch_and( arg, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_fetch_and_explicit( obj, arg, order );
#else
unsigned long val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = val & arg;
_ISR_Enable( level );
return val;
#endif
}
static inline void *_CPU_atomic_Fetch_and_ptr( CPU_atomic_Pointer *obj, void *arg, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return (void *) obj->fetch_and( (uintptr_t) arg, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return (void *) atomic_fetch_and_explicit( obj, (uintptr_t) arg, order );
#else
uintptr_t val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = val & (uintptr_t) arg;
_ISR_Enable( level );
return (void *) val;
#endif
}
static inline unsigned int _CPU_atomic_Exchange_uint( CPU_atomic_Uint *obj, unsigned int desired, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->exchange( desired, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_exchange_explicit( obj, desired, order );
#else
unsigned int val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = desired;
_ISR_Enable( level );
return val;
#endif
}
static inline unsigned long _CPU_atomic_Exchange_ulong( CPU_atomic_Ulong *obj, unsigned long desired, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->exchange( desired, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_exchange_explicit( obj, desired, order );
#else
unsigned long val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = desired;
_ISR_Enable( level );
return val;
#endif
}
static inline void *_CPU_atomic_Exchange_ptr( CPU_atomic_Pointer *obj, void *desired, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return (void *) obj->exchange( (uintptr_t) desired, order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return (void *) atomic_exchange_explicit( obj, (uintptr_t) desired, order );
#else
uintptr_t val;
ISR_Level level;
(void) order;
_ISR_Disable( level );
val = *obj;
*obj = (uintptr_t) desired;
_ISR_Enable( level );
return (void *) val;
#endif
}
static inline bool _CPU_atomic_Compare_exchange_uint( CPU_atomic_Uint *obj, unsigned int *expected, unsigned int desired, CPU_atomic_Order succ, CPU_atomic_Order fail )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->compare_exchange_strong( *expected, desired, succ, fail );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail );
#else
bool success;
ISR_Level level;
(void) succ;
(void) fail;
_ISR_Disable( level );
success = *obj == *expected;
if ( success ) {
*obj = desired;
}
_ISR_Enable( level );
return success;
#endif
}
static inline bool _CPU_atomic_Compare_exchange_ulong( CPU_atomic_Ulong *obj, unsigned long *expected, unsigned long desired, CPU_atomic_Order succ, CPU_atomic_Order fail )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->compare_exchange_strong( *expected, desired, succ, fail );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail );
#else
bool success;
ISR_Level level;
(void) succ;
(void) fail;
_ISR_Disable( level );
success = *obj == *expected;
if ( success ) {
*obj = desired;
}
_ISR_Enable( level );
return success;
#endif
}
static inline bool _CPU_atomic_Compare_exchange_ptr( CPU_atomic_Pointer *obj, void **expected, void *desired, CPU_atomic_Order succ, CPU_atomic_Order fail )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->compare_exchange_strong( *(uintptr_t *) expected, (uintptr_t) desired, succ, fail );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_compare_exchange_strong_explicit( obj, (uintptr_t *) expected, (uintptr_t) desired, succ, fail );
#else
bool success;
ISR_Level level;
(void) succ;
(void) fail;
_ISR_Disable( level );
success = *obj == (uintptr_t) *expected;
if ( success ) {
*obj = (uintptr_t) desired;
}
_ISR_Enable( level );
return success;
#endif
}
static inline void _CPU_atomic_Flag_clear( CPU_atomic_Flag *obj, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
obj->clear( order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
atomic_flag_clear_explicit( obj, order );
#else
(void) order;
*obj = false;
#endif
}
static inline bool _CPU_atomic_Flag_test_and_set( CPU_atomic_Flag *obj, CPU_atomic_Order order )
{
#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
return obj->test_and_set( order );
#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
return atomic_flag_test_and_set_explicit( obj, order );
#else
bool flag;
ISR_Level level;
(void) order;
_ISR_Disable( level );
flag = *obj;
*obj = true;
_ISR_Enable( level );
return flag;
#endif
}
#endif /* _RTEMS_SCORE_CPUSTDATOMIC_H */

View File

@@ -51,6 +51,10 @@ $(PROJECT_INCLUDE)/rtems/score/assert.h: include/rtems/score/assert.h $(PROJECT_
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/assert.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/assert.h
$(PROJECT_INCLUDE)/rtems/score/atomic.h: include/rtems/score/atomic.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/atomic.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/atomic.h
$(PROJECT_INCLUDE)/rtems/score/chain.h: include/rtems/score/chain.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/chain.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/chain.h
@@ -107,6 +111,10 @@ $(PROJECT_INCLUDE)/rtems/score/cpusetimpl.h: include/rtems/score/cpusetimpl.h $(
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpusetimpl.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpusetimpl.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/heap.h: include/rtems/score/heap.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/heap.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/heap.h
@@ -398,14 +406,6 @@ $(PROJECT_INCLUDE)/rtems/score/threadmp.h: include/rtems/score/threadmp.h $(PROJ
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/threadmp.h
endif
if HAS_SMP
$(PROJECT_INCLUDE)/rtems/score/atomic.h: include/rtems/score/atomic.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/atomic.h
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/schedulerprioritysmpimpl.h: include/rtems/score/schedulerprioritysmpimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmpimpl.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmpimpl.h

View File

@@ -389,63 +389,12 @@ static void worker_task(size_t worker_index)
rtems_test_assert(0);
}
static void test_static_and_dynamic_initialization(void)
{
static Atomic_Uint static_uint =
ATOMIC_INITIALIZER_UINT(0xc01dc0feU);
static Atomic_Ulong static_ulong =
ATOMIC_INITIALIZER_ULONG(0xdeadbeefUL);
static Atomic_Pointer static_ptr =
ATOMIC_INITIALIZER_PTR(&static_ptr);
static Atomic_Flag static_flag = ATOMIC_INITIALIZER_FLAG;
Atomic_Uint stack_uint;
Atomic_Ulong stack_ulong;
Atomic_Pointer stack_ptr;
Atomic_Flag stack_flag;
puts("=== static and dynamic initialization test case ===");
_Atomic_Init_uint(&stack_uint, 0xc01dc0feU);
_Atomic_Init_ulong(&stack_ulong, 0xdeadbeefUL);
_Atomic_Init_ptr(&stack_ptr, &static_ptr);
_Atomic_Flag_clear(&stack_flag, ATOMIC_ORDER_RELAXED);
rtems_test_assert(
memcmp(&stack_uint, &static_uint, sizeof(stack_uint)) == 0
);
rtems_test_assert(
memcmp(&stack_ulong, &static_ulong, sizeof(stack_ulong)) == 0
);
rtems_test_assert(
memcmp(&stack_ptr, &static_ptr, sizeof(stack_ptr)) == 0
);
rtems_test_assert(
memcmp(&stack_flag, &static_flag, sizeof(stack_flag)) == 0
);
rtems_test_assert(
_Atomic_Load_uint(&stack_uint, ATOMIC_ORDER_RELAXED) == 0xc01dc0feU
);
rtems_test_assert(
_Atomic_Load_ulong(&stack_ulong, ATOMIC_ORDER_RELAXED) == 0xdeadbeefUL
);
rtems_test_assert(
_Atomic_Load_ptr(&stack_ptr, ATOMIC_ORDER_RELAXED) == &static_ptr
);
rtems_test_assert(
!_Atomic_Flag_test_and_set(&stack_flag, ATOMIC_ORDER_RELAXED)
);
}
static void test(void)
{
test_context *ctx = &test_instance;
rtems_status_code sc;
size_t worker_index;
test_static_and_dynamic_initialization();
ctx->worker_count = rtems_get_processor_count();
sc = rtems_timer_create(
@@ -474,159 +423,10 @@ static void test(void)
run_tests(ctx, 0);
}
typedef void (*simple_test_body)(test_context *ctx);
static void test_simple_atomic_add_body(test_context *ctx)
{
unsigned int ia = 8, ib = 4;
unsigned int ic;
unsigned long a = 2, b = 1;
unsigned long c;
puts("=== atomic simple add test case ===\n");
_Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_add_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED);
ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(ic == (ia + ib));
_Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_add_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED);
c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(c == (a + b));
}
static void test_simple_atomic_sub_body(test_context *ctx)
{
unsigned int ia = 8, ib = 4;
unsigned int ic;
unsigned long a = 2, b = 1;
unsigned long c;
puts("=== atomic simple sub test case ===\n");
_Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_sub_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED);
ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(ic == (ia - ib));
_Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_sub_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED);
c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(c == (a - b));
}
static void test_simple_atomic_or_body(test_context *ctx)
{
unsigned int ia = 8, ib = 4;
unsigned int ic;
unsigned long a = 2, b = 1;
unsigned long c;
puts("=== atomic simple or test case ===\n");
_Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_or_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED);
ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(ic == (ia | ib));
_Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_or_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED);
c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(c == (a | b));
}
static void test_simple_atomic_and_body(test_context *ctx)
{
unsigned int ia = 8, ib = 4;
unsigned int ic;
unsigned long a = 2, b = 1;
unsigned long c;
puts("=== atomic simple and test case ===\n");
_Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_and_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED);
ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(ic == (ia & ib));
_Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_and_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED);
c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(c == (a & b));
}
static void test_simple_atomic_exchange_body(test_context *ctx)
{
unsigned int ia = 8, ib = 4;
unsigned int ic;
unsigned long a = 2, b = 1;
unsigned long c;
puts("=== atomic simple exchange test case ===\n");
_Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
_Atomic_Exchange_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED);
ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(ic == ib);
_Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED);
_Atomic_Exchange_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED);
c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(c == b);
}
static void test_simple_atomic_compare_exchange_body(test_context *ctx)
{
unsigned int ia = 8, ib = 4;
unsigned int ic;
unsigned long a = 2, b = 1;
unsigned long c;
puts("=== atomic simple compare exchange test case ===\n");
_Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
_Atomic_Compare_exchange_uint(&ctx->atomic_int_value, &ia, ib,
ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED);
ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(ic == ib);
_Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED);
_Atomic_Compare_exchange_ulong(&ctx->atomic_value, &a, b,
ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED);
c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(c == b);
}
static const simple_test_body simple_test_bodies[] = {
test_simple_atomic_add_body,
test_simple_atomic_sub_body,
test_simple_atomic_or_body,
test_simple_atomic_and_body,
test_simple_atomic_exchange_body,
test_simple_atomic_compare_exchange_body,
};
#define SIMPLE_TEST_COUNT RTEMS_ARRAY_SIZE(simple_test_bodies)
static void simple_tests(void)
{
test_context *ctx = &test_instance;
size_t test;
for (test = 0; test < SIMPLE_TEST_COUNT; ++test) {
const simple_test_body *test_body = &simple_test_bodies[test];
(*test_body)(ctx);
}
}
static void Init(rtems_task_argument arg)
{
TEST_BEGIN();
simple_tests();
test();
TEST_END();

View File

@@ -1,11 +1,4 @@
*** TEST SMPATOMIC 1 ***
=== atomic simple add test case ===
=== atomic simple sub test case ===
=== atomic simple or test case ===
=== atomic simple and test case ===
=== atomic simple exchange test case ===
=== atomic simple compare exchange test case ===
=== static and dynamic initialization test case ====
=== atomic add test case ===
worker 0 value: 16686
worker 1 value: 36405

View File

@@ -37,6 +37,7 @@ if HAS_SMP
else
_SUBDIRS += sp29
endif
_SUBDIRS += spatomic01
_SUBDIRS += spintrcritical22
_SUBDIRS += spsem03
_SUBDIRS += spresource01

View File

@@ -40,6 +40,7 @@ AM_CONDITIONAL(HAS_SMP,test "$rtems_cv_RTEMS_SMP" = "yes")
# Explicitly list all Makefiles here
AC_CONFIG_FILES([Makefile
spatomic01/Makefile
spglobalcon01/Makefile
spintrcritical22/Makefile
spsem03/Makefile

View File

@@ -0,0 +1,19 @@
rtems_tests_PROGRAMS = spatomic01
spatomic01_SOURCES = init.c
dist_rtems_tests_DATA = spatomic01.scn spatomic01.doc
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../automake/compile.am
include $(top_srcdir)/../automake/leaf.am
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
LINK_OBJS = $(spatomic01_OBJECTS)
LINK_LIBS = $(spatomic01_LDLIBS)
spatomic01$(EXEEXT): $(spatomic01_OBJECTS) $(spatomic01_DEPENDENCIES)
@rm -f spatomic01$(EXEEXT)
$(make-exe)
include $(top_srcdir)/../automake/local.am

View File

@@ -0,0 +1,254 @@
/*
* Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* Copyright (c) 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.org/license/LICENSE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/atomic.h>
#include <stdio.h>
#include <rtems.h>
#include "tmacros.h"
const char rtems_test_name[] = "SPATOMIC 1";
typedef struct {
Atomic_Uint atomic_int_value;
Atomic_Ulong atomic_value;
} test_context;
static test_context test_instance;
static void test_static_and_dynamic_initialization(void)
{
static Atomic_Uint static_uint =
ATOMIC_INITIALIZER_UINT(0xc01dc0feU);
static Atomic_Ulong static_ulong =
ATOMIC_INITIALIZER_ULONG(0xdeadbeefUL);
static Atomic_Pointer static_ptr =
ATOMIC_INITIALIZER_PTR(&static_ptr);
static Atomic_Flag static_flag = ATOMIC_INITIALIZER_FLAG;
Atomic_Uint stack_uint;
Atomic_Ulong stack_ulong;
Atomic_Pointer stack_ptr;
Atomic_Flag stack_flag;
puts("=== static and dynamic initialization test case ===");
_Atomic_Init_uint(&stack_uint, 0xc01dc0feU);
_Atomic_Init_ulong(&stack_ulong, 0xdeadbeefUL);
_Atomic_Init_ptr(&stack_ptr, &static_ptr);
_Atomic_Flag_clear(&stack_flag, ATOMIC_ORDER_RELAXED);
rtems_test_assert(
memcmp(&stack_uint, &static_uint, sizeof(stack_uint)) == 0
);
rtems_test_assert(
memcmp(&stack_ulong, &static_ulong, sizeof(stack_ulong)) == 0
);
rtems_test_assert(
memcmp(&stack_ptr, &static_ptr, sizeof(stack_ptr)) == 0
);
rtems_test_assert(
memcmp(&stack_flag, &static_flag, sizeof(stack_flag)) == 0
);
rtems_test_assert(
_Atomic_Load_uint(&stack_uint, ATOMIC_ORDER_RELAXED) == 0xc01dc0feU
);
rtems_test_assert(
_Atomic_Load_ulong(&stack_ulong, ATOMIC_ORDER_RELAXED) == 0xdeadbeefUL
);
rtems_test_assert(
_Atomic_Load_ptr(&stack_ptr, ATOMIC_ORDER_RELAXED) == &static_ptr
);
rtems_test_assert(
!_Atomic_Flag_test_and_set(&stack_flag, ATOMIC_ORDER_RELAXED)
);
}
typedef void (*simple_test_body)(test_context *ctx);
static void test_simple_atomic_add_body(test_context *ctx)
{
unsigned int ia = 8, ib = 4;
unsigned int ic;
unsigned long a = 2, b = 1;
unsigned long c;
puts("=== atomic simple add test case ===");
_Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_add_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED);
ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(ic == (ia + ib));
_Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_add_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED);
c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(c == (a + b));
}
static void test_simple_atomic_sub_body(test_context *ctx)
{
unsigned int ia = 8, ib = 4;
unsigned int ic;
unsigned long a = 2, b = 1;
unsigned long c;
puts("=== atomic simple sub test case ===");
_Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_sub_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED);
ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(ic == (ia - ib));
_Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_sub_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED);
c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(c == (a - b));
}
static void test_simple_atomic_or_body(test_context *ctx)
{
unsigned int ia = 8, ib = 4;
unsigned int ic;
unsigned long a = 2, b = 1;
unsigned long c;
puts("=== atomic simple or test case ===");
_Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_or_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED);
ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(ic == (ia | ib));
_Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_or_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED);
c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(c == (a | b));
}
static void test_simple_atomic_and_body(test_context *ctx)
{
unsigned int ia = 8, ib = 4;
unsigned int ic;
unsigned long a = 2, b = 1;
unsigned long c;
puts("=== atomic simple and test case ===");
_Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_and_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED);
ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(ic == (ia & ib));
_Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED);
_Atomic_Fetch_and_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED);
c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(c == (a & b));
}
static void test_simple_atomic_exchange_body(test_context *ctx)
{
unsigned int ia = 8, ib = 4;
unsigned int ic;
unsigned long a = 2, b = 1;
unsigned long c;
puts("=== atomic simple exchange test case ===");
_Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
_Atomic_Exchange_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED);
ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(ic == ib);
_Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED);
_Atomic_Exchange_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED);
c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(c == b);
}
static void test_simple_atomic_compare_exchange_body(test_context *ctx)
{
unsigned int ia = 8, ib = 4;
unsigned int ic;
unsigned long a = 2, b = 1;
unsigned long c;
puts("=== atomic simple compare exchange test case ===");
_Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
_Atomic_Compare_exchange_uint(&ctx->atomic_int_value, &ia, ib,
ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED);
ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(ic == ib);
_Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED);
_Atomic_Compare_exchange_ulong(&ctx->atomic_value, &a, b,
ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED);
c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
rtems_test_assert(c == b);
}
static const simple_test_body simple_test_bodies[] = {
test_simple_atomic_add_body,
test_simple_atomic_sub_body,
test_simple_atomic_or_body,
test_simple_atomic_and_body,
test_simple_atomic_exchange_body,
test_simple_atomic_compare_exchange_body,
};
#define SIMPLE_TEST_COUNT RTEMS_ARRAY_SIZE(simple_test_bodies)
static void simple_tests(void)
{
test_context *ctx = &test_instance;
size_t test;
for (test = 0; test < SIMPLE_TEST_COUNT; ++test) {
const simple_test_body *test_body = &simple_test_bodies[test];
(*test_body)(ctx);
}
}
static void Init(rtems_task_argument arg)
{
TEST_BEGIN();
test_static_and_dynamic_initialization();
simple_tests();
TEST_END();
rtems_test_exit(0);
}
#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT
#include <rtems/confdefs.h>

View File

@@ -0,0 +1,37 @@
This file describes the directives and concepts tested by this test set.
test set name: spatomic01
directives:
- ATOMIC_INITIALIZER_FLAG
- ATOMIC_INITIALIZER_PTR()
- ATOMIC_INITIALIZER_UINT()
- ATOMIC_INITIALIZER_ULONG()
- _Atomic_Compare_exchange_uint()
- _Atomic_Compare_exchange_ulong()
- _Atomic_Exchange_uint()
- _Atomic_Exchange_ulong()
- _Atomic_Fence()
- _Atomic_Fetch_add_uint()
- _Atomic_Fetch_add_ulong()
- _Atomic_Fetch_and_uint()
- _Atomic_Fetch_and_ulong()
- _Atomic_Fetch_or_uint()
- _Atomic_Fetch_or_ulong()
- _Atomic_Fetch_sub_uint()
- _Atomic_Fetch_sub_ulong()
- _Atomic_Flag_clear()
- _Atomic_Flag_test_and_set()
- _Atomic_Init_ptr()
- _Atomic_Init_uint()
- _Atomic_Init_ulong()
- _Atomic_Load_ptr()
- _Atomic_Load_uint()
- _Atomic_Load_ulong()
- _Atomic_Store_uint()
- _Atomic_Store_ulong()
concepts:
- Ensure that the atomic operations work.

View File

@@ -0,0 +1,9 @@
*** BEGIN OF TEST SPATOMIC 1 ***
=== static and dynamic initialization test case ===
=== atomic simple add test case ===
=== atomic simple sub test case ===
=== atomic simple or test case ===
=== atomic simple and test case ===
=== atomic simple exchange test case ===
=== atomic simple compare exchange test case ===
*** END OF TEST SPATOMIC 1 ***