diff --git a/include/etl/atomic/atomic_gcc_sync.h b/include/etl/atomic/atomic_gcc_sync.h index 80ce7c2d..e2d51cd9 100644 --- a/include/etl/atomic/atomic_gcc_sync.h +++ b/include/etl/atomic/atomic_gcc_sync.h @@ -36,10 +36,12 @@ SOFTWARE. #include "../char_traits.h" #include +#include #if defined(ETL_COMPILER_GCC) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wunused-value" #endif namespace etl @@ -94,100 +96,100 @@ namespace etl // Pre-increment T operator ++() { - return fetch_add(1) + 1; + return __sync_add_and_fetch(&value, 1); } T operator ++() volatile { - return fetch_add(1) + 1; + return __sync_add_and_fetch(&value, 1); } // Post-increment T operator ++(int) { - return fetch_add(1); + return __sync_fetch_and_add(&value, 1); } T operator ++(int) volatile { - return fetch_add(1); + return __sync_fetch_and_add(&value, 1); } // Pre-decrement T operator --() { - return fetch_sub(1) + 1; + return __sync_sub_and_fetch(&value, 1); } T operator --() volatile { - return fetch_sub(1) + 1; + return __sync_sub_and_fetch(&value, 1); } // Post-decrement T operator --(int) { - return fetch_sub(1); + return __sync_fetch_and_sub(&value, 1); } T operator --(int) volatile { - return fetch_sub(1); + return __sync_fetch_and_sub(&value, 1); } // Add T operator +=(T v) { - return fetch_add(v) + v; + return __sync_fetch_and_add(&value, v); } T operator +=(T v) volatile { - return fetch_add(v) + v; + return __sync_fetch_and_add(&value, v); } // Subtract T operator -=(T v) { - return fetch_sub(v) - v; + return __sync_fetch_and_sub(&value, v); } T operator -=(T v) volatile { - return fetch_sub(v) - v; + return __sync_fetch_and_sub(&value, v); } // And T operator &=(T v) { - return fetch_and(v) & v; + return __sync_fetch_and_and(&value, v); } T operator &=(T v) volatile { - return fetch_and(v) & v; + return __sync_fetch_and_and(&value, v); } // Or T operator |=(T v) { - return fetch_or(v) | v; + return __sync_fetch_and_or(&value, v); } T operator |=(T v) volatile { - return fetch_or(v) | v; + return __sync_fetch_and_or(&value, v); } // Exclusive or T operator ^=(T v) { - return fetch_xor(v) ^ v; + return __sync_fetch_and_xor(&value, v); } T operator ^=(T v) volatile { - return fetch_xor(v) ^ v; + return __sync_fetch_and_xor(&value, v); } // Conversion operator @@ -215,12 +217,12 @@ namespace etl // Store void store(T v, etl::memory_order order = etl::memory_order_seq_cst) { - __sync_lock_test_and_set(&value, v); + (void)__sync_lock_test_and_set(&value, v); } void store(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile { - __sync_lock_test_and_set(&value, v); + (void)__sync_lock_test_and_set(&value, v); } // Load @@ -467,73 +469,73 @@ namespace etl // Pre-increment T* operator ++() { - return fetch_add(1) + 1; + return (T*)__sync_add_and_fetch(&value, sizeof(T)); } T* operator ++() volatile { - return fetch_add(1) + 1; + return (T*)__sync_add_and_fetch(&value, sizeof(T)); } // Post-increment T* operator ++(int) { - return fetch_add(1); + return (T*)__sync_fetch_and_add(&value, sizeof(T)); } T* operator ++(int) volatile { - return fetch_add(1); + return (T*)__sync_fetch_and_add(&value, sizeof(T)); } // Pre-decrement T* operator --() { - return fetch_sub(1) + 1; + return (T*)__sync_sub_and_fetch(&value, sizeof(T)); } T* operator --() volatile { - return fetch_sub(1) + 1; + return (T*)__sync_sub_and_fetch(&value, sizeof(T)); } // Post-decrement T* operator --(int) { - return fetch_sub(1); + return (T*)__sync_fetch_and_sub(&value, sizeof(T)); } T* operator --(int) volatile { - return fetch_sub(1); + return (T*)__sync_fetch_and_sub(&value, sizeof(T)); } // Add T* operator +=(ptrdiff_t v) { - return fetch_add(v) + v; + return (T*)__sync_fetch_and_add(&value, v * sizeof(T)); } T* operator +=(ptrdiff_t v) volatile { - return fetch_add(v) + v; + return (T*)__sync_fetch_and_add(&value, v * sizeof(T)); } // Subtract T* operator -=(ptrdiff_t v) { - return fetch_sub(v) - v; + return (T*)__sync_fetch_and_sub(&value, v * sizeof(T)); } T* operator -=(ptrdiff_t v) volatile { - return fetch_sub(v) - v; + return (T*)__sync_fetch_and_sub(&value, v * sizeof(T)); } // Conversion operator operator T* () const { - return __sync_fetch_and_add(&value, 0); + return (T*)__sync_fetch_and_add(&value, 0); } operator T*() volatile const @@ -566,7 +568,7 @@ namespace etl // Load T* load(etl::memory_order order = etl::memory_order_seq_cst) const { - return __sync_fetch_and_add(&value, 0); + return (T*)__sync_fetch_and_add(&value, 0); } T* load(etl::memory_order order = etl::memory_order_seq_cst) const volatile @@ -577,34 +579,34 @@ namespace etl // Fetch add T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst) { - return __sync_fetch_and_add(&value, v); + return (T*)__sync_fetch_and_add(&value, v); } T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst) volatile { - return __sync_fetch_and_add(&value, v); + return (T*)__sync_fetch_and_add(&value, v); } // Fetch subtract T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst) { - return __sync_fetch_and_sub(&value, v); + return (T*)__sync_fetch_and_sub(&value, v); } T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst) volatile { - return __sync_fetch_and_sub(&value, v); + return (T*)__sync_fetch_and_sub(&value, v); } // Exchange T* exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst) { - return __sync_lock_test_and_set(&value, v); + return (T*)__sync_lock_test_and_set(&value, v); } T* exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst) volatile { - return __sync_lock_test_and_set(&value, v); + return (T*)__sync_lock_test_and_set(&value, v); } // Compare exchange weak diff --git a/include/etl/version.h b/include/etl/version.h index 635c2ac0..8455c357 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -39,7 +39,7 @@ SOFTWARE. #define ETL_VERSION_MAJOR 14 #define ETL_VERSION_MINOR 29 -#define ETL_VERSION_PATCH 1 +#define ETL_VERSION_PATCH 2 #define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) ETL_STRINGIFY(ETL_VERSION_MINOR) ETL_STRINGIFY(ETL_VERSION_PATCH) #define ETL_VERSION_W ETL_WIDE_STRING(ETL_CONCAT(ETL_CONCAT(ETL_VERSION_MAJOR, ETL_VERSION_MINOR), ETL_VERSION_PATCH)) diff --git a/support/Release notes.txt b/support/Release notes.txt index 2965cdf5..68785460 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,7 @@ +=============================================================================== +14.29.2 +Fixed incorrect results returned from pointers for atomic_gcc_sync + =============================================================================== 14.29.1 Added #include "stl/utility.h" to etl::optional diff --git a/test/test_atomic_gcc_sync.cpp b/test/test_atomic_gcc_sync.cpp index 8f26a827..db6c7b0e 100644 --- a/test/test_atomic_gcc_sync.cpp +++ b/test/test_atomic_gcc_sync.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include "etl/platform.h" -#include "etl/atomic/atomic_std.h" +#include "etl/atomic/atomic_gcc_sync.h" #include @@ -173,8 +173,8 @@ namespace std::atomic compare(&data[0]); etl::atomic test(&data[0]); - CHECK_EQUAL((int*)++compare, (int*)++test); - CHECK_EQUAL((int*)++compare, (int*)++test); + CHECK_EQUAL((int*)++compare, (int*)++test); + CHECK_EQUAL((int*)++compare, (int*)++test); } //========================================================================= @@ -265,8 +265,8 @@ namespace std::atomic compare(1); etl::atomic test(1); - compare += 2; - test += 2; + compare -= 2; + test -= 2; CHECK_EQUAL((int)compare, (int)test); } @@ -279,8 +279,8 @@ namespace std::atomic compare(&data[3]); etl::atomic test(&data[3]); - compare += 2; - test += 2; + compare -= 2; + test -= 2; CHECK_EQUAL((int*)compare, (int*)test); } diff --git a/test/test_atomic_std.cpp b/test/test_atomic_std.cpp index f1655549..ba8de484 100644 --- a/test/test_atomic_std.cpp +++ b/test/test_atomic_std.cpp @@ -265,8 +265,8 @@ namespace std::atomic compare(1); etl::atomic test(1); - compare += 2; - test += 2; + compare -= 2; + test -= 2; CHECK_EQUAL((int)compare, (int)test); } @@ -279,8 +279,8 @@ namespace std::atomic compare(&data[3]); etl::atomic test(&data[3]); - compare += 2; - test += 2; + compare -= 2; + test -= 2; CHECK_EQUAL((int*)compare, (int*)test); }