< prev index next >

src/hotspot/share/utilities/waitBarrier.hpp

Print this page
rev 53078 : 8214271: Fast primitive to wake many threads
Reviewed-by:
rev 53079 : [mq]: 8214271-4


  24 
  25 #ifndef SHARE_UTILITIES_WAITBARRIER_HPP
  26 #define SHARE_UTILITIES_WAITBARRIER_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "runtime/thread.hpp"
  30 #include "utilities/debug.hpp"
  31 #include "utilities/waitBarrier_generic.hpp"
  32 
  33 #if defined(LINUX)
  34 #include "waitBarrier_linux.hpp"
  35 typedef LinuxWaitBarrier WaitBarrierDefault;
  36 #else
  37 typedef GenericWaitBarrier WaitBarrierDefault;
  38 #endif
  39 
  40 // Platform independent WaitBarrier API.
  41 // An armed WaitBarrier prevents threads from advancing until the
  42 // barrier is disarmed and the waiting threads woken. The barrier is
  43 // armed by setting a non-zero value - the tag.



  44 //
  45 // Expected Usage:
  46 //  - Arming thread:
  47 //     tag = ...;  // non-zero value
  48 //     barrier.arm(tag);
  49 //     <publish tag>
  50 //     <work>
  51 //     barrier.disarm();
  52 //     barrier.wake();
  53 //
  54 //    - After arm(tag) returns any thread calling wait(tag) will block.
  55 //    - After disarm() returns any subsequent calls to wait(tag) will not block.
  56 //    - After wake() returns all blocked threads are unblocked and eligible to
  57 //      execute again.
  58 //    - After calling disarm() and wake() the barrier is ready to be re-armed
  59 //      with a new tag. (may not be re-armed with last used tag)
  60 //
  61 //  - Waiting threads
  62 //     wait(tag); // don't execute following code unless 'safe'
  63 //     <work>
  64 //
  65 //    - A call to wait(tag) will block if the barrier is armed with the value
  66 //      'tag'; else it will return immediately.
  67 //    - A blocked thread is eligible to execute again once the barrier is
  68 //      disarmed and wake() has been called.
  69 //







  70 // A primary goal of the WaitBarrier implementation is to wake all waiting
  71 // threads as fast, and as concurrently, as possible.
  72 //
  73 template <typename WaitBarrierImpl>
  74 class WaitBarrierType : public CHeapObj<mtInternal> {
  75   WaitBarrierImpl _impl;
  76 
  77   // Prevent copying and assignment of WaitBarrier instances.
  78   WaitBarrierType(const WaitBarrierDefault&);
  79   WaitBarrierType& operator=(const WaitBarrierDefault&);
  80 
  81 #ifdef ASSERT
  82   int _last_arm_tag;
  83   Thread* _owner;
  84 #endif
  85 
  86  public:
  87   WaitBarrierType(Thread* owner) : _impl() {
  88 #ifdef ASSERT
  89     _last_arm_tag = 0;


 103   _last_arm_tag = barrier_tag;
 104   assert(_owner == Thread::current(), "Not owner thread");
 105 #endif
 106     _impl.arm(barrier_tag);
 107   }
 108 
 109   // Guarantees any thread calling wait() with any tag will not be blocked.
 110   // Provides a trailing fence.
 111   void disarm() {
 112     assert(_owner == Thread::current(), "Not owner thread");
 113     _impl.disarm();
 114   }
 115 
 116   // Guarantees any thread called wait() will be awake when it returns.
 117   // Provides a trailing fence.
 118   void wake() {
 119     assert(_owner == Thread::current(), "Not owner thread");
 120     _impl.wake();
 121   }
 122 



 123   // Guarantees to return if disarm() and wake() is called.
 124   // Provides a trailing fence.
 125   void wait(int barrier_tag) {
 126     assert(_owner != Thread::current(), "Trying to wait with owner thread");
 127     _impl.wait(barrier_tag);
 128   }
 129 };
 130 
 131 typedef WaitBarrierType<WaitBarrierDefault> WaitBarrier;
 132 
 133 #endif // SHARE_UTILITIES_WAITBARRIER_HPP


  24 
  25 #ifndef SHARE_UTILITIES_WAITBARRIER_HPP
  26 #define SHARE_UTILITIES_WAITBARRIER_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "runtime/thread.hpp"
  30 #include "utilities/debug.hpp"
  31 #include "utilities/waitBarrier_generic.hpp"
  32 
  33 #if defined(LINUX)
  34 #include "waitBarrier_linux.hpp"
  35 typedef LinuxWaitBarrier WaitBarrierDefault;
  36 #else
  37 typedef GenericWaitBarrier WaitBarrierDefault;
  38 #endif
  39 
  40 // Platform independent WaitBarrier API.
  41 // An armed WaitBarrier prevents threads from advancing until the
  42 // barrier is disarmed and the waiting threads woken. The barrier is
  43 // armed by setting a non-zero value - the tag.
  44 // When the WaitBarrier is created, a thread is designated the owner
  45 // and is the thread that should arm/disarm/wake the WaitBarrier. In
  46 // debug builds this is enforced.
  47 //
  48 // Expected Usage:
  49 //  - Arming thread:
  50 //     tag = ...;  // non-zero value
  51 //     barrier.arm(tag);
  52 //     <publish tag>
  53 //     <work>
  54 //     barrier.disarm();
  55 //     barrier.wake();
  56 //
  57 //    - After arm(tag) returns any thread calling wait(tag) will block.
  58 //    - After disarm() returns any subsequent calls to wait(tag) will not block.
  59 //    - After wake() returns all blocked threads are unblocked and eligible to
  60 //      execute again.
  61 //    - After calling disarm() and wake() the barrier is ready to be re-armed
  62 //      with a new tag. (may not be re-armed with last used tag)
  63 //
  64 //  - Waiting threads
  65 //     wait(tag); // don't execute following code unless 'safe'
  66 //     <work>
  67 //
  68 //    - A call to wait(tag) will block if the barrier is armed with the value
  69 //      'tag'; else it will return immediately.
  70 //    - A blocked thread is eligible to execute again once the barrier is
  71 //      disarmed and wake() has been called.
  72 //
  73 // It is a usage error to:
  74 //  - call wake on a barrier that is still armed
  75 //  - call arm on a barrier that is already armed
  76 //  - call disarm on a barrier that is not armed
  77 //  - arm with the same tag as last used
  78 // Usage errors are checked in debug builds but may be ignored otherwise.
  79 //
  80 // A primary goal of the WaitBarrier implementation is to wake all waiting
  81 // threads as fast, and as concurrently, as possible.
  82 //
  83 template <typename WaitBarrierImpl>
  84 class WaitBarrierType : public CHeapObj<mtInternal> {
  85   WaitBarrierImpl _impl;
  86 
  87   // Prevent copying and assignment of WaitBarrier instances.
  88   WaitBarrierType(const WaitBarrierDefault&);
  89   WaitBarrierType& operator=(const WaitBarrierDefault&);
  90 
  91 #ifdef ASSERT
  92   int _last_arm_tag;
  93   Thread* _owner;
  94 #endif
  95 
  96  public:
  97   WaitBarrierType(Thread* owner) : _impl() {
  98 #ifdef ASSERT
  99     _last_arm_tag = 0;


 113   _last_arm_tag = barrier_tag;
 114   assert(_owner == Thread::current(), "Not owner thread");
 115 #endif
 116     _impl.arm(barrier_tag);
 117   }
 118 
 119   // Guarantees any thread calling wait() with any tag will not be blocked.
 120   // Provides a trailing fence.
 121   void disarm() {
 122     assert(_owner == Thread::current(), "Not owner thread");
 123     _impl.disarm();
 124   }
 125 
 126   // Guarantees any thread called wait() will be awake when it returns.
 127   // Provides a trailing fence.
 128   void wake() {
 129     assert(_owner == Thread::current(), "Not owner thread");
 130     _impl.wake();
 131   }
 132 
 133   // Guarantees not to return until disarm() is called,
 134   // if called with currently armed tag (otherwise returns immediately).
 135   // Implementation must guarantee no spurious wakeups.
 136   // Guarantees to return if disarm() and wake() is called.
 137   // Provides a trailing fence.
 138   void wait(int barrier_tag) {
 139     assert(_owner != Thread::current(), "Trying to wait with owner thread");
 140     _impl.wait(barrier_tag);
 141   }
 142 };
 143 
 144 typedef WaitBarrierType<WaitBarrierDefault> WaitBarrier;
 145 
 146 #endif // SHARE_UTILITIES_WAITBARRIER_HPP
< prev index next >