Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / fiber / detail / spinlock_ttas_adaptive.hpp
index c6a9a57..da044b6 100644 (file)
@@ -31,11 +31,8 @@ private:
         unlocked
     };
 
-    // align shared variable 'state_' at cache line to prevent false sharing
-    alignas(cache_alignment) std::atomic< spinlock_status > state_{ spinlock_status::unlocked };
-    std::atomic< std::size_t >                              tests_{ 0 };
-    // padding to avoid other data one the cacheline of shared variable 'state_'
-    char                                                    pad[cacheline_length];
+    std::atomic< spinlock_status >  state_{ spinlock_status::unlocked };
+    std::atomic< std::size_t >      tests_{ 0 };
 
 public:
     spinlock_ttas_adaptive() noexcept = default;
@@ -67,8 +64,9 @@ public:
                     // delays the next instruction's execution for a finite period of time (depends on processor family)
                     // the CPU is not under demand, parts of the pipeline are no longer being used
                     // -> reduces the power consumed by the CPU
+                    // -> prevent pipeline stalls
                     cpu_relax();
-                } else if ( BOOST_FIBERS_SPIN_MAX_TESTS + 20 > tests) {
+                } else {
                     ++tests;
                     // std::this_thread::sleep_for( 0us) has a fairly long instruction path length,
                     // combined with an expensive ring3 to ring 0 transition costing about 1000 cycles
@@ -76,11 +74,6 @@ public:
                     // if and only if a thread of equal or greater priority is ready to run
                     static constexpr std::chrono::microseconds us0{ 0 };
                     std::this_thread::sleep_for( us0);
-                } else {
-                    // std::this_thread::yield() allows this_thread to give up the remaining part of its time slice,
-                    // but only to another thread on the same processor
-                    // instead of constant checking, a thread only checks if no other useful work is pending
-                    std::this_thread::yield();
                 }
 #else
                 std::this_thread::yield();
@@ -93,10 +86,12 @@ public:
                 // utilize 'Binary Exponential Backoff' algorithm
                 // linear_congruential_engine is a random number engine based on Linear congruential generator (LCG)
                 static thread_local std::minstd_rand generator;
-                const std::size_t z =
-                    std::uniform_int_distribution< std::size_t >{ 0, static_cast< std::size_t >( 1) << collisions }( generator);
+                static std::uniform_int_distribution< std::size_t > distribution{ 0, static_cast< std::size_t >( 1) << collisions };
+                const std::size_t z = distribution( generator);
                 ++collisions;
                 for ( std::size_t i = 0; i < z; ++i) {
+                    // -> reduces the power consumed by the CPU
+                    // -> prevent pipeline stalls
                     cpu_relax();
                 }
             } else {