Fixed 64bit operations issues on 32bit architecture
authorkhizmax <khizmax@gmail.com>
Mon, 7 Nov 2016 14:36:28 +0000 (17:36 +0300)
committerkhizmax <khizmax@gmail.com>
Mon, 7 Nov 2016 14:36:28 +0000 (17:36 +0300)
cds/algo/int_algo.h
test/unit/misc/bitop.cpp
test/unit/misc/cxx11_atomic_class.cpp
test/unit/misc/cxx11_atomic_func.cpp
test/unit/misc/split_bitstring.cpp

index 4593f3c5f92c585a6348a80f81c2da99f0e76299..5c0436ea6d80f71692a0942eca4f198a0b4e585a 100644 (file)
@@ -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
index dfbe8dfaea391733df93724cb775fda2f18f404f..4f64931c9990d1b98804e3c6b2fbe2d7007a7290 100644 (file)
@@ -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 )
         {
index 8102d3555b47955f12fcf30c36da5d3727b18572..e75141b4d36747b48287aeee1c26515c225c8332 100644 (file)
@@ -73,13 +73,13 @@ namespace {
 
             EXPECT_TRUE( a.is_lock_free());
             a.store( (integral_type) 0 );
-            EXPECT_EQ( a, static_cast<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);
                 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 ));
             }
@@ -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 <class Atomic, typename Integral>
@@ -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 ) {
index 4f7255de8d3b8f4c9a60921e3f93f92a5282cba6..417752fb2b2faf3e015a94a0c203ca24fbf017f5 100644 (file)
@@ -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 ) {
index ffb11acc5cb680e3dee2b9fef408836996845ab6..27f7dc0c40dd11038077eacf67fc524f7f92c003 100644 (file)
@@ -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<size_t>(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<uint64_t>(splitter.cut( 1 )) << i);