mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 12:34:32 +02:00
6899058: G1: Internal error in ptrQueue.cpp:201 in nightly tests
Fixes a race on the dirty card queue completed buffer list between worker thread(s) performing a flush of a deferred store barrier (enqueueing a newly completed buffer) and worker thread(s) in the RSet updating code claiming completed buffers. Removed the routine that removes elements from the completed update buffer queue using a CAS. Reviewed-by: ysr, tonyp
This commit is contained in:
parent
9cf0c891d9
commit
5a239d996b
2 changed files with 9 additions and 35 deletions
|
@ -155,7 +155,7 @@ bool DirtyCardQueueSet::mut_process_buffer(void** buf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DirtyCardQueueSet::CompletedBufferNode*
|
DirtyCardQueueSet::CompletedBufferNode*
|
||||||
DirtyCardQueueSet::get_completed_buffer_lock(int stop_at) {
|
DirtyCardQueueSet::get_completed_buffer(int stop_at) {
|
||||||
CompletedBufferNode* nd = NULL;
|
CompletedBufferNode* nd = NULL;
|
||||||
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
||||||
|
|
||||||
|
@ -175,28 +175,6 @@ DirtyCardQueueSet::get_completed_buffer_lock(int stop_at) {
|
||||||
return nd;
|
return nd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only do this in contexts where there is no concurrent enqueueing.
|
|
||||||
DirtyCardQueueSet::CompletedBufferNode*
|
|
||||||
DirtyCardQueueSet::get_completed_buffer_CAS() {
|
|
||||||
CompletedBufferNode* nd = _completed_buffers_head;
|
|
||||||
|
|
||||||
while (nd != NULL) {
|
|
||||||
CompletedBufferNode* next = nd->next;
|
|
||||||
CompletedBufferNode* result =
|
|
||||||
(CompletedBufferNode*)Atomic::cmpxchg_ptr(next,
|
|
||||||
&_completed_buffers_head,
|
|
||||||
nd);
|
|
||||||
if (result == nd) {
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
nd = _completed_buffers_head;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(_completed_buffers_head == NULL, "Loop post");
|
|
||||||
_completed_buffers_tail = NULL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DirtyCardQueueSet::
|
bool DirtyCardQueueSet::
|
||||||
apply_closure_to_completed_buffer_helper(int worker_i,
|
apply_closure_to_completed_buffer_helper(int worker_i,
|
||||||
CompletedBufferNode* nd) {
|
CompletedBufferNode* nd) {
|
||||||
|
@ -222,15 +200,10 @@ apply_closure_to_completed_buffer_helper(int worker_i,
|
||||||
|
|
||||||
bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i,
|
bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i,
|
||||||
int stop_at,
|
int stop_at,
|
||||||
bool with_CAS)
|
bool during_pause)
|
||||||
{
|
{
|
||||||
CompletedBufferNode* nd = NULL;
|
assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause");
|
||||||
if (with_CAS) {
|
CompletedBufferNode* nd = get_completed_buffer(stop_at);
|
||||||
guarantee(stop_at == 0, "Precondition");
|
|
||||||
nd = get_completed_buffer_CAS();
|
|
||||||
} else {
|
|
||||||
nd = get_completed_buffer_lock(stop_at);
|
|
||||||
}
|
|
||||||
bool res = apply_closure_to_completed_buffer_helper(worker_i, nd);
|
bool res = apply_closure_to_completed_buffer_helper(worker_i, nd);
|
||||||
if (res) Atomic::inc(&_processed_buffers_rs_thread);
|
if (res) Atomic::inc(&_processed_buffers_rs_thread);
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -120,12 +120,13 @@ public:
|
||||||
// is returned to the completed buffer set, and this call returns false.
|
// is returned to the completed buffer set, and this call returns false.
|
||||||
bool apply_closure_to_completed_buffer(int worker_i = 0,
|
bool apply_closure_to_completed_buffer(int worker_i = 0,
|
||||||
int stop_at = 0,
|
int stop_at = 0,
|
||||||
bool with_CAS = false);
|
bool during_pause = false);
|
||||||
|
|
||||||
bool apply_closure_to_completed_buffer_helper(int worker_i,
|
bool apply_closure_to_completed_buffer_helper(int worker_i,
|
||||||
CompletedBufferNode* nd);
|
CompletedBufferNode* nd);
|
||||||
|
|
||||||
CompletedBufferNode* get_completed_buffer_CAS();
|
CompletedBufferNode* get_completed_buffer(int stop_at);
|
||||||
CompletedBufferNode* get_completed_buffer_lock(int stop_at);
|
|
||||||
// Applies the current closure to all completed buffers,
|
// Applies the current closure to all completed buffers,
|
||||||
// non-consumptively.
|
// non-consumptively.
|
||||||
void apply_closure_to_all_completed_buffers();
|
void apply_closure_to_all_completed_buffers();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue