< 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,65 +24,110 @@
 
 #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.
-// 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)
+// 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() : _impl() {}
+  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)    { _impl.arm(barrier_tag); }
+  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()                { _impl.disarm(); }
+  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()                  { _impl.wake(); }
+  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)   { _impl.wait(barrier_tag); }
+  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 >