89 _completed_buffers_head(NULL), |
89 _completed_buffers_head(NULL), |
90 _completed_buffers_tail(NULL), |
90 _completed_buffers_tail(NULL), |
91 _n_completed_buffers(0), |
91 _n_completed_buffers(0), |
92 _process_completed_threshold(0), _process_completed(false), |
92 _process_completed_threshold(0), _process_completed(false), |
93 _buf_free_list(NULL), _buf_free_list_sz(0) |
93 _buf_free_list(NULL), _buf_free_list_sz(0) |
94 {} |
94 { |
|
95 _fl_owner = this; |
|
96 } |
95 |
97 |
96 void** PtrQueueSet::allocate_buffer() { |
98 void** PtrQueueSet::allocate_buffer() { |
97 assert(_sz > 0, "Didn't set a buffer size."); |
99 assert(_sz > 0, "Didn't set a buffer size."); |
98 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag); |
100 MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag); |
99 if (_buf_free_list != NULL) { |
101 if (_fl_owner->_buf_free_list != NULL) { |
100 void** res = _buf_free_list; |
102 void** res = _fl_owner->_buf_free_list; |
101 _buf_free_list = (void**)_buf_free_list[0]; |
103 _fl_owner->_buf_free_list = (void**)_fl_owner->_buf_free_list[0]; |
102 _buf_free_list_sz--; |
104 _fl_owner->_buf_free_list_sz--; |
103 // Just override the next pointer with NULL, just in case we scan this part |
105 // Just override the next pointer with NULL, just in case we scan this part |
104 // of the buffer. |
106 // of the buffer. |
105 res[0] = NULL; |
107 res[0] = NULL; |
106 return res; |
108 return res; |
107 } else { |
109 } else { |
109 } |
111 } |
110 } |
112 } |
111 |
113 |
112 void PtrQueueSet::deallocate_buffer(void** buf) { |
114 void PtrQueueSet::deallocate_buffer(void** buf) { |
113 assert(_sz > 0, "Didn't set a buffer size."); |
115 assert(_sz > 0, "Didn't set a buffer size."); |
114 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag); |
116 MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag); |
115 buf[0] = (void*)_buf_free_list; |
117 buf[0] = (void*)_fl_owner->_buf_free_list; |
116 _buf_free_list = buf; |
118 _fl_owner->_buf_free_list = buf; |
117 _buf_free_list_sz++; |
119 _fl_owner->_buf_free_list_sz++; |
118 } |
120 } |
119 |
121 |
120 void PtrQueueSet::reduce_free_list() { |
122 void PtrQueueSet::reduce_free_list() { |
121 // For now we'll adopt the strategy of deleting half. |
123 // For now we'll adopt the strategy of deleting half. |
122 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag); |
124 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag); |
205 } |
207 } |
206 |
208 |
207 void PtrQueueSet::set_process_completed_threshold(size_t sz) { |
209 void PtrQueueSet::set_process_completed_threshold(size_t sz) { |
208 _process_completed_threshold = sz; |
210 _process_completed_threshold = sz; |
209 } |
211 } |
|
212 |
|
213 // Merge lists of buffers. Notify waiting threads if the length of the list |
|
214 // exceeds threshold. The source queue is emptied as a result. The queues |
|
215 // must share the monitor. |
|
216 void PtrQueueSet::merge_bufferlists(PtrQueueSet *src) { |
|
217 assert(_cbl_mon == src->_cbl_mon, "Should share the same lock"); |
|
218 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); |
|
219 if (_completed_buffers_tail == NULL) { |
|
220 assert(_completed_buffers_head == NULL, "Well-formedness"); |
|
221 _completed_buffers_head = src->_completed_buffers_head; |
|
222 _completed_buffers_tail = src->_completed_buffers_tail; |
|
223 } else { |
|
224 assert(_completed_buffers_head != NULL, "Well formedness"); |
|
225 if (src->_completed_buffers_head != NULL) { |
|
226 _completed_buffers_tail->next = src->_completed_buffers_head; |
|
227 _completed_buffers_tail = src->_completed_buffers_tail; |
|
228 } |
|
229 } |
|
230 _n_completed_buffers += src->_n_completed_buffers; |
|
231 |
|
232 src->_n_completed_buffers = 0; |
|
233 src->_completed_buffers_head = NULL; |
|
234 src->_completed_buffers_tail = NULL; |
|
235 |
|
236 assert(_completed_buffers_head == NULL && _completed_buffers_tail == NULL || |
|
237 _completed_buffers_head != NULL && _completed_buffers_tail != NULL, |
|
238 "Sanity"); |
|
239 |
|
240 if (!_process_completed && |
|
241 _n_completed_buffers >= _process_completed_threshold) { |
|
242 _process_completed = true; |
|
243 if (_notify_when_complete) |
|
244 _cbl_mon->notify_all(); |
|
245 } |
|
246 } |
|
247 |
|
248 // Merge free lists of the two queues. The free list of the source |
|
249 // queue is emptied as a result. The queues must share the same |
|
250 // mutex that guards free lists. |
|
251 void PtrQueueSet::merge_freelists(PtrQueueSet* src) { |
|
252 assert(_fl_lock == src->_fl_lock, "Should share the same lock"); |
|
253 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag); |
|
254 if (_buf_free_list != NULL) { |
|
255 void **p = _buf_free_list; |
|
256 while (*p != NULL) { |
|
257 p = (void**)*p; |
|
258 } |
|
259 *p = src->_buf_free_list; |
|
260 } else { |
|
261 _buf_free_list = src->_buf_free_list; |
|
262 } |
|
263 _buf_free_list_sz += src->_buf_free_list_sz; |
|
264 src->_buf_free_list = NULL; |
|
265 src->_buf_free_list_sz = 0; |
|
266 } |