summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWeiY <wei.a.yang@gmail.com>2013-07-15 23:31:09 +0800
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-07-17 13:07:33 +0200
commit34229d52855e98907be78222f4afb7ea62fc105a (patch)
treee908d7c016511690b25d3f339753e5a006655d97
parentNew atomic API definition based on C11 atomic (diff)
downloadrtems-34229d52855e98907be78222f4afb7ea62fc105a.tar.bz2
A generic atomic implementation for smp architectures
-rw-r--r--cpukit/score/Makefile.am1
-rw-r--r--cpukit/score/include/rtems/score/cpustdatomic.h332
-rw-r--r--cpukit/score/preinstall.am4
3 files changed, 337 insertions, 0 deletions
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 3f6e686ad9..82bf26d4ae 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -63,6 +63,7 @@ include_rtems_score_HEADERS += include/rtems/score/basedefs.h
include_rtems_score_HEADERS += include/rtems/score/atomic.h
include_rtems_score_HEADERS += include/rtems/score/genericcpuatomic.h
include_rtems_score_HEADERS += include/rtems/score/genericatomicops.h
+include_rtems_score_HEADERS += include/rtems/score/cpustdatomic.h
if HAS_PTHREADS
include_rtems_score_HEADERS += include/rtems/score/corespinlock.h
diff --git a/cpukit/score/include/rtems/score/cpustdatomic.h b/cpukit/score/include/rtems/score/cpustdatomic.h
new file mode 100644
index 0000000000..97cacc55cb
--- /dev/null
+++ b/cpukit/score/include/rtems/score/cpustdatomic.h
@@ -0,0 +1,332 @@
+/**
+ * @file rtems/score/cpustdatomic.h
+ *
+ * This include file defines the generic data struct and implementation
+ * based on stdatomic.h for all the support architectures. You should not
+ * include this header file directly, because it will be used by atomic.h
+ * which should be included by score components
+ */
+
+/*
+ * 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.com/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_GENERAL_STDATOMIC_CPU_H_
+#define _RTEMS_SCORE_GENERAL_STDATOMIC_CPU_H_
+
+#include <stdatomic.h>
+#include <rtems/score/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup RTEMS general stdatomic data type and implementation.
+ *
+ */
+
+/**@{*/
+
+/**
+ * @brief atomic operation unsigned integer type
+ */
+typedef atomic_uint_fast32_t Atomic_Uint;
+
+/**
+ * @brief atomic operation unsigned integer the size of a pointer type
+ */
+typedef atomic_uintptr_t Atomic_Pointer;
+
+/**
+ * @brief atomic operation flag type
+ */
+typedef atomic_flag Atomic_Flag;
+
+/**
+ * @brief the enumeration Atomic_Memory_barrier specifies the detailed regular
+ * memory synchronization operations used in the atomic operation API
+ * definitions.
+ */
+typedef enum {
+ /** no operation orders memory. */
+ ATOMIC_ORDER_RELAXED = memory_order_relaxed,
+ /** a load operation performs an acquire operation on the affected memory
+ * location. This flag guarantees that the effects of load operation are
+ * completed before the effects of any later data accesses.
+ */
+ ATOMIC_ORDER_ACQUIRE = memory_order_acquire,
+ /** a store operation performs a release operation on the affected memory
+ * location. This flag guarantee that all effects of all previous data
+ * accesses are completed before the store operation takes place.
+ */
+ ATOMIC_ORDER_RELEASE = memory_order_release
+} Atomic_Order;
+
+/**
+ * @brief Atomically load an atomic type value from atomic object.
+ *
+ * @param object an atomic type pointer of object.
+ * @param order a type of Atomic_Order.
+ *
+ * The order shall not be ATOMIC_ORDER_RELEASE.
+ */
+RTEMS_INLINE_ROUTINE uint_fast32_t _CPU_atomic_Load_uint(
+ volatile Atomic_Uint *object,
+ Atomic_Order order
+)
+{
+ return atomic_load_explicit( object, order );
+}
+
+RTEMS_INLINE_ROUTINE uintptr_t _CPU_atomic_Load_ptr(
+ volatile Atomic_Pointer *object,
+ Atomic_Order order
+)
+{
+ return atomic_load_explicit( object, order );
+}
+
+/**
+ * @brief Atomically store an atomic type value into a atomic object.
+ *
+ * @param object an atomic type pointer of object.
+ * @param value a value to be stored into object.
+ * @param order a type of Atomic_Order.
+ *
+ * The order shall not be ATOMIC_ORDER_ACQUIRE.
+ */
+RTEMS_INLINE_ROUTINE void _CPU_atomic_Store_uint(
+ volatile Atomic_Uint *object,
+ uint_fast32_t value,
+ Atomic_Order order
+)
+{
+ atomic_store_explicit( object, value, order );
+}
+
+RTEMS_INLINE_ROUTINE void _CPU_atomic_Store_ptr(
+ volatile Atomic_Pointer *object,
+ uintptr_t value,
+ Atomic_Order order
+)
+{
+ atomic_store_explicit( object, value, order );
+}
+
+/**
+ * @brief Atomically load-add-store an atomic type value into object
+ *
+ * @param object a atomic type pointer of object.
+ * @param value a value to be add and store into object.
+ * @param order a type of Atomic_Order.
+ *
+ * @retval a result value after add ops.
+ */
+RTEMS_INLINE_ROUTINE uint_fast32_t _CPU_atomic_Fetch_add_uint(
+ volatile Atomic_Uint *object,
+ uint_fast32_t value,
+ Atomic_Order order
+)
+{
+ return atomic_fetch_add_explicit( object, value, order );
+}
+
+RTEMS_INLINE_ROUTINE uintptr_t _CPU_atomic_Fetch_add_ptr(
+ volatile Atomic_Pointer *object,
+ uintptr_t value,
+ Atomic_Order order
+)
+{
+ return atomic_fetch_add_explicit( object, value, order );
+}
+
+/**
+ * @brief Atomically load-sub-store an atomic type value into object
+ *
+ * @param object a atomic type pointer of object.
+ * @param value a value to be sub and store into object.
+ * @param order a type of Atomic_Order.
+ *
+ * @retval a result value after sub ops.
+ */
+RTEMS_INLINE_ROUTINE uint_fast32_t _CPU_atomic_Fetch_sub_uint(
+ volatile Atomic_Uint *object,
+ uint_fast32_t value,
+ Atomic_Order order
+)
+{
+ return atomic_fetch_sub_explicit( object, value, order );
+}
+
+RTEMS_INLINE_ROUTINE uintptr_t _CPU_atomic_Fetch_sub_ptr(
+ volatile Atomic_Pointer *object,
+ uintptr_t value,
+ Atomic_Order order
+)
+{
+ return atomic_fetch_sub_explicit( object, value, order );
+}
+
+/**
+ * @brief Atomically load-or-store an atomic type value into object
+ *
+ * @param object a atomic type pointer of object.
+ * @param value a value to be or and store into object.
+ * @param order a type of Atomic_Order.
+ *
+ * @retval a result value after or ops.
+ */
+RTEMS_INLINE_ROUTINE uint_fast32_t _CPU_atomic_Fetch_or_uint(
+ volatile Atomic_Uint *object,
+ uint_fast32_t value,
+ Atomic_Order order
+)
+{
+ return atomic_fetch_or_explicit( object, value, order );
+}
+
+RTEMS_INLINE_ROUTINE uintptr_t _CPU_atomic_Fetch_or_ptr(
+ volatile Atomic_Pointer *object,
+ uintptr_t value,
+ Atomic_Order order
+)
+{
+ return atomic_fetch_or_explicit( object, value, order );
+}
+
+/**
+ * @brief Atomically load-and-store an atomic type value into object
+ *
+ * @param object a atomic type pointer of object.
+ * @param value a value to be and and store into object.
+ * @param order a type of Atomic_Order.
+ *
+ * @retval a result value after and ops.
+ */
+RTEMS_INLINE_ROUTINE uint_fast32_t _CPU_atomic_Fetch_and_uint(
+ volatile Atomic_Uint *object,
+ uint_fast32_t value,
+ Atomic_Order order
+)
+{
+ return atomic_fetch_and_explicit( object, value, order );
+}
+
+RTEMS_INLINE_ROUTINE uintptr_t _CPU_atomic_Fetch_and_ptr(
+ volatile Atomic_Pointer *object,
+ uintptr_t value,
+ Atomic_Order order
+)
+{
+ return atomic_fetch_and_explicit( object, value, order );
+}
+
+/**
+ * @brief Atomically exchange an atomic type value into object
+ *
+ * @param object a atomic type pointer of object.
+ * @param value a value to exchange and and store into object.
+ * @param order a type of Atomic_Order.
+ *
+ * @retval a result value after exchange ops.
+ */
+RTEMS_INLINE_ROUTINE uint_fast32_t _CPU_atomic_Exchange_uint(
+ volatile Atomic_Uint *object,
+ uint_fast32_t value,
+ Atomic_Order order
+)
+{
+ return atomic_exchange_explicit( object, value, order );
+}
+
+RTEMS_INLINE_ROUTINE uintptr_t _CPU_atomic_Exchange_ptr(
+ volatile Atomic_Pointer *object,
+ uintptr_t value,
+ Atomic_Order order
+)
+{
+ return atomic_exchange_explicit( object, value, order );
+}
+
+/**
+ * @brief Atomically compare the value stored at object with a
+ * old_value and if the two values are equal, update the value of a
+ * address with a new_value
+ *
+ * @param object a atomic type pointer of object.
+ * @param old_value pointer of a value.
+ * @param new_value a atomic type value.
+ * @param order_succ a type of Atomic_Order for successful exchange.
+ * @param order_fail a type of Atomic_Order for failed exchange.
+ *
+ * @retval true if the compare exchange successully.
+ * @retval false if the compare exchange failed.
+ */
+RTEMS_INLINE_ROUTINE bool _CPU_atomic_Compare_exchange_uint(
+ volatile Atomic_Uint *object,
+ uint_fast32_t *old_value,
+ uint_fast32_t new_value,
+ Atomic_Order order_succ,
+ Atomic_Order order_fail
+)
+{
+ return atomic_compare_exchange_strong_explicit( object, old_value,
+ new_value, order_succ, order_fail );
+}
+
+RTEMS_INLINE_ROUTINE bool _CPU_atomic_Compare_exchange_ptr(
+ volatile Atomic_Pointer *object,
+ uintptr_t *old_value,
+ uintptr_t new_value,
+ Atomic_Order order_succ,
+ Atomic_Order order_fail
+)
+{
+ return atomic_compare_exchange_strong_explicit( object, old_value,
+ new_value, order_succ, order_fail );
+}
+
+/**
+ * @brief Atomically clear the value of an atomic flag type object.
+ *
+ * @param[in, out] object an atomic flag type pointer of object.
+ * @param order a type of Atomic_Order.
+ *
+ */
+RTEMS_INLINE_ROUTINE void _CPU_atomic_Clear_flag(
+ volatile Atomic_Flag *object,
+ Atomic_Order order
+)
+{
+ return atomic_flag_clear_explicit( object, order );
+}
+
+/**
+ * @brief Atomically test and clear the value of an atomic flag type object.
+ *
+ * @param[in, out] object an atomic flag type pointer of object.
+ * @param order a type of Atomic_Order.
+ *
+ * @retval true if the test and set successully.
+ * @retval false if the test and set failed.
+ */
+RTEMS_INLINE_ROUTINE bool _CPU_atomic_Test_set_flag(
+ volatile Atomic_Flag *object,
+ Atomic_Order order
+)
+{
+ return atomic_flag_test_and_set_explicit( object, order );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+#endif
+/* end of include file */
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
index dc84b216b1..1b7955e872 100644
--- a/cpukit/score/preinstall.am
+++ b/cpukit/score/preinstall.am
@@ -235,6 +235,10 @@ $(PROJECT_INCLUDE)/rtems/score/genericatomicops.h: include/rtems/score/genericat
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/genericatomicops.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/genericatomicops.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
+
if HAS_PTHREADS
$(PROJECT_INCLUDE)/rtems/score/corespinlock.h: include/rtems/score/corespinlock.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/corespinlock.h