< prev index next >

src/hotspot/share/utilities/waitBarrier.hpp

Print this page
rev 53038 : 8214271: Fast primitive to wake many threads
Reviewed-by:
rev 53039 : [mq]: 8214271-3

*** 24,88 **** #ifndef SHARE_UTILITIES_WAITBARRIER_HPP #define SHARE_UTILITIES_WAITBARRIER_HPP #include "memory/allocation.hpp" #include "utilities/waitBarrier_generic.hpp" #if defined(LINUX) #include "waitBarrier_linux.hpp" typedef LinuxWaitBarrier WaitBarrierDefault; #else typedef GenericWaitBarrier WaitBarrierDefault; #endif // Platform independent WaitBarrier API. ! // The WaitBarrier primary objective is to wake threads waiting in wait() fast. ! // It can be arm with any int, the tag, that is not 0. ! // - After arm() returns any thread calling wait(tag) with the correct tag will be blocked. ! // - After disarm() is called any thread calling wait(...) will never block. ! // - When wake() returns no threads are blocked any more, if it was disarmed before. ! // - After calling disarm() and wake() it my be re-armed immediately with a different tag. ! // - Re-arming with the same tag before all threads returned from previously wait ! // is implementation defined. They may or may not return from the previously wait(). ! // Wake thread: ! // - arm(tag) ! // - *work* ! // - disarm() ! // - wake() ! // Wait thread: ! // - wait(tag) template <typename WaitBarrierImpl> class WaitBarrierType : public CHeapObj<mtInternal> { WaitBarrierImpl _impl; // Prevent copying and assignment of WaitBarrier instances. WaitBarrierType(const WaitBarrierDefault&); WaitBarrierType& operator=(const WaitBarrierDefault&); public: ! WaitBarrierType() : _impl() {} ~WaitBarrierType() {} // Returns implementation type. const char* description() { return _impl.description(); } // Guarantees any thread calling wait() with same tag will be blocked. // Provides a trailing fence. ! void arm(int barrier_tag) { _impl.arm(barrier_tag); } // Guarantees any thread calling wait() with any tag will not be blocked. // Provides a trailing fence. ! void disarm() { _impl.disarm(); } // Guarantees any thread called wait() will be awake when it returns. // Provides a trailing fence. ! void wake() { _impl.wake(); } // Guarantees to return if disarm() and wake() is called. // Provides a trailing fence. ! void wait(int barrier_tag) { _impl.wait(barrier_tag); } }; typedef WaitBarrierType<WaitBarrierDefault> WaitBarrier; #endif // SHARE_UTILITIES_WAITBARRIER_HPP --- 24,133 ---- #ifndef SHARE_UTILITIES_WAITBARRIER_HPP #define SHARE_UTILITIES_WAITBARRIER_HPP #include "memory/allocation.hpp" + #include "runtime/thread.hpp" + #include "utilities/debug.hpp" #include "utilities/waitBarrier_generic.hpp" #if defined(LINUX) #include "waitBarrier_linux.hpp" typedef LinuxWaitBarrier WaitBarrierDefault; #else typedef GenericWaitBarrier WaitBarrierDefault; #endif // Platform independent WaitBarrier API. ! // An armed WaitBarrier prevents threads from advancing until the ! // barrier is disarmed and the waiting threads woken. The barrier is ! // armed by setting a non-zero value - the tag. ! // ! // Expected Usage: ! // - Arming thread: ! // tag = ...; // non-zero value ! // barrier.arm(tag); ! // <publish tag> ! // <work> ! // barrier.disarm(); ! // barrier.wake(); ! // ! // - After arm(tag) returns any thread calling wait(tag) will block. ! // - After disarm() returns any subsequent calls to wait(tag) will not block. ! // - After wake() returns all blocked threads are unblocked and eligible to ! // execute again. ! // - After calling disarm() and wake() the barrier is ready to be re-armed ! // with a new tag. (may not be re-armed with last used tag) ! // ! // - Waiting threads ! // wait(tag); // don't execute following code unless 'safe' ! // <work> ! // ! // - A call to wait(tag) will block if the barrier is armed with the value ! // 'tag'; else it will return immediately. ! // - A blocked thread is eligible to execute again once the barrier is ! // disarmed and wake() has been called. ! // ! // A primary goal of the WaitBarrier implementation is to wake all waiting ! // threads as fast, and as concurrently, as possible. ! // template <typename WaitBarrierImpl> class WaitBarrierType : public CHeapObj<mtInternal> { WaitBarrierImpl _impl; // Prevent copying and assignment of WaitBarrier instances. WaitBarrierType(const WaitBarrierDefault&); WaitBarrierType& operator=(const WaitBarrierDefault&); + #ifdef ASSERT + int _last_arm_tag; + Thread* _owner; + #endif + public: ! WaitBarrierType(Thread* owner) : _impl() { ! #ifdef ASSERT ! _last_arm_tag = 0; ! _owner = owner; ! #endif ! } ~WaitBarrierType() {} // Returns implementation type. const char* description() { return _impl.description(); } // Guarantees any thread calling wait() with same tag will be blocked. // Provides a trailing fence. ! void arm(int barrier_tag) { ! #ifdef ASSERT ! assert(_last_arm_tag != barrier_tag, "Re-arming with same tag"); ! _last_arm_tag = barrier_tag; ! assert(_owner == Thread::current(), "Not owner thread"); ! #endif ! _impl.arm(barrier_tag); ! } // Guarantees any thread calling wait() with any tag will not be blocked. // Provides a trailing fence. ! void disarm() { ! assert(_owner == Thread::current(), "Not owner thread"); ! _impl.disarm(); ! } // Guarantees any thread called wait() will be awake when it returns. // Provides a trailing fence. ! void wake() { ! assert(_owner == Thread::current(), "Not owner thread"); ! _impl.wake(); ! } // Guarantees to return if disarm() and wake() is called. // Provides a trailing fence. ! void wait(int barrier_tag) { ! assert(_owner != Thread::current(), "Trying to wait with owner thread"); ! _impl.wait(barrier_tag); ! } }; typedef WaitBarrierType<WaitBarrierDefault> WaitBarrier; #endif // SHARE_UTILITIES_WAITBARRIER_HPP
< prev index next >