/*
This file is a part of libcds - Concurrent Data Structures library
- (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+ (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
Source code repo: http://github.com/khizmax/libcds/
Download: http://sourceforge.net/projects/libcds/files/
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <gtest/gtest.h>
+#include <cds_test/ext_gtest.h>
#include <cds/algo/atomic.h>
#include "cxx11_convert_memory_order.h"
+#define EXPECT_ATOMIC_IS_LOCK_FREE( x ) EXPECT_TRUE( x.is_lock_free())
+
namespace {
class cxx11_atomic_class: public ::testing::Test
{
{
typedef Integral integral_type;
- EXPECT_TRUE( a.is_lock_free());
+ EXPECT_ATOMIC_IS_LOCK_FREE( a );
a.store( (integral_type) 0 );
- EXPECT_EQ( a, static_cast<integral_type>( 0 ));
EXPECT_EQ( a.load(), static_cast<integral_type>( 0 ));
for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) {
- integral_type n = integral_type(42) << (nByte * 8);
+ integral_type n = static_cast<integral_type>( integral_type(42) << (nByte * 8));
EXPECT_EQ( a.exchange( n ), static_cast<integral_type>( 0 ));
- EXPECT_EQ( a, n );
+ EXPECT_EQ( a.load(), n );
EXPECT_EQ( a.exchange( (integral_type) 0 ), n );
EXPECT_EQ( a.load(), static_cast<integral_type>( 0 ));
}
integral_type prev = a.load();
for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) {
- integral_type n = integral_type(42) << (nByte * 8);
+ integral_type n = static_cast<integral_type>( integral_type(42) << (nByte * 8));
integral_type expected = prev;
EXPECT_TRUE( a.compare_exchange_weak( expected, n));
EXPECT_EQ( expected, n );
prev = n;
- EXPECT_EQ( a, n );
+ EXPECT_EQ( a.load(), n );
}
a = (integral_type) 0;
prev = a;
for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) {
- integral_type n = integral_type(42) << (nByte * 8);
+ integral_type n = static_cast<integral_type>( integral_type(42) << (nByte * 8));
integral_type expected = prev;
EXPECT_TRUE( a.compare_exchange_strong( expected, n));
for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte )
{
integral_type prev = a.load();
- integral_type n = integral_type(42) << (nByte * 8);
+ integral_type n = static_cast<integral_type>( integral_type(42) << (nByte * 8));
EXPECT_EQ( a.fetch_add(n), prev);
}
for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte )
{
integral_type prev = a.load();
- integral_type n = integral_type(42) << ((nByte - 1) * 8);
+ integral_type n = static_cast<integral_type>( integral_type(42) << ((nByte - 1) * 8));
EXPECT_EQ( a.fetch_sub(n), prev);
}
for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit )
{
integral_type prev = a.load() ;;
- integral_type mask = integral_type(1) << nBit;
+ integral_type mask = static_cast<integral_type>( integral_type(1) << nBit );
EXPECT_EQ( a.fetch_or( mask ), prev );
prev = a.load();
for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte )
{
integral_type prev = a;
- integral_type n = integral_type(42) << (nByte * 8);
+ integral_type n = static_cast<integral_type>( integral_type(42) << (nByte * 8));
EXPECT_EQ( (a += n), (prev + n));
}
for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte )
{
integral_type prev = a;
- integral_type n = integral_type(42) << ((nByte - 1) * 8);
+ integral_type n = static_cast<integral_type>( integral_type(42) << ((nByte - 1) * 8));
EXPECT_EQ( (a -= n), prev - n );
}
for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit )
{
integral_type prev = a;
- integral_type mask = integral_type(1) << nBit;
+ integral_type mask = static_cast<integral_type>( integral_type(1) << nBit );
EXPECT_EQ( (a |= mask ), (prev | mask ));
prev = a;
prev = a;
EXPECT_EQ( ( prev & mask), mask);
}
- EXPECT_EQ( a, (integral_type) -1 );
+ EXPECT_EQ( a.load(), (integral_type) -1 );
}
template <class Atomic, typename Integral>
const atomics::memory_order oLoad = convert_to_load_order( order );
const atomics::memory_order oStore = convert_to_store_order( order );
- EXPECT_TRUE( a.is_lock_free());
+ EXPECT_ATOMIC_IS_LOCK_FREE( a );
a.store((integral_type) 0, oStore );
- EXPECT_EQ( a, integral_type( 0 ));
EXPECT_EQ( a.load( oLoad ), integral_type( 0 ));
for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) {
- integral_type n = integral_type(42) << (nByte * 8);
+ integral_type n = static_cast<integral_type>( integral_type(42) << (nByte * 8));
EXPECT_EQ( a.exchange( n, order ), integral_type( 0 ));
EXPECT_EQ( a.load( oLoad ), n );
EXPECT_EQ( a.exchange( (integral_type) 0, order ), n );
integral_type prev = a.load( oLoad );
for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) {
- integral_type n = integral_type(42) << (nByte * 8);
+ integral_type n = static_cast<integral_type>( integral_type(42) << (nByte * 8));
integral_type expected = prev;
EXPECT_TRUE( a.compare_exchange_weak( expected, n, order, atomics::memory_order_relaxed));
prev = a.load( oLoad );
for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) {
- integral_type n = integral_type(42) << (nByte * 8);
+ integral_type n = static_cast<integral_type>( integral_type(42) << (nByte * 8));
integral_type expected = prev;
EXPECT_TRUE( a.compare_exchange_strong( expected, n, order, atomics::memory_order_relaxed));
for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte )
{
integral_type prev = a.load( oLoad );
- integral_type n = integral_type(42) << (nByte * 8);
+ integral_type n = static_cast<integral_type>( integral_type(42) << (nByte * 8));
EXPECT_EQ( a.fetch_add( n, order), prev);
}
for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte )
{
integral_type prev = a.load( oLoad );
- integral_type n = integral_type(42) << ((nByte - 1) * 8);
+ integral_type n = static_cast<integral_type>( integral_type(42) << ((nByte - 1) * 8));
EXPECT_EQ( a.fetch_sub( n, order ), prev);
}
for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit )
{
integral_type prev = a.load( oLoad ) ;;
- integral_type mask = integral_type(1) << nBit;
+ integral_type mask = static_cast<integral_type>( integral_type(1) << nBit );
EXPECT_EQ( a.fetch_or( mask, order ), prev );
prev = a.load( oLoad );
template <class AtomicBool>
void do_test_atomic_bool( AtomicBool& a )
{
- EXPECT_TRUE( a.is_lock_free());
+ EXPECT_ATOMIC_IS_LOCK_FREE( a );
a.store( false );
EXPECT_FALSE( a );
EXPECT_FALSE( a.load());
const atomics::memory_order oStore = convert_to_store_order( order );
const atomics::memory_order oExchange = convert_to_exchange_order( order );
- EXPECT_TRUE( a.is_lock_free());
+ EXPECT_ATOMIC_IS_LOCK_FREE( a );
a.store( false, oStore );
EXPECT_FALSE( a );
EXPECT_FALSE( a.load( oLoad ));
template <typename Atomic>
void do_test_atomic_pointer_void_( Atomic& a, char * arr, char aSize, atomics::memory_order order )
{
+ CDS_UNUSED( aSize );
+
atomics::memory_order oLoad = convert_to_load_order(order);
atomics::memory_order oStore = convert_to_store_order(order);
void * p;
EXPECT_EQ( reinterpret_cast<char *>(a.exchange( (void *) arr, order )), arr + 3 );
EXPECT_EQ( reinterpret_cast<char *>(a.load( oLoad )), arr );
EXPECT_EQ( *reinterpret_cast<char *>(a.load( oLoad )), 1 );
-
- for ( char i = 1; i < aSize; ++i ) {
- EXPECT_EQ( *reinterpret_cast<char *>(a.load( oLoad )), i );
- a.fetch_add( 1, order );
- EXPECT_EQ( *reinterpret_cast<char *>(a.load( oLoad )), i + 1 );
- }
-
- for ( char i = aSize; i > 1; --i ) {
- EXPECT_EQ( *reinterpret_cast<char *>(a.load( oLoad )), i );
- a.fetch_sub( 1, order );
- EXPECT_EQ( *reinterpret_cast<char *>(a.load( oLoad )), i - 1 );
- }
}
template <bool Volatile>
char arr[8];
const char aSize = sizeof(arr)/sizeof(arr[0]);
for ( char i = 0; i < aSize; ++i ) {
- arr[unsigned(i)] = i + 1;
+ arr[static_cast<unsigned>( i )] = i + 1;
}
atomic_pointer a;
EXPECT_EQ( reinterpret_cast<char *>( a.load()), arr );
EXPECT_EQ( *reinterpret_cast<char *>( a.load()), 1 );
- for ( char i = 1; i < aSize; ++i ) {
- EXPECT_EQ( *reinterpret_cast<char *>(a.load()), i );
- a.fetch_add( 1 );
- EXPECT_EQ( *reinterpret_cast<char *>(a.load()), i + 1 );
- }
-
- for ( char i = aSize; i > 1; --i ) {
- EXPECT_EQ( *reinterpret_cast<char *>(a.load()), i );
- a.fetch_sub( 1 );
- EXPECT_EQ( *reinterpret_cast<char *>(a.load()), i - 1 );
- }
-
do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_relaxed );
do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_acquire );
do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_release );
EXPECT_EQ( *a.load( oLoad ), 1 );
for ( integral_type i = 1; i < aSize; ++i ) {
- integral_type * p = a.load();
+ p = a.load();
EXPECT_EQ( *p, i );
EXPECT_EQ( a.fetch_add( 1, order ), p );
EXPECT_EQ( *a.load( oLoad ), i + 1 );
}
for ( integral_type i = aSize; i > 1; --i ) {
- integral_type * p = a.load();
+ p = a.load();
EXPECT_EQ( *p, i );
EXPECT_EQ( a.fetch_sub( 1, order ), p );
EXPECT_EQ( *a.load( oLoad ), i - 1 );
integral_type arr[8];
const integral_type aSize = sizeof(arr)/sizeof(arr[0]);
for ( integral_type i = 0; i < aSize; ++i ) {
- arr[size_t(i)] = i + 1;
+ arr[static_cast<size_t>(i)] = i + 1;
}
atomic_pointer a;
EXPECT_EQ( *a.load(), 1 );
for ( integral_type i = 1; i < aSize; ++i ) {
- integral_type * p = a.load();
+ p = a.load();
EXPECT_EQ( *p, i );
integral_type * pa = a.fetch_add( 1 );
EXPECT_EQ( pa, p );
}
for ( integral_type i = aSize; i > 1; --i ) {
- integral_type * p = a.load();
+ p = a.load();
EXPECT_EQ( *p, i );
EXPECT_EQ( a.fetch_sub( 1 ), p );
EXPECT_EQ( *a.load(), i - 1 );
test_atomic_integral_volatile<unsigned long long>();
}
-#if !( CDS_COMPILER == CDS_COMPILER_CLANG && defined(_LIBCPP_VERSION) && CDS_COMPILER_VERSION < 40000 )
- //clang error (libc++) with atomic<void> fetch_add/fetch_sub
TEST_F( cxx11_atomic_class, atomic_pointer_void )
{
do_test_atomic_pointer_void<false>();
{
do_test_atomic_pointer_void<true>();
}
-#endif
TEST_F( cxx11_atomic_class, atomic_pointer_char )
{