From: khizmax Date: Mon, 7 Nov 2016 14:36:28 +0000 (+0300) Subject: Fixed 64bit operations issues on 32bit architecture X-Git-Tag: v2.2.0~78 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=libcds.git;a=commitdiff_plain;h=ae5ba1cd6256cab6598225e009d432a071134450 Fixed 64bit operations issues on 32bit architecture --- diff --git a/cds/algo/int_algo.h b/cds/algo/int_algo.h index 4593f3c5..5c0436ea 100644 --- a/cds/algo/int_algo.h +++ b/cds/algo/int_algo.h @@ -97,6 +97,45 @@ namespace cds { namespace beans { { return is_power2(n) ? log2floor(n) : 0; } + +#if CDS_BUILD_BITS == 32 + //@cond + // 64bit specializations + + static inline uint64_t log2floor( uint64_t n ) + { + return n ? cds::bitop::MSBnz( n ) : 0; + } + + static inline uint64_t log2ceil( uint64_t n ) + { + uint64_t i = log2floor( n ); + return (uint64_t( 1 ) << i) < n ? i + 1 : i; + } + + static inline uint64_t floor2( uint64_t n ) + { + return uint64_t( 1 ) << log2floor( n ); + } + + static inline uint64_t ceil2( uint64_t n ) + { + return uint64_t( 1 ) << log2ceil( n ); + } + + CDS_CONSTEXPR static inline bool is_power2( uint64_t n ) CDS_NOEXCEPT + { + return (n & (n - 1)) == 0 && n; + } + + static inline uint64_t log2( uint64_t n ) + { + return is_power2( n ) ? log2floor( n ) : 0; + } + + //@endcond +#endif + }} // namespace cds::beans #endif // #ifndef CDSLIB_INT_ALGO_H diff --git a/test/unit/misc/bitop.cpp b/test/unit/misc/bitop.cpp index dfbe8dfa..4f64931c 100644 --- a/test/unit/misc/bitop.cpp +++ b/test/unit/misc/bitop.cpp @@ -83,15 +83,15 @@ namespace { TEST_F( bitop, floor_pow2 ) { - EXPECT_EQ( cds::beans::floor2( 0 ), 1u ); - EXPECT_EQ( cds::beans::floor2( 1 ), 1u ); - EXPECT_EQ( cds::beans::floor2( 2 ), 2u ); - EXPECT_EQ( cds::beans::floor2( 3 ), 2u ); - EXPECT_EQ( cds::beans::floor2( 4 ), 4u ); - EXPECT_EQ( cds::beans::floor2( 5 ), 4u ); - EXPECT_EQ( cds::beans::floor2( 7 ), 4u ); - EXPECT_EQ( cds::beans::floor2( 8 ), 8u ); - EXPECT_EQ( cds::beans::floor2( 9 ), 8u ); + EXPECT_EQ( cds::beans::floor2( 0u ), 1u ); + EXPECT_EQ( cds::beans::floor2( 1u ), 1u ); + EXPECT_EQ( cds::beans::floor2( 2u ), 2u ); + EXPECT_EQ( cds::beans::floor2( 3u ), 2u ); + EXPECT_EQ( cds::beans::floor2( 4u ), 4u ); + EXPECT_EQ( cds::beans::floor2( 5u ), 4u ); + EXPECT_EQ( cds::beans::floor2( 7u ), 4u ); + EXPECT_EQ( cds::beans::floor2( 8u ), 8u ); + EXPECT_EQ( cds::beans::floor2( 9u ), 8u ); for ( uint32_t n = 2; n; n <<= 1 ) { @@ -109,15 +109,15 @@ namespace { TEST_F( bitop, ceil_pow2 ) { - EXPECT_EQ( cds::beans::ceil2( 0 ), 1u ); - EXPECT_EQ( cds::beans::ceil2( 1 ), 1u ); - EXPECT_EQ( cds::beans::ceil2( 2 ), 2u ); - EXPECT_EQ( cds::beans::ceil2( 3 ), 4u ); - EXPECT_EQ( cds::beans::ceil2( 4 ), 4u ); - EXPECT_EQ( cds::beans::ceil2( 5 ), 8u ); - EXPECT_EQ( cds::beans::ceil2( 7 ), 8u ); - EXPECT_EQ( cds::beans::ceil2( 8 ), 8u ); - EXPECT_EQ( cds::beans::ceil2( 9 ), 16u ); + EXPECT_EQ( cds::beans::ceil2( 0u ), 1u ); + EXPECT_EQ( cds::beans::ceil2( 1u ), 1u ); + EXPECT_EQ( cds::beans::ceil2( 2u ), 2u ); + EXPECT_EQ( cds::beans::ceil2( 3u ), 4u ); + EXPECT_EQ( cds::beans::ceil2( 4u ), 4u ); + EXPECT_EQ( cds::beans::ceil2( 5u ), 8u ); + EXPECT_EQ( cds::beans::ceil2( 7u ), 8u ); + EXPECT_EQ( cds::beans::ceil2( 8u ), 8u ); + EXPECT_EQ( cds::beans::ceil2( 9u ), 16u ); for ( uint32_t n = 4; n < (uint32_t(1) << 31); n <<= 1 ) { diff --git a/test/unit/misc/cxx11_atomic_class.cpp b/test/unit/misc/cxx11_atomic_class.cpp index 8102d355..e75141b4 100644 --- a/test/unit/misc/cxx11_atomic_class.cpp +++ b/test/unit/misc/cxx11_atomic_class.cpp @@ -73,13 +73,13 @@ namespace { EXPECT_TRUE( a.is_lock_free()); a.store( (integral_type) 0 ); - EXPECT_EQ( a, static_cast( 0 )); + //EXPECT_EQ( a, static_cast( 0 )); EXPECT_EQ( a.load(), static_cast( 0 )); for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { integral_type n = integral_type(42) << (nByte * 8); EXPECT_EQ( a.exchange( n ), static_cast( 0 )); - EXPECT_EQ( a, n ); + EXPECT_EQ( a.load(), n ); EXPECT_EQ( a.exchange( (integral_type) 0 ), n ); EXPECT_EQ( a.load(), static_cast( 0 )); } @@ -95,7 +95,7 @@ namespace { EXPECT_EQ( expected, n ); prev = n; - EXPECT_EQ( a, n ); + EXPECT_EQ( a.load(), n ); } a = (integral_type) 0; @@ -207,7 +207,7 @@ namespace { prev = a; EXPECT_EQ( ( prev & mask), mask); } - EXPECT_EQ( a, (integral_type) -1 ); + EXPECT_EQ( a.load(), (integral_type) -1 ); } template @@ -220,7 +220,7 @@ namespace { EXPECT_TRUE( a.is_lock_free()); a.store((integral_type) 0, oStore ); - EXPECT_EQ( a, integral_type( 0 )); + //EXPECT_EQ( a, integral_type( 0 )); EXPECT_EQ( a.load( oLoad ), integral_type( 0 )); for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { diff --git a/test/unit/misc/cxx11_atomic_func.cpp b/test/unit/misc/cxx11_atomic_func.cpp index 4f7255de..417752fb 100644 --- a/test/unit/misc/cxx11_atomic_func.cpp +++ b/test/unit/misc/cxx11_atomic_func.cpp @@ -83,7 +83,7 @@ namespace misc { EXPECT_TRUE( atomics::atomic_is_lock_free( &a )); atomics::atomic_store( &a, (integral_type) 0 ); - EXPECT_EQ( a, integral_type( 0 )); + //EXPECT_EQ( a, integral_type( 0 )); EXPECT_EQ( atomics::atomic_load( &a ), integral_type( 0 )); for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { @@ -188,7 +188,7 @@ namespace misc { EXPECT_TRUE( atomics::atomic_is_lock_free( &a )); atomics::atomic_store_explicit( &a, (integral_type) 0, oStore ); - EXPECT_EQ( a, integral_type( 0 )); + //EXPECT_EQ( a, integral_type( 0 )); EXPECT_EQ( atomics::atomic_load_explicit( &a, oLoad ), (integral_type) 0 ); for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { diff --git a/test/unit/misc/split_bitstring.cpp b/test/unit/misc/split_bitstring.cpp index ffb11acc..27f7dc0c 100644 --- a/test/unit/misc/split_bitstring.cpp +++ b/test/unit/misc/split_bitstring.cpp @@ -203,7 +203,7 @@ namespace { // Cut each hex digit splitter.reset(); - for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) { + for ( size_t i = 0; i < sizeof(src) * 2; ++i ) { ASSERT_FALSE( splitter.eos()); ASSERT_FALSE( !splitter ); EXPECT_EQ( static_cast(splitter.cut( 4 )), i ); @@ -215,7 +215,7 @@ namespace { { splitter.reset(); res = 0; - for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) { + for ( size_t i = 0; i < sizeof(src) * 8; ++i ) { ASSERT_FALSE( splitter.eos()); ASSERT_FALSE( !splitter ); res = res + ( static_cast(splitter.cut( 1 )) << i);