< prev index next >

src/hotspot/share/gc/shared/ptrQueue.cpp

Print this page
rev 55389 : [mq]: satb_lock_free


 233   }
 234   OrderAccess::release_store(&_transfer_lock, false);
 235   return true;
 236 }
 237 
 238 size_t BufferNode::Allocator::reduce_free_list(size_t remove_goal) {
 239   try_transfer_pending();
 240   size_t removed = 0;
 241   for ( ; removed < remove_goal; ++removed) {
 242     BufferNode* node = _free_list.pop();
 243     if (node == NULL) break;
 244     BufferNode::deallocate(node);
 245   }
 246   size_t new_count = Atomic::sub(removed, &_free_count);
 247   log_debug(gc, ptrqueue, freelist)
 248            ("Reduced %s free list by " SIZE_FORMAT " to " SIZE_FORMAT,
 249             name(), removed, new_count);
 250   return removed;
 251 }
 252 
 253 PtrQueueSet::PtrQueueSet(bool notify_when_complete) :
 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)
 263 {}
 264 
 265 PtrQueueSet::~PtrQueueSet() {
 266   // There are presently only a couple (derived) instances ever
 267   // created, and they are permanent, so no harm currently done by
 268   // doing nothing here.
 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;
 276 }
 277 
 278 void** PtrQueueSet::allocate_buffer() {
 279   BufferNode* node = _allocator->allocate();
 280   return BufferNode::make_buffer_from_node(node);
 281 }
 282 
 283 void PtrQueueSet::deallocate_buffer(BufferNode* node) {
 284   _allocator->release(node);
 285 }
 286 
 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 }


 233   }
 234   OrderAccess::release_store(&_transfer_lock, false);
 235   return true;
 236 }
 237 
 238 size_t BufferNode::Allocator::reduce_free_list(size_t remove_goal) {
 239   try_transfer_pending();
 240   size_t removed = 0;
 241   for ( ; removed < remove_goal; ++removed) {
 242     BufferNode* node = _free_list.pop();
 243     if (node == NULL) break;
 244     BufferNode::deallocate(node);
 245   }
 246   size_t new_count = Atomic::sub(removed, &_free_count);
 247   log_debug(gc, ptrqueue, freelist)
 248            ("Reduced %s free list by " SIZE_FORMAT " to " SIZE_FORMAT,
 249             name(), removed, new_count);
 250   return removed;
 251 }
 252 
 253 PtrQueueSet::PtrQueueSet() :
 254   _allocator(NULL),







 255   _all_active(false)
 256 {}
 257 
 258 PtrQueueSet::~PtrQueueSet() {}




 259 
 260 void PtrQueueSet::initialize(BufferNode::Allocator* allocator) {
 261   assert(allocator != NULL, "Init order issue?");


 262   _allocator = allocator;
 263 }
 264 
 265 void** PtrQueueSet::allocate_buffer() {
 266   BufferNode* node = _allocator->allocate();
 267   return BufferNode::make_buffer_from_node(node);
 268 }
 269 
 270 void PtrQueueSet::deallocate_buffer(BufferNode* node) {
 271   _allocator->release(node);
 272 }
 273 






















































































































< prev index next >