248 ("Reduced %s free list by " SIZE_FORMAT " to " SIZE_FORMAT, |
248 ("Reduced %s free list by " SIZE_FORMAT " to " SIZE_FORMAT, |
249 name(), removed, new_count); |
249 name(), removed, new_count); |
250 return removed; |
250 return removed; |
251 } |
251 } |
252 |
252 |
253 PtrQueueSet::PtrQueueSet(bool notify_when_complete) : |
253 PtrQueueSet::PtrQueueSet() : |
254 _allocator(NULL), |
254 _allocator(NULL), |
255 _cbl_mon(NULL), |
|
256 _completed_buffers_head(NULL), |
|
257 _completed_buffers_tail(NULL), |
|
258 _n_completed_buffers(0), |
|
259 _process_completed_buffers_threshold(ProcessCompletedBuffersThresholdNever), |
|
260 _process_completed_buffers(false), |
|
261 _notify_when_complete(notify_when_complete), |
|
262 _all_active(false) |
255 _all_active(false) |
263 {} |
256 {} |
264 |
257 |
265 PtrQueueSet::~PtrQueueSet() { |
258 PtrQueueSet::~PtrQueueSet() {} |
266 // There are presently only a couple (derived) instances ever |
259 |
267 // created, and they are permanent, so no harm currently done by |
260 void PtrQueueSet::initialize(BufferNode::Allocator* allocator) { |
268 // doing nothing here. |
261 assert(allocator != NULL, "Init order issue?"); |
269 } |
|
270 |
|
271 void PtrQueueSet::initialize(Monitor* cbl_mon, |
|
272 BufferNode::Allocator* allocator) { |
|
273 assert(cbl_mon != NULL && allocator != NULL, "Init order issue?"); |
|
274 _cbl_mon = cbl_mon; |
|
275 _allocator = allocator; |
262 _allocator = allocator; |
276 } |
263 } |
277 |
264 |
278 void** PtrQueueSet::allocate_buffer() { |
265 void** PtrQueueSet::allocate_buffer() { |
279 BufferNode* node = _allocator->allocate(); |
266 BufferNode* node = _allocator->allocate(); |
282 |
269 |
283 void PtrQueueSet::deallocate_buffer(BufferNode* node) { |
270 void PtrQueueSet::deallocate_buffer(BufferNode* node) { |
284 _allocator->release(node); |
271 _allocator->release(node); |
285 } |
272 } |
286 |
273 |
287 void PtrQueueSet::enqueue_completed_buffer(BufferNode* cbn) { |
|
288 MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag); |
|
289 cbn->set_next(NULL); |
|
290 if (_completed_buffers_tail == NULL) { |
|
291 assert(_completed_buffers_head == NULL, "Well-formedness"); |
|
292 _completed_buffers_head = cbn; |
|
293 _completed_buffers_tail = cbn; |
|
294 } else { |
|
295 _completed_buffers_tail->set_next(cbn); |
|
296 _completed_buffers_tail = cbn; |
|
297 } |
|
298 _n_completed_buffers++; |
|
299 |
|
300 if (!_process_completed_buffers && |
|
301 (_n_completed_buffers > _process_completed_buffers_threshold)) { |
|
302 _process_completed_buffers = true; |
|
303 if (_notify_when_complete) { |
|
304 _cbl_mon->notify(); |
|
305 } |
|
306 } |
|
307 assert_completed_buffers_list_len_correct_locked(); |
|
308 } |
|
309 |
|
310 BufferNode* PtrQueueSet::get_completed_buffer(size_t stop_at) { |
|
311 MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag); |
|
312 |
|
313 if (_n_completed_buffers <= stop_at) { |
|
314 return NULL; |
|
315 } |
|
316 |
|
317 assert(_n_completed_buffers > 0, "invariant"); |
|
318 assert(_completed_buffers_head != NULL, "invariant"); |
|
319 assert(_completed_buffers_tail != NULL, "invariant"); |
|
320 |
|
321 BufferNode* bn = _completed_buffers_head; |
|
322 _n_completed_buffers--; |
|
323 _completed_buffers_head = bn->next(); |
|
324 if (_completed_buffers_head == NULL) { |
|
325 assert(_n_completed_buffers == 0, "invariant"); |
|
326 _completed_buffers_tail = NULL; |
|
327 _process_completed_buffers = false; |
|
328 } |
|
329 assert_completed_buffers_list_len_correct_locked(); |
|
330 bn->set_next(NULL); |
|
331 return bn; |
|
332 } |
|
333 |
|
334 void PtrQueueSet::abandon_completed_buffers() { |
|
335 BufferNode* buffers_to_delete = NULL; |
|
336 { |
|
337 MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag); |
|
338 buffers_to_delete = _completed_buffers_head; |
|
339 _completed_buffers_head = NULL; |
|
340 _completed_buffers_tail = NULL; |
|
341 _n_completed_buffers = 0; |
|
342 _process_completed_buffers = false; |
|
343 } |
|
344 while (buffers_to_delete != NULL) { |
|
345 BufferNode* bn = buffers_to_delete; |
|
346 buffers_to_delete = bn->next(); |
|
347 bn->set_next(NULL); |
|
348 deallocate_buffer(bn); |
|
349 } |
|
350 } |
|
351 |
|
352 #ifdef ASSERT |
|
353 |
|
354 void PtrQueueSet::assert_completed_buffers_list_len_correct_locked() { |
|
355 assert_lock_strong(_cbl_mon); |
|
356 size_t n = 0; |
|
357 for (BufferNode* bn = _completed_buffers_head; bn != NULL; bn = bn->next()) { |
|
358 ++n; |
|
359 } |
|
360 assert(n == _n_completed_buffers, |
|
361 "Completed buffer length is wrong: counted: " SIZE_FORMAT |
|
362 ", expected: " SIZE_FORMAT, n, _n_completed_buffers); |
|
363 } |
|
364 |
|
365 #endif // ASSERT |
|
366 |
|
367 // Merge lists of buffers. Notify the processing threads. |
|
368 // The source queue is emptied as a result. The queues |
|
369 // must share the monitor. |
|
370 void PtrQueueSet::merge_bufferlists(PtrQueueSet *src) { |
|
371 assert(_cbl_mon == src->_cbl_mon, "Should share the same lock"); |
|
372 MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag); |
|
373 if (_completed_buffers_tail == NULL) { |
|
374 assert(_completed_buffers_head == NULL, "Well-formedness"); |
|
375 _completed_buffers_head = src->_completed_buffers_head; |
|
376 _completed_buffers_tail = src->_completed_buffers_tail; |
|
377 } else { |
|
378 assert(_completed_buffers_head != NULL, "Well formedness"); |
|
379 if (src->_completed_buffers_head != NULL) { |
|
380 _completed_buffers_tail->set_next(src->_completed_buffers_head); |
|
381 _completed_buffers_tail = src->_completed_buffers_tail; |
|
382 } |
|
383 } |
|
384 _n_completed_buffers += src->_n_completed_buffers; |
|
385 |
|
386 src->_n_completed_buffers = 0; |
|
387 src->_completed_buffers_head = NULL; |
|
388 src->_completed_buffers_tail = NULL; |
|
389 src->_process_completed_buffers = false; |
|
390 |
|
391 assert(_completed_buffers_head == NULL && _completed_buffers_tail == NULL || |
|
392 _completed_buffers_head != NULL && _completed_buffers_tail != NULL, |
|
393 "Sanity"); |
|
394 assert_completed_buffers_list_len_correct_locked(); |
|
395 } |
|
396 |
|
397 void PtrQueueSet::notify_if_necessary() { |
|
398 MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag); |
|
399 if (_n_completed_buffers > _process_completed_buffers_threshold) { |
|
400 _process_completed_buffers = true; |
|
401 if (_notify_when_complete) |
|
402 _cbl_mon->notify(); |
|
403 } |
|
404 } |
|