9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_UTILITIES_WAITBARRIER_HPP
26 #define SHARE_UTILITIES_WAITBARRIER_HPP
27
28 #include "memory/allocation.hpp"
29 #include "utilities/waitBarrier_generic.hpp"
30
31 #if defined(LINUX)
32 #include "waitBarrier_linux.hpp"
33 typedef LinuxWaitBarrier WaitBarrierDefault;
34 #else
35 typedef GenericWaitBarrier WaitBarrierDefault;
36 #endif
37
38 // Platform independent WaitBarrier API.
39 // The WaitBarrier primary objective is to wake threads waiting in wait() fast.
40 // It can be arm with any int, the tag, that is not 0.
41 // - After arm() returns any thread calling wait(tag) with the correct tag will be blocked.
42 // - After disarm() is called any thread calling wait(...) will never block.
43 // - When wake() returns no threads are blocked any more, if it was disarmed before.
44 // - After calling disarm() and wake() it my be re-armed immediately with a different tag.
45 // - Re-arming with the same tag before all threads returned from previously wait
46 // is implementation defined. They may or may not return from the previously wait().
47 // Wake thread:
48 // - arm(tag)
49 // - *work*
50 // - disarm()
51 // - wake()
52 // Wait thread:
53 // - wait(tag)
54 template <typename WaitBarrierImpl>
55 class WaitBarrierType : public CHeapObj<mtInternal> {
56 WaitBarrierImpl _impl;
57
58 // Prevent copying and assignment of WaitBarrier instances.
59 WaitBarrierType(const WaitBarrierDefault&);
60 WaitBarrierType& operator=(const WaitBarrierDefault&);
61
62 public:
63 WaitBarrierType() : _impl() {}
64 ~WaitBarrierType() {}
65
66 // Returns implementation type.
67 const char* description() { return _impl.description(); }
68
69 // Guarantees any thread calling wait() with same tag will be blocked.
70 // Provides a trailing fence.
71 void arm(int barrier_tag) { _impl.arm(barrier_tag); }
72
73 // Guarantees any thread calling wait() with any tag will not be blocked.
74 // Provides a trailing fence.
75 void disarm() { _impl.disarm(); }
76
77 // Guarantees any thread called wait() will be awake when it returns.
78 // Provides a trailing fence.
79 void wake() { _impl.wake(); }
80
81 // Guarantees to return if disarm() and wake() is called.
82 // Provides a trailing fence.
83 void wait(int barrier_tag) { _impl.wait(barrier_tag); }
84 };
85
86 typedef WaitBarrierType<WaitBarrierDefault> WaitBarrier;
87
88 #endif // SHARE_UTILITIES_WAITBARRIER_HPP
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
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;
90 _owner = owner;
91 #endif
92 }
93 ~WaitBarrierType() {}
94
95 // Returns implementation type.
96 const char* description() { return _impl.description(); }
97
98 // Guarantees any thread calling wait() with same tag will be blocked.
99 // Provides a trailing fence.
100 void arm(int barrier_tag) {
101 #ifdef ASSERT
102 assert(_last_arm_tag != barrier_tag, "Re-arming with same tag");
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
|