提交 6269ed5f 编写于 作者: J johnc

6899058: G1: Internal error in ptrQueue.cpp:201 in nightly tests

Summary: 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
上级 f7d6a4e8
...@@ -155,7 +155,7 @@ bool DirtyCardQueueSet::mut_process_buffer(void** buf) { ...@@ -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) { ...@@ -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, ...@@ -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;
......
/* /*
* 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: ...@@ -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();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册