267 size_t buffer_size() const { return _buffer_size; }
268 size_t free_count() const;
269 BufferNode* allocate();
270 void release(BufferNode* node);
271 void reduce_free_list();
272 };
273 };
274
275 // A PtrQueueSet represents resources common to a set of pointer queues.
276 // In particular, the individual queues allocate buffers from this shared
277 // set, and return completed buffers to the set.
278 // All these variables are are protected by the TLOQ_CBL_mon. XXX ???
279 class PtrQueueSet {
280 BufferNode::Allocator* _allocator;
281
282 protected:
283 Monitor* _cbl_mon; // Protects the fields below.
284 BufferNode* _completed_buffers_head;
285 BufferNode* _completed_buffers_tail;
286 size_t _n_completed_buffers;
287 int _process_completed_threshold;
288 volatile bool _process_completed;
289
290 bool _all_active;
291
292 // If true, notify_all on _cbl_mon when the threshold is reached.
293 bool _notify_when_complete;
294
295 // Maximum number of elements allowed on completed queue: after that,
296 // enqueuer does the work itself. Zero indicates no maximum.
297 int _max_completed_queue;
298 size_t _completed_queue_padding;
299
300 size_t completed_buffers_list_length();
301 void assert_completed_buffer_list_len_correct_locked();
302 void assert_completed_buffer_list_len_correct();
303
304 protected:
305 // A mutator thread does the the work of processing a buffer.
306 // Returns "true" iff the work is complete (and the buffer may be
307 // deallocated).
308 virtual bool mut_process_buffer(BufferNode* node) {
309 ShouldNotReachHere();
310 return false;
311 }
312
313 // Create an empty ptr queue set.
314 PtrQueueSet(bool notify_when_complete = false);
315 ~PtrQueueSet();
316
317 // Because of init-order concerns, we can't pass these as constructor
318 // arguments.
319 void initialize(Monitor* cbl_mon,
320 BufferNode::Allocator* allocator,
321 int process_completed_threshold,
322 int max_completed_queue);
323
324 public:
325
326 // Return the buffer for a BufferNode of size buffer_size().
327 void** allocate_buffer();
328
329 // Return an empty buffer to the free list. The node is required
330 // to have been allocated with a size of buffer_size().
331 void deallocate_buffer(BufferNode* node);
332
333 // Declares that "buf" is a complete buffer.
334 void enqueue_complete_buffer(BufferNode* node);
335
336 // To be invoked by the mutator.
337 bool process_or_enqueue_complete_buffer(BufferNode* node);
338
339 bool completed_buffers_exist_dirty() {
340 return _n_completed_buffers > 0;
341 }
342
343 bool process_completed_buffers() { return _process_completed; }
344 void set_process_completed(bool x) { _process_completed = x; }
345
346 bool is_active() { return _all_active; }
347
348 size_t buffer_size() const {
349 return _allocator->buffer_size();
350 }
351
352 // Get/Set the number of completed buffers that triggers log processing.
353 void set_process_completed_threshold(int sz) { _process_completed_threshold = sz; }
354 int process_completed_threshold() const { return _process_completed_threshold; }
355
356 size_t completed_buffers_num() { return _n_completed_buffers; }
357
358 void merge_bufferlists(PtrQueueSet* src);
359
360 void set_max_completed_queue(int m) { _max_completed_queue = m; }
361 int max_completed_queue() { return _max_completed_queue; }
362
363 void set_completed_queue_padding(size_t padding) { _completed_queue_padding = padding; }
364 size_t completed_queue_padding() { return _completed_queue_padding; }
365
366 // Notify the consumer if the number of buffers crossed the threshold
367 void notify_if_necessary();
368 };
369
370 #endif // SHARE_GC_SHARED_PTRQUEUE_HPP
|
267 size_t buffer_size() const { return _buffer_size; }
268 size_t free_count() const;
269 BufferNode* allocate();
270 void release(BufferNode* node);
271 void reduce_free_list();
272 };
273 };
274
275 // A PtrQueueSet represents resources common to a set of pointer queues.
276 // In particular, the individual queues allocate buffers from this shared
277 // set, and return completed buffers to the set.
278 // All these variables are are protected by the TLOQ_CBL_mon. XXX ???
279 class PtrQueueSet {
280 BufferNode::Allocator* _allocator;
281
282 protected:
283 Monitor* _cbl_mon; // Protects the fields below.
284 BufferNode* _completed_buffers_head;
285 BufferNode* _completed_buffers_tail;
286 size_t _n_completed_buffers;
287 size_t _process_completed_buffers_threshold;
288 volatile bool _process_completed;
289
290 bool _all_active;
291
292 // If true, notify_all on _cbl_mon when the threshold is reached.
293 bool _notify_when_complete;
294
295 // Maximum number of elements allowed on completed queue: after that,
296 // enqueuer does the work itself.
297 size_t _max_completed_buffers;
298 size_t _completed_buffers_padding;
299
300 size_t completed_buffers_list_length();
301 void assert_completed_buffer_list_len_correct_locked();
302 void assert_completed_buffer_list_len_correct();
303
304 protected:
305 // A mutator thread does the the work of processing a buffer.
306 // Returns "true" iff the work is complete (and the buffer may be
307 // deallocated).
308 virtual bool mut_process_buffer(BufferNode* node) {
309 ShouldNotReachHere();
310 return false;
311 }
312
313 // Create an empty ptr queue set.
314 PtrQueueSet(bool notify_when_complete = false);
315 ~PtrQueueSet();
316
317 // Because of init-order concerns, we can't pass these as constructor
318 // arguments.
319 void initialize(Monitor* cbl_mon, BufferNode::Allocator* allocator);
320
321 public:
322
323 // Return the buffer for a BufferNode of size buffer_size().
324 void** allocate_buffer();
325
326 // Return an empty buffer to the free list. The node is required
327 // to have been allocated with a size of buffer_size().
328 void deallocate_buffer(BufferNode* node);
329
330 // Declares that "buf" is a complete buffer.
331 void enqueue_complete_buffer(BufferNode* node);
332
333 // To be invoked by the mutator.
334 bool process_or_enqueue_complete_buffer(BufferNode* node);
335
336 bool completed_buffers_exist_dirty() {
337 return _n_completed_buffers > 0;
338 }
339
340 bool process_completed_buffers() { return _process_completed; }
341 void set_process_completed(bool x) { _process_completed = x; }
342
343 bool is_active() { return _all_active; }
344
345 size_t buffer_size() const {
346 return _allocator->buffer_size();
347 }
348
349 // Get/Set the number of completed buffers that triggers log processing.
350 // Log processing should be done when the number of buffers exceeds the
351 // threshold.
352 void set_process_completed_buffers_threshold(size_t sz) {
353 _process_completed_buffers_threshold = sz;
354 }
355 size_t process_completed_buffers_threshold() const {
356 return _process_completed_buffers_threshold;
357 }
358 static const size_t ProcessCompletedBuffersThresholdNever = ~size_t(0);
359
360 size_t completed_buffers_num() const { return _n_completed_buffers; }
361
362 void merge_bufferlists(PtrQueueSet* src);
363
364 void set_max_completed_buffers(size_t m) {
365 _max_completed_buffers = m;
366 }
367 size_t max_completed_buffers() const {
368 return _max_completed_buffers;
369 }
370 static const size_t MaxCompletedBuffersUnlimited = ~size_t(0);
371
372 void set_completed_buffers_padding(size_t padding) {
373 _completed_buffers_padding = padding;
374 }
375 size_t completed_buffers_padding() const {
376 return _completed_buffers_padding;
377 }
378
379 // Notify the consumer if the number of buffers crossed the threshold
380 void notify_if_necessary();
381 };
382
383 #endif // SHARE_GC_SHARED_PTRQUEUE_HPP
|