< prev index next >
src/hotspot/share/gc/shared/ptrQueue.hpp
Print this page
rev 52403 : [mq]: allocator
rev 52405 : [mq]: use_allocators
*** 26,35 ****
--- 26,37 ----
#define SHARE_GC_SHARED_PTRQUEUE_HPP
#include "utilities/align.hpp"
#include "utilities/sizes.hpp"
+ class Mutex;
+
// There are various techniques that require threads to be able to log
// addresses. For example, a generational write barrier might log
// the addresses of modified old-generation objects. This type supports
// this operation.
*** 221,242 ****
static size_t buffer_offset() {
return offset_of(BufferNode, _buffer);
}
! public:
! BufferNode* next() const { return _next; }
! void set_next(BufferNode* n) { _next = n; }
! size_t index() const { return _index; }
! void set_index(size_t i) { _index = i; }
!
// Allocate a new BufferNode with the "buffer" having size elements.
static BufferNode* allocate(size_t size);
// Free a BufferNode.
static void deallocate(BufferNode* node);
// Return the BufferNode containing the buffer, after setting its index.
static BufferNode* make_node_from_buffer(void** buffer, size_t index) {
BufferNode* node =
reinterpret_cast<BufferNode*>(
reinterpret_cast<char*>(buffer) - buffer_offset());
--- 223,245 ----
static size_t buffer_offset() {
return offset_of(BufferNode, _buffer);
}
! AIX_ONLY(public:) // xlC 12 on AIX doesn't implement C++ DR45.
// Allocate a new BufferNode with the "buffer" having size elements.
static BufferNode* allocate(size_t size);
// Free a BufferNode.
static void deallocate(BufferNode* node);
+ public:
+ BufferNode* next() const { return _next; }
+ void set_next(BufferNode* n) { _next = n; }
+ size_t index() const { return _index; }
+ void set_index(size_t i) { _index = i; }
+
// Return the BufferNode containing the buffer, after setting its index.
static BufferNode* make_node_from_buffer(void** buffer, size_t index) {
BufferNode* node =
reinterpret_cast<BufferNode*>(
reinterpret_cast<char*>(buffer) - buffer_offset());
*** 248,284 ****
static void** make_buffer_from_node(BufferNode *node) {
// &_buffer[0] might lead to index out of bounds warnings.
return reinterpret_cast<void**>(
reinterpret_cast<char*>(node) + buffer_offset());
}
};
// A PtrQueueSet represents resources common to a set of pointer queues.
// In particular, the individual queues allocate buffers from this shared
// set, and return completed buffers to the set.
// All these variables are are protected by the TLOQ_CBL_mon. XXX ???
class PtrQueueSet {
! // The size of all buffers in the set.
! size_t _buffer_size;
protected:
Monitor* _cbl_mon; // Protects the fields below.
BufferNode* _completed_buffers_head;
BufferNode* _completed_buffers_tail;
size_t _n_completed_buffers;
int _process_completed_threshold;
volatile bool _process_completed;
- // This (and the interpretation of the first element as a "next"
- // pointer) are protected by the TLOQ_FL_lock.
- Mutex* _fl_lock;
- BufferNode* _buf_free_list;
- size_t _buf_free_list_sz;
- // Queue set can share a freelist. The _fl_owner variable
- // specifies the owner. It is set to "this" by default.
- PtrQueueSet* _fl_owner;
-
bool _all_active;
// If true, notify_all on _cbl_mon when the threshold is reached.
bool _notify_when_complete;
--- 251,295 ----
static void** make_buffer_from_node(BufferNode *node) {
// &_buffer[0] might lead to index out of bounds warnings.
return reinterpret_cast<void**>(
reinterpret_cast<char*>(node) + buffer_offset());
}
+
+ // Free-list based allocator.
+ class Allocator {
+ size_t _buffer_size;
+ Mutex* _lock;
+ BufferNode* _free_list;
+ volatile size_t _free_count;
+
+ public:
+ Allocator(size_t buffer_size, Mutex* lock);
+ ~Allocator();
+
+ size_t buffer_size() const { return _buffer_size; }
+ size_t free_count() const;
+ BufferNode* allocate();
+ void release(BufferNode* node);
+ void reduce_free_list();
+ };
};
// A PtrQueueSet represents resources common to a set of pointer queues.
// In particular, the individual queues allocate buffers from this shared
// set, and return completed buffers to the set.
// All these variables are are protected by the TLOQ_CBL_mon. XXX ???
class PtrQueueSet {
! BufferNode::Allocator* _allocator;
protected:
Monitor* _cbl_mon; // Protects the fields below.
BufferNode* _completed_buffers_head;
BufferNode* _completed_buffers_tail;
size_t _n_completed_buffers;
int _process_completed_threshold;
volatile bool _process_completed;
bool _all_active;
// If true, notify_all on _cbl_mon when the threshold is reached.
bool _notify_when_complete;
*** 305,318 ****
~PtrQueueSet();
// Because of init-order concerns, we can't pass these as constructor
// arguments.
void initialize(Monitor* cbl_mon,
! Mutex* fl_lock,
int process_completed_threshold,
! int max_completed_queue,
! PtrQueueSet *fl_owner = NULL);
public:
// Return the buffer for a BufferNode of size buffer_size().
void** allocate_buffer();
--- 316,328 ----
~PtrQueueSet();
// Because of init-order concerns, we can't pass these as constructor
// arguments.
void initialize(Monitor* cbl_mon,
! BufferNode::Allocator* allocator,
int process_completed_threshold,
! int max_completed_queue);
public:
// Return the buffer for a BufferNode of size buffer_size().
void** allocate_buffer();
*** 334,361 ****
bool process_completed_buffers() { return _process_completed; }
void set_process_completed(bool x) { _process_completed = x; }
bool is_active() { return _all_active; }
- // Set the buffer size. Should be called before any "enqueue" operation
- // can be called. And should only be called once.
- void set_buffer_size(size_t sz);
-
- // Get the buffer size. Must have been set.
size_t buffer_size() const {
! assert(_buffer_size > 0, "buffer size not set");
! return _buffer_size;
}
// Get/Set the number of completed buffers that triggers log processing.
void set_process_completed_threshold(int sz) { _process_completed_threshold = sz; }
int process_completed_threshold() const { return _process_completed_threshold; }
- // Must only be called at a safe point. Indicates that the buffer free
- // list size may be reduced, if that is deemed desirable.
- void reduce_free_list();
-
size_t completed_buffers_num() { return _n_completed_buffers; }
void merge_bufferlists(PtrQueueSet* src);
void set_max_completed_queue(int m) { _max_completed_queue = m; }
--- 344,361 ----
bool process_completed_buffers() { return _process_completed; }
void set_process_completed(bool x) { _process_completed = x; }
bool is_active() { return _all_active; }
size_t buffer_size() const {
! return _allocator->buffer_size();
}
// Get/Set the number of completed buffers that triggers log processing.
void set_process_completed_threshold(int sz) { _process_completed_threshold = sz; }
int process_completed_threshold() const { return _process_completed_threshold; }
size_t completed_buffers_num() { return _n_completed_buffers; }
void merge_bufferlists(PtrQueueSet* src);
void set_max_completed_queue(int m) { _max_completed_queue = m; }
< prev index next >