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 #include "precompiled.hpp"
26 #include "gc/g1/concurrentG1Refine.hpp"
27 #include "gc/g1/concurrentG1RefineThread.hpp"
28 #include "gc/g1/g1CollectedHeap.inline.hpp"
29 #include "gc/g1/suspendibleThreadSet.hpp"
30 #include "logging/log.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "runtime/handles.inline.hpp"
33 #include "runtime/mutexLocker.hpp"
34
35 ConcurrentG1RefineThread::
36 ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next,
37 CardTableEntryClosure* refine_closure,
38 uint worker_id_offset, uint worker_id,
39 size_t activate, size_t deactivate) :
40 ConcurrentGCThread(),
41 _refine_closure(refine_closure),
42 _worker_id_offset(worker_id_offset),
43 _worker_id(worker_id),
44 _active(false),
45 _next(next),
46 _monitor(NULL),
47 _cg1r(cg1r),
48 _vtime_accum(0.0),
49 _activation_threshold(activate),
50 _deactivation_threshold(deactivate)
51 {
52
53 // Each thread has its own monitor. The i-th thread is responsible for signaling
54 // to thread i+1 if the number of buffers in the queue exceeds a threshold for this
55 // thread. Monitors are also used to wake up the threads during termination.
56 // The 0th (primary) worker is notified by mutator threads and has a special monitor.
57 if (!is_primary()) {
58 _monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true,
59 Monitor::_safepoint_check_never);
60 } else {
61 _monitor = DirtyCardQ_CBL_mon;
128 if (sts_join.should_yield()) {
129 sts_join.yield();
130 continue; // Re-check for termination after yield delay.
131 }
132
133 size_t curr_buffer_num = dcqs.completed_buffers_num();
134 // If the number of the buffers falls down into the yellow zone,
135 // that means that the transition period after the evacuation pause has ended.
136 if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) {
137 dcqs.set_completed_queue_padding(0);
138 }
139
140 // Check if we need to activate the next thread.
141 if ((_next != NULL) &&
142 !_next->is_active() &&
143 (curr_buffer_num > _next->_activation_threshold)) {
144 _next->activate();
145 }
146
147 // Process the next buffer, if there are enough left.
148 if (!dcqs.apply_closure_to_completed_buffer(_refine_closure,
149 _worker_id + _worker_id_offset,
150 _deactivation_threshold,
151 false /* during_pause */)) {
152 break; // Deactivate, number of buffers fell below threshold.
153 }
154 ++buffers_processed;
155 }
156 }
157
158 deactivate();
159 log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT
160 ", current: " SIZE_FORMAT ", processed: " SIZE_FORMAT,
161 _worker_id, _deactivation_threshold,
162 dcqs.completed_buffers_num(),
163 buffers_processed);
164
165 if (os::supports_vtime()) {
166 _vtime_accum = (os::elapsedVTime() - _vtime_start);
167 } else {
168 _vtime_accum = 0.0;
169 }
170 }
171
|
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 #include "precompiled.hpp"
26 #include "gc/g1/concurrentG1Refine.hpp"
27 #include "gc/g1/concurrentG1RefineThread.hpp"
28 #include "gc/g1/g1CollectedHeap.inline.hpp"
29 #include "gc/g1/g1RemSet.hpp"
30 #include "gc/g1/suspendibleThreadSet.hpp"
31 #include "logging/log.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "runtime/handles.inline.hpp"
34 #include "runtime/mutexLocker.hpp"
35
36 ConcurrentG1RefineThread::
37 ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next,
38 uint worker_id_offset, uint worker_id,
39 size_t activate, size_t deactivate) :
40 ConcurrentGCThread(),
41 _worker_id_offset(worker_id_offset),
42 _worker_id(worker_id),
43 _active(false),
44 _next(next),
45 _monitor(NULL),
46 _cg1r(cg1r),
47 _vtime_accum(0.0),
48 _activation_threshold(activate),
49 _deactivation_threshold(deactivate)
50 {
51
52 // Each thread has its own monitor. The i-th thread is responsible for signaling
53 // to thread i+1 if the number of buffers in the queue exceeds a threshold for this
54 // thread. Monitors are also used to wake up the threads during termination.
55 // The 0th (primary) worker is notified by mutator threads and has a special monitor.
56 if (!is_primary()) {
57 _monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true,
58 Monitor::_safepoint_check_never);
59 } else {
60 _monitor = DirtyCardQ_CBL_mon;
127 if (sts_join.should_yield()) {
128 sts_join.yield();
129 continue; // Re-check for termination after yield delay.
130 }
131
132 size_t curr_buffer_num = dcqs.completed_buffers_num();
133 // If the number of the buffers falls down into the yellow zone,
134 // that means that the transition period after the evacuation pause has ended.
135 if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) {
136 dcqs.set_completed_queue_padding(0);
137 }
138
139 // Check if we need to activate the next thread.
140 if ((_next != NULL) &&
141 !_next->is_active() &&
142 (curr_buffer_num > _next->_activation_threshold)) {
143 _next->activate();
144 }
145
146 // Process the next buffer, if there are enough left.
147 if (!dcqs.refine_completed_buffer_concurrently(_worker_id + _worker_id_offset, _deactivation_threshold)) {
148 break; // Deactivate, number of buffers fell below threshold.
149 }
150 ++buffers_processed;
151 }
152 }
153
154 deactivate();
155 log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT
156 ", current: " SIZE_FORMAT ", processed: " SIZE_FORMAT,
157 _worker_id, _deactivation_threshold,
158 dcqs.completed_buffers_num(),
159 buffers_processed);
160
161 if (os::supports_vtime()) {
162 _vtime_accum = (os::elapsedVTime() - _vtime_start);
163 } else {
164 _vtime_accum = 0.0;
165 }
166 }
167
|