< prev index next >

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

Print this page




 119 SATBMarkQueueSet::~SATBMarkQueueSet() {
 120   abandon_completed_buffers();
 121 }
 122 
 123 // _count_and_process_flag has flag in least significant bit, count in
 124 // remaining bits.  _process_completed_buffers_threshold is scaled
 125 // accordingly, with the lsbit set, so a _count_and_process_flag value
 126 // is directly comparable with the recorded threshold value.  The
 127 // process flag is set whenever the count exceeds the threshold, and
 128 // remains set until the count is reduced to zero.
 129 
 130 // Increment count.  If count > threshold, set flag, else maintain flag.
 131 static void increment_count(volatile size_t* cfptr, size_t threshold) {
 132   size_t old;
 133   size_t value = Atomic::load(cfptr);
 134   do {
 135     old = value;
 136     value += 2;
 137     assert(value > old, "overflow");
 138     if (value > threshold) value |= 1;
 139     value = Atomic::cmpxchg(value, cfptr, old);
 140   } while (value != old);
 141 }
 142 
 143 // Decrement count.  If count == 0, clear flag, else maintain flag.
 144 static void decrement_count(volatile size_t* cfptr) {
 145   size_t old;
 146   size_t value = Atomic::load(cfptr);
 147   do {
 148     assert((value >> 1) != 0, "underflow");
 149     old = value;
 150     value -= 2;
 151     if (value <= 1) value = 0;
 152     value = Atomic::cmpxchg(value, cfptr, old);
 153   } while (value != old);
 154 }
 155 
 156 void SATBMarkQueueSet::set_process_completed_buffers_threshold(size_t value) {
 157   // Scale requested threshold to align with count field.  If scaling
 158   // overflows, just use max value.  Set process flag field to make
 159   // comparison in increment_count exact.
 160   size_t scaled_value = value << 1;
 161   if ((scaled_value >> 1) != value) {
 162     scaled_value = SIZE_MAX;
 163   }
 164   _process_completed_buffers_threshold = scaled_value | 1;
 165 }
 166 
 167 void SATBMarkQueueSet::set_buffer_enqueue_threshold_percentage(uint value) {
 168   // Minimum threshold of 1 ensures enqueuing of completely full buffers.
 169   size_t size = buffer_size();
 170   size_t enqueue_qty = (size * value) / 100;
 171   _buffer_enqueue_threshold = MAX2(size - enqueue_qty, (size_t)1);
 172 }


 312   class PrintThreadClosure : public ThreadClosure {
 313     SATBMarkQueueSet* _qset;
 314     char* _buffer;
 315 
 316   public:
 317     PrintThreadClosure(SATBMarkQueueSet* qset, char* buffer) :
 318       _qset(qset), _buffer(buffer) {}
 319 
 320     virtual void do_thread(Thread* t) {
 321       os::snprintf(_buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name());
 322       _qset->satb_queue_for_thread(t).print(_buffer);
 323     }
 324   } closure(this, buffer);
 325   Threads::threads_do(&closure);
 326 
 327   tty->cr();
 328 }
 329 #endif // PRODUCT
 330 
 331 void SATBMarkQueueSet::abandon_completed_buffers() {
 332   Atomic::store(size_t(0), &_count_and_process_flag);
 333   BufferNode* buffers_to_delete = _list.pop_all();
 334   while (buffers_to_delete != NULL) {
 335     BufferNode* bn = buffers_to_delete;
 336     buffers_to_delete = bn->next();
 337     bn->set_next(NULL);
 338     deallocate_buffer(bn);
 339   }
 340 }
 341 
 342 void SATBMarkQueueSet::abandon_partial_marking() {
 343   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
 344   abandon_completed_buffers();
 345 
 346   class AbandonThreadQueueClosure : public ThreadClosure {
 347     SATBMarkQueueSet* _qset;
 348   public:
 349     AbandonThreadQueueClosure(SATBMarkQueueSet* qset) : _qset(qset) {}
 350     virtual void do_thread(Thread* t) {
 351       _qset->satb_queue_for_thread(t).reset();
 352     }


 119 SATBMarkQueueSet::~SATBMarkQueueSet() {
 120   abandon_completed_buffers();
 121 }
 122 
 123 // _count_and_process_flag has flag in least significant bit, count in
 124 // remaining bits.  _process_completed_buffers_threshold is scaled
 125 // accordingly, with the lsbit set, so a _count_and_process_flag value
 126 // is directly comparable with the recorded threshold value.  The
 127 // process flag is set whenever the count exceeds the threshold, and
 128 // remains set until the count is reduced to zero.
 129 
 130 // Increment count.  If count > threshold, set flag, else maintain flag.
 131 static void increment_count(volatile size_t* cfptr, size_t threshold) {
 132   size_t old;
 133   size_t value = Atomic::load(cfptr);
 134   do {
 135     old = value;
 136     value += 2;
 137     assert(value > old, "overflow");
 138     if (value > threshold) value |= 1;
 139     value = Atomic::cmpxchg(cfptr, old, value);
 140   } while (value != old);
 141 }
 142 
 143 // Decrement count.  If count == 0, clear flag, else maintain flag.
 144 static void decrement_count(volatile size_t* cfptr) {
 145   size_t old;
 146   size_t value = Atomic::load(cfptr);
 147   do {
 148     assert((value >> 1) != 0, "underflow");
 149     old = value;
 150     value -= 2;
 151     if (value <= 1) value = 0;
 152     value = Atomic::cmpxchg(cfptr, old, value);
 153   } while (value != old);
 154 }
 155 
 156 void SATBMarkQueueSet::set_process_completed_buffers_threshold(size_t value) {
 157   // Scale requested threshold to align with count field.  If scaling
 158   // overflows, just use max value.  Set process flag field to make
 159   // comparison in increment_count exact.
 160   size_t scaled_value = value << 1;
 161   if ((scaled_value >> 1) != value) {
 162     scaled_value = SIZE_MAX;
 163   }
 164   _process_completed_buffers_threshold = scaled_value | 1;
 165 }
 166 
 167 void SATBMarkQueueSet::set_buffer_enqueue_threshold_percentage(uint value) {
 168   // Minimum threshold of 1 ensures enqueuing of completely full buffers.
 169   size_t size = buffer_size();
 170   size_t enqueue_qty = (size * value) / 100;
 171   _buffer_enqueue_threshold = MAX2(size - enqueue_qty, (size_t)1);
 172 }


 312   class PrintThreadClosure : public ThreadClosure {
 313     SATBMarkQueueSet* _qset;
 314     char* _buffer;
 315 
 316   public:
 317     PrintThreadClosure(SATBMarkQueueSet* qset, char* buffer) :
 318       _qset(qset), _buffer(buffer) {}
 319 
 320     virtual void do_thread(Thread* t) {
 321       os::snprintf(_buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name());
 322       _qset->satb_queue_for_thread(t).print(_buffer);
 323     }
 324   } closure(this, buffer);
 325   Threads::threads_do(&closure);
 326 
 327   tty->cr();
 328 }
 329 #endif // PRODUCT
 330 
 331 void SATBMarkQueueSet::abandon_completed_buffers() {
 332   Atomic::store(&_count_and_process_flag, size_t(0));
 333   BufferNode* buffers_to_delete = _list.pop_all();
 334   while (buffers_to_delete != NULL) {
 335     BufferNode* bn = buffers_to_delete;
 336     buffers_to_delete = bn->next();
 337     bn->set_next(NULL);
 338     deallocate_buffer(bn);
 339   }
 340 }
 341 
 342 void SATBMarkQueueSet::abandon_partial_marking() {
 343   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
 344   abandon_completed_buffers();
 345 
 346   class AbandonThreadQueueClosure : public ThreadClosure {
 347     SATBMarkQueueSet* _qset;
 348   public:
 349     AbandonThreadQueueClosure(SATBMarkQueueSet* qset) : _qset(qset) {}
 350     virtual void do_thread(Thread* t) {
 351       _qset->satb_queue_for_thread(t).reset();
 352     }
< prev index next >