< prev index next >

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

Print this page
rev 56193 : [mq]: pqsinit


  91 }
  92 
  93 #ifndef PRODUCT
  94 // Helpful for debugging
  95 
  96 static void print_satb_buffer(const char* name,
  97                               void** buf,
  98                               size_t index,
  99                               size_t capacity) {
 100   tty->print_cr("  SATB BUFFER [%s] buf: " PTR_FORMAT " index: " SIZE_FORMAT
 101                 " capacity: " SIZE_FORMAT,
 102                 name, p2i(buf), index, capacity);
 103 }
 104 
 105 void SATBMarkQueue::print(const char* name) {
 106   print_satb_buffer(name, _buf, index(), capacity());
 107 }
 108 
 109 #endif // PRODUCT
 110 
 111 SATBMarkQueueSet::SATBMarkQueueSet() :
 112   PtrQueueSet(),
 113   _list(),
 114   _count_and_process_flag(0),
 115   _process_completed_buffers_threshold(SIZE_MAX),
 116   _buffer_enqueue_threshold(0)
 117 {}
 118 
 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;


 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 // Scale requested threshold to align with count field.  If scaling
 157 // overflows, just use max value.  Set process flag field to make
 158 // comparison in increment_count exact.
 159 static size_t scale_threshold(size_t value) {
 160   size_t scaled_value = value << 1;
 161   if ((scaled_value >> 1) != value) {
 162     scaled_value = SIZE_MAX;
 163   }
 164   return scaled_value | 1;
 165 }
 166 
 167 void SATBMarkQueueSet::initialize(BufferNode::Allocator* allocator,
 168                                   size_t process_completed_buffers_threshold,
 169                                   uint buffer_enqueue_threshold_percentage) {
 170   PtrQueueSet::initialize(allocator);
 171   _process_completed_buffers_threshold =
 172     scale_threshold(process_completed_buffers_threshold);
 173   assert(buffer_size() != 0, "buffer size not initialized");
 174   // Minimum threshold of 1 ensures enqueuing of completely full buffers.
 175   size_t size = buffer_size();
 176   size_t enqueue_qty = (size * buffer_enqueue_threshold_percentage) / 100;
 177   _buffer_enqueue_threshold = MAX2(size - enqueue_qty, (size_t)1);
 178 }
 179 
 180 #ifdef ASSERT
 181 void SATBMarkQueueSet::dump_active_states(bool expected_active) {
 182   log_error(gc, verify)("Expected SATB active state: %s", expected_active ? "ACTIVE" : "INACTIVE");
 183   log_error(gc, verify)("Actual SATB active states:");
 184   log_error(gc, verify)("  Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
 185 
 186   class DumpThreadStateClosure : public ThreadClosure {
 187     SATBMarkQueueSet* _qset;
 188   public:
 189     DumpThreadStateClosure(SATBMarkQueueSet* qset) : _qset(qset) {}
 190     virtual void do_thread(Thread* t) {
 191       SATBMarkQueue& queue = _qset->satb_queue_for_thread(t);
 192       log_error(gc, verify)("  Thread \"%s\" queue: %s",
 193                             t->name(),
 194                             queue.is_active() ? "ACTIVE" : "INACTIVE");
 195     }
 196   } closure(this);




  91 }
  92 
  93 #ifndef PRODUCT
  94 // Helpful for debugging
  95 
  96 static void print_satb_buffer(const char* name,
  97                               void** buf,
  98                               size_t index,
  99                               size_t capacity) {
 100   tty->print_cr("  SATB BUFFER [%s] buf: " PTR_FORMAT " index: " SIZE_FORMAT
 101                 " capacity: " SIZE_FORMAT,
 102                 name, p2i(buf), index, capacity);
 103 }
 104 
 105 void SATBMarkQueue::print(const char* name) {
 106   print_satb_buffer(name, _buf, index(), capacity());
 107 }
 108 
 109 #endif // PRODUCT
 110 
 111 SATBMarkQueueSet::SATBMarkQueueSet(BufferNode::Allocator* allocator) :
 112   PtrQueueSet(allocator),
 113   _list(),
 114   _count_and_process_flag(0),
 115   _process_completed_buffers_threshold(SIZE_MAX),
 116   _buffer_enqueue_threshold(0)
 117 {}
 118 
 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;


 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 }
 173 
 174 #ifdef ASSERT
 175 void SATBMarkQueueSet::dump_active_states(bool expected_active) {
 176   log_error(gc, verify)("Expected SATB active state: %s", expected_active ? "ACTIVE" : "INACTIVE");
 177   log_error(gc, verify)("Actual SATB active states:");
 178   log_error(gc, verify)("  Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
 179 
 180   class DumpThreadStateClosure : public ThreadClosure {
 181     SATBMarkQueueSet* _qset;
 182   public:
 183     DumpThreadStateClosure(SATBMarkQueueSet* qset) : _qset(qset) {}
 184     virtual void do_thread(Thread* t) {
 185       SATBMarkQueue& queue = _qset->satb_queue_for_thread(t);
 186       log_error(gc, verify)("  Thread \"%s\" queue: %s",
 187                             t->name(),
 188                             queue.is_active() ? "ACTIVE" : "INACTIVE");
 189     }
 190   } closure(this);


< prev index next >