Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8135575 | emb-9 | Bengt Rutisson | P2 | Resolved | Fixed | team |
JDK-8262493 | openjdk8u292 | Fei Yang | P2 | Resolved | Fixed | b05 |
ConcurrentMarkThread::during_cycle() is implemented as:
bool during_cycle() { return started() || in_progress(); }
So, it checks both ConcurrentMarkThread::_started and ConcurrentMarkThread::_in_progress and they are meant to overlap. That is, we should not set _started to false until after we have set _in_progress to true. This is done in sleepBeforeNextCycle():
void ConcurrentMarkThread::sleepBeforeNextCycle() {
// We join here because we don't want to do the "shouldConcurrentMark()"
// below while the world is otherwise stopped.
assert(!in_progress(), "should have been cleared");
MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
while (!started() && !_should_terminate) {
CGC_lock->wait(Mutex::_no_safepoint_check_flag);
}
if (started()) {
set_in_progress();
clear_started();
}
}
On non-TSO platforms there is a risk that the write to _in_progress (from set_in_progress()) is seen by other threads after the write to _started (in clear_started()). In that case there is a window when during_cycle() may return false even though we are in a concurrent cycle.
bool during_cycle() { return started() || in_progress(); }
So, it checks both ConcurrentMarkThread::_started and ConcurrentMarkThread::_in_progress and they are meant to overlap. That is, we should not set _started to false until after we have set _in_progress to true. This is done in sleepBeforeNextCycle():
void ConcurrentMarkThread::sleepBeforeNextCycle() {
// We join here because we don't want to do the "shouldConcurrentMark()"
// below while the world is otherwise stopped.
assert(!in_progress(), "should have been cleared");
MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
while (!started() && !_should_terminate) {
CGC_lock->wait(Mutex::_no_safepoint_check_flag);
}
if (started()) {
set_in_progress();
clear_started();
}
}
On non-TSO platforms there is a risk that the write to _in_progress (from set_in_progress()) is seen by other threads after the write to _started (in clear_started()). In that case there is a window when during_cycle() may return false even though we are in a concurrent cycle.
- backported by
-
JDK-8135575 G1: set_in_progress() and clear_started() needs a barrier on non-TSO platforms
- Resolved
-
JDK-8262493 G1: set_in_progress() and clear_started() needs a barrier on non-TSO platforms
- Resolved