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 } | 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 } |