47 _wrt_start->signal(); |
47 _wrt_start->signal(); |
48 int vv, tag; |
48 int vv, tag; |
49 // Similar to how a JavaThread would stop in a safepoint. |
49 // Similar to how a JavaThread would stop in a safepoint. |
50 while (!_exit) { |
50 while (!_exit) { |
51 // Load the published tag. |
51 // Load the published tag. |
52 tag = OrderAccess::load_acquire(&wait_tag); |
52 tag = Atomic::load_acquire(&wait_tag); |
53 // Publish the tag this thread is going to wait for. |
53 // Publish the tag this thread is going to wait for. |
54 OrderAccess::release_store(&_on_barrier, tag); |
54 Atomic::release_store(&_on_barrier, tag); |
55 if (_on_barrier == 0) { |
55 if (_on_barrier == 0) { |
56 SpinPause(); |
56 SpinPause(); |
57 continue; |
57 continue; |
58 } |
58 } |
59 OrderAccess::storeload(); // Loads in WB must not float up. |
59 OrderAccess::storeload(); // Loads in WB must not float up. |
60 // Wait until we are woken. |
60 // Wait until we are woken. |
61 _wait_barrier->wait(tag); |
61 _wait_barrier->wait(tag); |
62 // Verify that we do not see an invalid value. |
62 // Verify that we do not see an invalid value. |
63 vv = OrderAccess::load_acquire(&valid_value); |
63 vv = Atomic::load_acquire(&valid_value); |
64 ASSERT_EQ((vv & 0x1), 0); |
64 ASSERT_EQ((vv & 0x1), 0); |
65 OrderAccess::release_store(&_on_barrier, 0); |
65 Atomic::release_store(&_on_barrier, 0); |
66 } |
66 } |
67 } |
67 } |
68 }; |
68 }; |
69 |
69 |
70 template <typename WaitBarrierImpl> |
70 template <typename WaitBarrierImpl> |
102 // Similar to how the VM thread would use a WaitBarrier in a safepoint. |
102 // Similar to how the VM thread would use a WaitBarrier in a safepoint. |
103 while (stop_ms > os::javaTimeMillis()) { |
103 while (stop_ms > os::javaTimeMillis()) { |
104 // Arm next tag. |
104 // Arm next tag. |
105 wb.arm(next_tag); |
105 wb.arm(next_tag); |
106 // Publish tag. |
106 // Publish tag. |
107 OrderAccess::release_store_fence(&wait_tag, next_tag); |
107 Atomic::release_store_fence(&wait_tag, next_tag); |
108 |
108 |
109 // Wait until threads picked up new tag. |
109 // Wait until threads picked up new tag. |
110 while (reader1->_on_barrier != wait_tag || |
110 while (reader1->_on_barrier != wait_tag || |
111 reader2->_on_barrier != wait_tag || |
111 reader2->_on_barrier != wait_tag || |
112 reader3->_on_barrier != wait_tag || |
112 reader3->_on_barrier != wait_tag || |
113 reader4->_on_barrier != wait_tag) { |
113 reader4->_on_barrier != wait_tag) { |
114 SpinPause(); |
114 SpinPause(); |
115 } |
115 } |
116 |
116 |
117 // Set an invalid value. |
117 // Set an invalid value. |
118 OrderAccess::release_store(&valid_value, valid_value + 1); // odd |
118 Atomic::release_store(&valid_value, valid_value + 1); // odd |
119 os::naked_yield(); |
119 os::naked_yield(); |
120 // Set a valid value. |
120 // Set a valid value. |
121 OrderAccess::release_store(&valid_value, valid_value + 1); // even |
121 Atomic::release_store(&valid_value, valid_value + 1); // even |
122 // Publish inactive tag. |
122 // Publish inactive tag. |
123 OrderAccess::release_store_fence(&wait_tag, 0); // Stores in WB must not float up. |
123 Atomic::release_store_fence(&wait_tag, 0); // Stores in WB must not float up. |
124 wb.disarm(); |
124 wb.disarm(); |
125 |
125 |
126 // Wait until threads done valid_value verification. |
126 // Wait until threads done valid_value verification. |
127 while (reader1->_on_barrier != 0 || |
127 while (reader1->_on_barrier != 0 || |
128 reader2->_on_barrier != 0 || |
128 reader2->_on_barrier != 0 || |