src/hotspot/share/gc/shared/ptrQueue.cpp
changeset 55498 e64383344f14
parent 54970 76d3d96a8bc2
child 58059 baa4dd528de0
equal deleted inserted replaced
55497:d3a33953b936 55498:e64383344f14
   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 }