294 // In particular, the individual queues allocate buffers from this shared |
294 // In particular, the individual queues allocate buffers from this shared |
295 // set, and return completed buffers to the set. |
295 // set, and return completed buffers to the set. |
296 class PtrQueueSet { |
296 class PtrQueueSet { |
297 BufferNode::Allocator* _allocator; |
297 BufferNode::Allocator* _allocator; |
298 |
298 |
299 Monitor* _cbl_mon; // Protects the fields below. |
|
300 BufferNode* _completed_buffers_head; |
|
301 BufferNode* _completed_buffers_tail; |
|
302 volatile size_t _n_completed_buffers; |
|
303 |
|
304 size_t _process_completed_buffers_threshold; |
|
305 volatile bool _process_completed_buffers; |
|
306 |
|
307 // If true, notify_all on _cbl_mon when the threshold is reached. |
|
308 bool _notify_when_complete; |
|
309 |
|
310 void assert_completed_buffers_list_len_correct_locked() NOT_DEBUG_RETURN; |
|
311 |
|
312 protected: |
299 protected: |
313 bool _all_active; |
300 bool _all_active; |
314 |
301 |
315 // Create an empty ptr queue set. |
302 // Create an empty ptr queue set. |
316 PtrQueueSet(bool notify_when_complete = false); |
303 PtrQueueSet(); |
317 ~PtrQueueSet(); |
304 ~PtrQueueSet(); |
318 |
305 |
319 // Because of init-order concerns, we can't pass these as constructor |
306 // Because of init-order concerns, we can't pass these as constructor |
320 // arguments. |
307 // arguments. |
321 void initialize(Monitor* cbl_mon, BufferNode::Allocator* allocator); |
308 void initialize(BufferNode::Allocator* allocator); |
322 |
|
323 // For (unlocked!) iteration over the completed buffers. |
|
324 BufferNode* completed_buffers_head() const { return _completed_buffers_head; } |
|
325 |
|
326 // Deallocate all of the completed buffers. |
|
327 void abandon_completed_buffers(); |
|
328 |
309 |
329 public: |
310 public: |
330 |
311 |
331 // Return the buffer for a BufferNode of size buffer_size(). |
312 // Return the buffer for a BufferNode of size buffer_size(). |
332 void** allocate_buffer(); |
313 void** allocate_buffer(); |
337 |
318 |
338 // A completed buffer is a buffer the mutator is finished with, and |
319 // A completed buffer is a buffer the mutator is finished with, and |
339 // is ready to be processed by the collector. It need not be full. |
320 // is ready to be processed by the collector. It need not be full. |
340 |
321 |
341 // Adds node to the completed buffer list. |
322 // Adds node to the completed buffer list. |
342 void enqueue_completed_buffer(BufferNode* node); |
323 virtual void enqueue_completed_buffer(BufferNode* node) = 0; |
343 |
|
344 // If the number of completed buffers is > stop_at, then remove and |
|
345 // return a completed buffer from the list. Otherwise, return NULL. |
|
346 BufferNode* get_completed_buffer(size_t stop_at = 0); |
|
347 |
|
348 bool process_completed_buffers() { return _process_completed_buffers; } |
|
349 void set_process_completed_buffers(bool x) { _process_completed_buffers = x; } |
|
350 |
324 |
351 bool is_active() { return _all_active; } |
325 bool is_active() { return _all_active; } |
352 |
326 |
353 size_t buffer_size() const { |
327 size_t buffer_size() const { |
354 return _allocator->buffer_size(); |
328 return _allocator->buffer_size(); |
355 } |
329 } |
356 |
|
357 // Get/Set the number of completed buffers that triggers log processing. |
|
358 // Log processing should be done when the number of buffers exceeds the |
|
359 // threshold. |
|
360 void set_process_completed_buffers_threshold(size_t sz) { |
|
361 _process_completed_buffers_threshold = sz; |
|
362 } |
|
363 size_t process_completed_buffers_threshold() const { |
|
364 return _process_completed_buffers_threshold; |
|
365 } |
|
366 static const size_t ProcessCompletedBuffersThresholdNever = ~size_t(0); |
|
367 |
|
368 size_t completed_buffers_num() const { return _n_completed_buffers; } |
|
369 |
|
370 void merge_bufferlists(PtrQueueSet* src); |
|
371 |
|
372 // Notify the consumer if the number of buffers crossed the threshold |
|
373 void notify_if_necessary(); |
|
374 }; |
330 }; |
375 |
331 |
376 #endif // SHARE_GC_SHARED_PTRQUEUE_HPP |
332 #endif // SHARE_GC_SHARED_PTRQUEUE_HPP |