< 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 >