Fix RMW bug
[c11tester.git] / include / impatomic.h
index 889a960b3888a1beab03d3dc75c9acf92541ea79..70b77de2ddc28cf2c3a5c356f718666eb0ea5a65 100644 (file)
@@ -1,3 +1,4 @@
+#include <stdio.h>
 /**
  * @file impatomic.h
  * @brief Common header for C11/C++11 atomics
@@ -14,6 +15,8 @@
 
 #ifdef __cplusplus
 namespace std {
+#else
+#include <stdbool.h>
 #endif
 
 #define CPP0X( feature )
@@ -23,7 +26,6 @@ typedef struct atomic_flag
 #ifdef __cplusplus
     bool test_and_set( memory_order = memory_order_seq_cst ) volatile;
     void clear( memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
 
     CPP0X( atomic_flag() = default; )
     CPP0X( atomic_flag( const atomic_flag& ) = delete; )
@@ -46,8 +48,6 @@ extern bool atomic_flag_test_and_set_explicit
 extern void atomic_flag_clear( volatile atomic_flag* );
 extern void atomic_flag_clear_explicit
 ( volatile atomic_flag*, memory_order );
-extern void atomic_flag_fence
-( const volatile atomic_flag*, memory_order );
 extern void __atomic_flag_wait__
 ( volatile atomic_flag* );
 extern void __atomic_flag_wait_explicit__
@@ -65,9 +65,6 @@ inline bool atomic_flag::test_and_set( memory_order __x__ ) volatile
 inline void atomic_flag::clear( memory_order __x__ ) volatile
 { atomic_flag_clear_explicit( this, __x__ ); }
 
-inline void atomic_flag::fence( memory_order __x__ ) const volatile
-{ atomic_flag_fence( this, __x__ ); }
-
 #endif
 
 
@@ -92,14 +89,16 @@ inline void atomic_flag::fence( memory_order __x__ ) const volatile
         ({ volatile __typeof__((__a__)->__f__)* __p__ = & ((__a__)->__f__);   \
                 __typeof__(__m__) __v__ = (__m__);                            \
                 model_write_action((void *) __p__,  __x__, (uint64_t) __v__); \
-                __v__; })
+                __v__ = __v__; /* Silence clang (-Wunused-value) */           \
+         })
 
 
 #define _ATOMIC_INIT_( __a__, __m__ )                                         \
         ({ volatile __typeof__((__a__)->__f__)* __p__ = & ((__a__)->__f__);   \
                 __typeof__(__m__) __v__ = (__m__);                            \
                 model_init_action((void *) __p__,  (uint64_t) __v__);         \
-                __v__; })
+                __v__ = __v__; /* Silence clang (-Wunused-value) */           \
+         })
 
 #define _ATOMIC_MODIFY_( __a__, __o__, __m__, __x__ )                         \
         ({ volatile __typeof__((__a__)->__f__)* __p__ = & ((__a__)->__f__);   \
@@ -108,7 +107,8 @@ inline void atomic_flag::fence( memory_order __x__ ) const volatile
         __typeof__((__a__)->__f__) __copy__= __old__;                         \
         __copy__ __o__ __v__;                                                 \
         model_rmw_action((void *)__p__, __x__, (uint64_t) __copy__);          \
-        __old__; })
+        __old__ = __old__; /* Silence clang (-Wunused-value) */               \
+         })
 
 /* No spurious failure for now */
 #define _ATOMIC_CMPSWP_WEAK_ _ATOMIC_CMPSWP_
@@ -118,13 +118,13 @@ inline void atomic_flag::fence( memory_order __x__ ) const volatile
                 __typeof__(__e__) __q__ = (__e__);                            \
                 __typeof__(__m__) __v__ = (__m__);                            \
                 bool __r__;                                                   \
-                __typeof__((__a__)->__f__) __t__=(__typeof__((__a__)->__f__)) model_rmwr_action((void *)__p__, __x__); \
-                if (__t__ == * __q__ ) {                                      \
+                __typeof__((__a__)->__f__) __t__=(__typeof__((__a__)->__f__)) model_rmwrcas_action((void *)__p__, __x__, (uint64_t) * __q__, sizeof((__a__)->__f__)); \
+                if (__t__ == * __q__ ) {;                                     \
                         model_rmw_action((void *)__p__, __x__, (uint64_t) __v__); __r__ = true; } \
                 else {  model_rmwc_action((void *)__p__, __x__); *__q__ = __t__;  __r__ = false;} \
                 __r__; })
 
-#define _ATOMIC_FENCE_( __a__, __x__ ) \
+#define _ATOMIC_FENCE_( __x__ ) \
        ({ model_fence_action(__x__);})
  
 
@@ -151,7 +151,6 @@ typedef struct atomic_bool
                         memory_order = memory_order_seq_cst) volatile;
     bool compare_exchange_strong ( bool&, bool,
                         memory_order = memory_order_seq_cst) volatile;
-    void fence( memory_order ) const volatile;
 
     CPP0X( atomic_bool() = delete; )
     CPP0X( constexpr explicit atomic_bool( bool __v__ ) : __f__( __v__ ) { } )
@@ -170,7 +169,6 @@ typedef struct atomic_bool
                                               memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_bool*, bool*, bool,
                                               memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_bool*, memory_order );
 
 CPP0X(private:)
 #endif
@@ -191,7 +189,6 @@ typedef struct atomic_address
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( void*&, void*,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     void* fetch_add( ptrdiff_t, memory_order = memory_order_seq_cst ) volatile;
     void* fetch_sub( ptrdiff_t, memory_order = memory_order_seq_cst ) volatile;
 
@@ -218,7 +215,6 @@ typedef struct atomic_address
                               void**, void*, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_address*,
                               void**, void*, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_address*, memory_order );
     friend void* atomic_fetch_add_explicit( volatile atomic_address*, ptrdiff_t,
                                             memory_order );
     friend void* atomic_fetch_sub_explicit( volatile atomic_address*, ptrdiff_t,
@@ -247,7 +243,6 @@ typedef struct atomic_char
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( char&, char,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     char fetch_add( char,
                            memory_order = memory_order_seq_cst ) volatile;
     char fetch_sub( char,
@@ -304,7 +299,6 @@ typedef struct atomic_char
                       char*, char, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_char*,
                       char*, char, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_char*, memory_order );
     friend char atomic_fetch_add_explicit( volatile atomic_char*,
                                                   char, memory_order );
     friend char atomic_fetch_sub_explicit( volatile atomic_char*,
@@ -339,7 +333,6 @@ typedef struct atomic_schar
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( signed char&, signed char,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     signed char fetch_add( signed char,
                            memory_order = memory_order_seq_cst ) volatile;
     signed char fetch_sub( signed char,
@@ -396,7 +389,6 @@ typedef struct atomic_schar
                       signed char*, signed char, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_schar*,
                       signed char*, signed char, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_schar*, memory_order );
     friend signed char atomic_fetch_add_explicit( volatile atomic_schar*,
                                                   signed char, memory_order );
     friend signed char atomic_fetch_sub_explicit( volatile atomic_schar*,
@@ -431,7 +423,6 @@ typedef struct atomic_uchar
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( unsigned char&, unsigned char,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     unsigned char fetch_add( unsigned char,
                            memory_order = memory_order_seq_cst ) volatile;
     unsigned char fetch_sub( unsigned char,
@@ -488,7 +479,6 @@ typedef struct atomic_uchar
                       unsigned char*, unsigned char, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_uchar*,
                       unsigned char*, unsigned char, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_uchar*, memory_order );
     friend unsigned char atomic_fetch_add_explicit( volatile atomic_uchar*,
                                                   unsigned char, memory_order );
     friend unsigned char atomic_fetch_sub_explicit( volatile atomic_uchar*,
@@ -523,7 +513,6 @@ typedef struct atomic_short
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( short&, short,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     short fetch_add( short,
                            memory_order = memory_order_seq_cst ) volatile;
     short fetch_sub( short,
@@ -580,7 +569,6 @@ typedef struct atomic_short
                       short*, short, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_short*,
                       short*, short, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_short*, memory_order );
     friend short atomic_fetch_add_explicit( volatile atomic_short*,
                                                   short, memory_order );
     friend short atomic_fetch_sub_explicit( volatile atomic_short*,
@@ -615,7 +603,6 @@ typedef struct atomic_ushort
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( unsigned short&, unsigned short,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     unsigned short fetch_add( unsigned short,
                            memory_order = memory_order_seq_cst ) volatile;
     unsigned short fetch_sub( unsigned short,
@@ -672,7 +659,6 @@ typedef struct atomic_ushort
                       unsigned short*, unsigned short, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_ushort*,
                       unsigned short*, unsigned short, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_ushort*, memory_order );
     friend unsigned short atomic_fetch_add_explicit( volatile atomic_ushort*,
                                                   unsigned short, memory_order );
     friend unsigned short atomic_fetch_sub_explicit( volatile atomic_ushort*,
@@ -707,7 +693,6 @@ typedef struct atomic_int
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( int&, int,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     int fetch_add( int,
                            memory_order = memory_order_seq_cst ) volatile;
     int fetch_sub( int,
@@ -764,7 +749,6 @@ typedef struct atomic_int
                       int*, int, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_int*,
                       int*, int, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_int*, memory_order );
     friend int atomic_fetch_add_explicit( volatile atomic_int*,
                                                   int, memory_order );
     friend int atomic_fetch_sub_explicit( volatile atomic_int*,
@@ -799,7 +783,6 @@ typedef struct atomic_uint
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( unsigned int&, unsigned int,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     unsigned int fetch_add( unsigned int,
                            memory_order = memory_order_seq_cst ) volatile;
     unsigned int fetch_sub( unsigned int,
@@ -856,7 +839,6 @@ typedef struct atomic_uint
                       unsigned int*, unsigned int, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_uint*,
                       unsigned int*, unsigned int, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_uint*, memory_order );
     friend unsigned int atomic_fetch_add_explicit( volatile atomic_uint*,
                                                   unsigned int, memory_order );
     friend unsigned int atomic_fetch_sub_explicit( volatile atomic_uint*,
@@ -891,7 +873,6 @@ typedef struct atomic_long
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( long&, long,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     long fetch_add( long,
                            memory_order = memory_order_seq_cst ) volatile;
     long fetch_sub( long,
@@ -948,7 +929,6 @@ typedef struct atomic_long
                       long*, long, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_long*,
                       long*, long, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_long*, memory_order );
     friend long atomic_fetch_add_explicit( volatile atomic_long*,
                                                   long, memory_order );
     friend long atomic_fetch_sub_explicit( volatile atomic_long*,
@@ -983,7 +963,6 @@ typedef struct atomic_ulong
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( unsigned long&, unsigned long,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     unsigned long fetch_add( unsigned long,
                            memory_order = memory_order_seq_cst ) volatile;
     unsigned long fetch_sub( unsigned long,
@@ -1040,7 +1019,6 @@ typedef struct atomic_ulong
                       unsigned long*, unsigned long, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_ulong*,
                       unsigned long*, unsigned long, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_ulong*, memory_order );
     friend unsigned long atomic_fetch_add_explicit( volatile atomic_ulong*,
                                                   unsigned long, memory_order );
     friend unsigned long atomic_fetch_sub_explicit( volatile atomic_ulong*,
@@ -1075,7 +1053,6 @@ typedef struct atomic_llong
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( long long&, long long,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     long long fetch_add( long long,
                            memory_order = memory_order_seq_cst ) volatile;
     long long fetch_sub( long long,
@@ -1132,7 +1109,6 @@ typedef struct atomic_llong
                       long long*, long long, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_llong*,
                       long long*, long long, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_llong*, memory_order );
     friend long long atomic_fetch_add_explicit( volatile atomic_llong*,
                                                   long long, memory_order );
     friend long long atomic_fetch_sub_explicit( volatile atomic_llong*,
@@ -1167,7 +1143,6 @@ typedef struct atomic_ullong
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( unsigned long long&, unsigned long long,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     unsigned long long fetch_add( unsigned long long,
                            memory_order = memory_order_seq_cst ) volatile;
     unsigned long long fetch_sub( unsigned long long,
@@ -1224,7 +1199,6 @@ typedef struct atomic_ullong
                       unsigned long long*, unsigned long long, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_ullong*,
                       unsigned long long*, unsigned long long, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_ullong*, memory_order );
     friend unsigned long long atomic_fetch_add_explicit( volatile atomic_ullong*,
                                                   unsigned long long, memory_order );
     friend unsigned long long atomic_fetch_sub_explicit( volatile atomic_ullong*,
@@ -1291,7 +1265,6 @@ typedef struct atomic_wchar_t
                        memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( wchar_t&, wchar_t,
                        memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
     wchar_t fetch_add( wchar_t,
                            memory_order = memory_order_seq_cst ) volatile;
     wchar_t fetch_sub( wchar_t,
@@ -1348,7 +1321,6 @@ typedef struct atomic_wchar_t
                     wchar_t*, wchar_t, memory_order, memory_order );
     friend bool atomic_compare_exchange_strong_explicit( volatile atomic_wchar_t*,
                     wchar_t*, wchar_t, memory_order, memory_order );
-    friend void atomic_fence( const volatile atomic_wchar_t*, memory_order );
     friend wchar_t atomic_fetch_add_explicit( volatile atomic_wchar_t*,
                                                   wchar_t, memory_order );
     friend wchar_t atomic_fetch_sub_explicit( volatile atomic_wchar_t*,
@@ -1390,7 +1362,6 @@ struct atomic
     bool compare_exchange_strong( T&, T, memory_order, memory_order ) volatile;
     bool compare_exchange_weak( T&, T, memory_order = memory_order_seq_cst ) volatile;
     bool compare_exchange_strong( T&, T, memory_order = memory_order_seq_cst ) volatile;
-    void fence( memory_order ) const volatile;
 
     CPP0X( atomic() = default; )
     CPP0X( constexpr explicit atomic( T __v__ ) : __f__( __v__ ) { } )
@@ -1653,6 +1624,10 @@ inline bool atomic_load_explicit
 inline bool atomic_load
 ( volatile atomic_bool* __a__ ) { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_bool* __a__, bool __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_bool* __a__, bool __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -1689,10 +1664,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_bool* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_address* __a__ )
 { return false; }
@@ -1704,6 +1675,10 @@ inline void* atomic_load_explicit
 inline void* atomic_load( volatile atomic_address* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_address* __a__, void* __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_address* __a__, void* __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -1740,10 +1715,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_address* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_char* __a__ )
 { return false; }
@@ -1755,6 +1726,10 @@ inline char atomic_load_explicit
 inline char atomic_load( volatile atomic_char* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_char* __a__, char __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_char* __a__, char __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -1791,10 +1766,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_char* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_schar* __a__ )
 { return false; }
@@ -1806,6 +1777,10 @@ inline signed char atomic_load_explicit
 inline signed char atomic_load( volatile atomic_schar* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_schar* __a__, signed char __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_schar* __a__, signed char __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -1842,10 +1817,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_schar* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_uchar* __a__ )
 { return false; }
@@ -1857,6 +1828,10 @@ inline unsigned char atomic_load_explicit
 inline unsigned char atomic_load( volatile atomic_uchar* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_uchar* __a__, unsigned char __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_uchar* __a__, unsigned char __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -1893,10 +1868,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_uchar* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_short* __a__ )
 { return false; }
@@ -1908,6 +1879,10 @@ inline short atomic_load_explicit
 inline short atomic_load( volatile atomic_short* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_short* __a__, short __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_short* __a__, short __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -1944,10 +1919,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_short* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_ushort* __a__ )
 { return false; }
@@ -1959,6 +1930,10 @@ inline unsigned short atomic_load_explicit
 inline unsigned short atomic_load( volatile atomic_ushort* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_ushort* __a__, unsigned short __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_ushort* __a__, unsigned short __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -1995,10 +1970,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_ushort* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_int* __a__ )
 { return false; }
@@ -2010,6 +1981,10 @@ inline int atomic_load_explicit
 inline int atomic_load( volatile atomic_int* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_int* __a__, int __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_int* __a__, int __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -2046,10 +2021,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_int* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_uint* __a__ )
 { return false; }
@@ -2061,6 +2032,10 @@ inline unsigned int atomic_load_explicit
 inline unsigned int atomic_load( volatile atomic_uint* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_uint* __a__, unsigned int __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_uint* __a__, unsigned int __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -2097,10 +2072,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_uint* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_long* __a__ )
 { return false; }
@@ -2112,6 +2083,10 @@ inline long atomic_load_explicit
 inline long atomic_load( volatile atomic_long* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_long* __a__, long __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_long* __a__, long __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -2148,10 +2123,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_long* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_ulong* __a__ )
 { return false; }
@@ -2163,6 +2134,10 @@ inline unsigned long atomic_load_explicit
 inline unsigned long atomic_load( volatile atomic_ulong* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_ulong* __a__, unsigned long __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_ulong* __a__, unsigned long __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -2199,10 +2174,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_ulong* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_llong* __a__ )
 { return false; }
@@ -2214,6 +2185,10 @@ inline long long atomic_load_explicit
 inline long long atomic_load( volatile atomic_llong* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_llong* __a__, long long __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_llong* __a__, long long __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -2250,10 +2225,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_llong* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_ullong* __a__ )
 { return false; }
@@ -2265,6 +2236,10 @@ inline unsigned long long atomic_load_explicit
 inline unsigned long long atomic_load( volatile atomic_ullong* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_ullong* __a__, unsigned long long __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_ullong* __a__, unsigned long long __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -2301,10 +2276,6 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_ullong* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline bool atomic_is_lock_free( const volatile atomic_wchar_t* __a__ )
 { return false; }
@@ -2316,6 +2287,10 @@ inline wchar_t atomic_load_explicit
 inline wchar_t atomic_load( volatile atomic_wchar_t* __a__ )
 { return atomic_load_explicit( __a__, memory_order_seq_cst ); }
 
+inline void atomic_init
+( volatile atomic_wchar_t* __a__, wchar_t __m__ )
+{ _ATOMIC_INIT_( __a__, __m__ ); }
+
 inline void atomic_store_explicit
 ( volatile atomic_wchar_t* __a__, wchar_t __m__, memory_order __x__ )
 { _ATOMIC_STORE_( __a__, __m__, __x__ ); }
@@ -2352,31 +2327,32 @@ inline bool atomic_compare_exchange_strong
 { return atomic_compare_exchange_strong_explicit( __a__, __e__, __m__,
                  memory_order_seq_cst, memory_order_seq_cst ); }
 
-inline void atomic_fence
-( const volatile atomic_wchar_t* __a__, memory_order __x__ )
-{ _ATOMIC_FENCE_( __a__, __x__ ); }
-
 
 inline void* atomic_fetch_add_explicit
 ( volatile atomic_address* __a__, ptrdiff_t __m__, memory_order __x__ )
 {
-       void* volatile* __p__ = &((__a__)->__f__);
-       void* __r__ = (void *) model_rmwr_action((void *)__p__, __x__);
-       model_rmw_action((void *)__p__, __x__, (uint64_t) ((char*)(*__p__) + __m__));
-  return __r__; }
+       volatile __typeof__((__a__)->__f__)* __p__ = & ((__a__)->__f__);
+       __typeof__((__a__)->__f__) __old__=(__typeof__((__a__)->__f__)) model_rmwr_action((void *)__p__, __x__);
+       __typeof__((__a__)->__f__) __copy__= __old__;
+       __copy__ = (void *) (((char *)__copy__) + __m__);
+       model_rmw_action((void *)__p__, __x__, (uint64_t) __copy__);
+       return __old__;
+}
 
-inline void* atomic_fetch_add
+ inline void* atomic_fetch_add
 ( volatile atomic_address* __a__, ptrdiff_t __m__ )
 { return atomic_fetch_add_explicit( __a__, __m__, memory_order_seq_cst ); }
 
 
 inline void* atomic_fetch_sub_explicit
 ( volatile atomic_address* __a__, ptrdiff_t __m__, memory_order __x__ )
-{
-       void* volatile* __p__ = &((__a__)->__f__);
-       void* __r__ = (void *) model_rmwr_action((void *)__p__, __x__);
-       model_rmw_action((void *)__p__, __x__, (uint64_t)((char*)(*__p__) - __m__));
-  return __r__; }
+{      volatile __typeof__((__a__)->__f__)* __p__ = & ((__a__)->__f__);
+       __typeof__((__a__)->__f__) __old__=(__typeof__((__a__)->__f__)) model_rmwr_action((void *)__p__, __x__);
+       __typeof__((__a__)->__f__) __copy__= __old__;
+       __copy__ = (void *) (((char *)__copy__) - __m__);
+       model_rmw_action((void *)__p__, __x__, (uint64_t) __copy__);
+       return __old__;
+}
 
 inline void* atomic_fetch_sub
 ( volatile atomic_address* __a__, ptrdiff_t __m__ )
@@ -2961,9 +2937,6 @@ _ATOMIC_CMPSWP_WEAK_( __a__, __e__, __m__, __x__ )
 #define atomic_compare_exchange_strong_explicit( __a__, __e__, __m__, __x__, __y__ ) \
 _ATOMIC_CMPSWP_( __a__, __e__, __m__, __x__ )
 
-#define atomic_fence( __a__, __x__ ) \
-({ _ATOMIC_FENCE_( __a__, __x__ ); })
-
 
 #define atomic_fetch_add_explicit( __a__, __m__, __x__ ) \
 _ATOMIC_MODIFY_( __a__, +=, __m__, __x__ )
@@ -3043,10 +3016,6 @@ inline bool atomic_bool::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_bool::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_address::is_lock_free() const volatile
 { return false; }
@@ -3085,10 +3054,6 @@ inline bool atomic_address::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_address::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_char::is_lock_free() const volatile
 { return false; }
@@ -3127,10 +3092,6 @@ inline bool atomic_char::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_char::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_schar::is_lock_free() const volatile
 { return false; }
@@ -3169,10 +3130,6 @@ inline bool atomic_schar::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_schar::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_uchar::is_lock_free() const volatile
 { return false; }
@@ -3211,10 +3168,6 @@ inline bool atomic_uchar::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_uchar::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_short::is_lock_free() const volatile
 { return false; }
@@ -3253,10 +3206,6 @@ inline bool atomic_short::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_short::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_ushort::is_lock_free() const volatile
 { return false; }
@@ -3295,10 +3244,6 @@ inline bool atomic_ushort::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_ushort::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_int::is_lock_free() const volatile
 { return false; }
@@ -3337,10 +3282,6 @@ inline bool atomic_int::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_int::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_uint::is_lock_free() const volatile
 { return false; }
@@ -3379,10 +3320,6 @@ inline bool atomic_uint::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_uint::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_long::is_lock_free() const volatile
 { return false; }
@@ -3421,10 +3358,6 @@ inline bool atomic_long::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_long::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_ulong::is_lock_free() const volatile
 { return false; }
@@ -3463,10 +3396,6 @@ inline bool atomic_ulong::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_ulong::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_llong::is_lock_free() const volatile
 { return false; }
@@ -3505,10 +3434,6 @@ inline bool atomic_llong::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_llong::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_ullong::is_lock_free() const volatile
 { return false; }
@@ -3547,10 +3472,6 @@ inline bool atomic_ullong::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_ullong::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 inline bool atomic_wchar_t::is_lock_free() const volatile
 { return false; }
@@ -3589,10 +3510,6 @@ inline bool atomic_wchar_t::compare_exchange_strong
       __x__ == memory_order_acq_rel ? memory_order_acquire :
       __x__ == memory_order_release ? memory_order_relaxed : __x__ ); }
 
-inline void atomic_wchar_t::fence
-( memory_order __x__ ) const volatile
-{ return atomic_fence( this, __x__ ); }
-
 
 template< typename T >
 inline bool atomic<T>::is_lock_free() const volatile
@@ -3991,6 +3908,19 @@ T* atomic<T*>::fetch_sub( ptrdiff_t __v__, memory_order __x__ ) volatile
 
 #endif
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+static inline void atomic_thread_fence(memory_order order)
+{ _ATOMIC_FENCE_(order); }
+
+/** @todo Do we want to try to support a user's signal-handler? */
+static inline void atomic_signal_fence(memory_order order)
+{ /* No-op? */ }
+#ifdef __cplusplus
+}
+#endif
+
 
 #ifdef __cplusplus
 } // namespace std