153 } |
153 } |
154 return b; |
154 return b; |
155 } |
155 } |
156 |
156 |
157 DirtyCardQueueSet::CompletedBufferNode* |
157 DirtyCardQueueSet::CompletedBufferNode* |
158 DirtyCardQueueSet::get_completed_buffer_lock(int stop_at) { |
158 DirtyCardQueueSet::get_completed_buffer(int stop_at) { |
159 CompletedBufferNode* nd = NULL; |
159 CompletedBufferNode* nd = NULL; |
160 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); |
160 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); |
161 |
161 |
162 if ((int)_n_completed_buffers <= stop_at) { |
162 if ((int)_n_completed_buffers <= stop_at) { |
163 _process_completed = false; |
163 _process_completed = false; |
171 _completed_buffers_tail = NULL; |
171 _completed_buffers_tail = NULL; |
172 _n_completed_buffers--; |
172 _n_completed_buffers--; |
173 } |
173 } |
174 debug_only(assert_completed_buffer_list_len_correct_locked()); |
174 debug_only(assert_completed_buffer_list_len_correct_locked()); |
175 return nd; |
175 return nd; |
176 } |
|
177 |
|
178 // We only do this in contexts where there is no concurrent enqueueing. |
|
179 DirtyCardQueueSet::CompletedBufferNode* |
|
180 DirtyCardQueueSet::get_completed_buffer_CAS() { |
|
181 CompletedBufferNode* nd = _completed_buffers_head; |
|
182 |
|
183 while (nd != NULL) { |
|
184 CompletedBufferNode* next = nd->next; |
|
185 CompletedBufferNode* result = |
|
186 (CompletedBufferNode*)Atomic::cmpxchg_ptr(next, |
|
187 &_completed_buffers_head, |
|
188 nd); |
|
189 if (result == nd) { |
|
190 return result; |
|
191 } else { |
|
192 nd = _completed_buffers_head; |
|
193 } |
|
194 } |
|
195 assert(_completed_buffers_head == NULL, "Loop post"); |
|
196 _completed_buffers_tail = NULL; |
|
197 return NULL; |
|
198 } |
176 } |
199 |
177 |
200 bool DirtyCardQueueSet:: |
178 bool DirtyCardQueueSet:: |
201 apply_closure_to_completed_buffer_helper(int worker_i, |
179 apply_closure_to_completed_buffer_helper(int worker_i, |
202 CompletedBufferNode* nd) { |
180 CompletedBufferNode* nd) { |
220 } |
198 } |
221 } |
199 } |
222 |
200 |
223 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i, |
201 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i, |
224 int stop_at, |
202 int stop_at, |
225 bool with_CAS) |
203 bool during_pause) |
226 { |
204 { |
227 CompletedBufferNode* nd = NULL; |
205 assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause"); |
228 if (with_CAS) { |
206 CompletedBufferNode* nd = get_completed_buffer(stop_at); |
229 guarantee(stop_at == 0, "Precondition"); |
|
230 nd = get_completed_buffer_CAS(); |
|
231 } else { |
|
232 nd = get_completed_buffer_lock(stop_at); |
|
233 } |
|
234 bool res = apply_closure_to_completed_buffer_helper(worker_i, nd); |
207 bool res = apply_closure_to_completed_buffer_helper(worker_i, nd); |
235 if (res) Atomic::inc(&_processed_buffers_rs_thread); |
208 if (res) Atomic::inc(&_processed_buffers_rs_thread); |
236 return res; |
209 return res; |
237 } |
210 } |
238 |
211 |