192 reinterpret_cast<char*>(buffer) - buffer_offset()); 193 } 194 195 // Return the buffer for node. 196 static void** make_buffer_from_node(BufferNode *node) { 197 // &_buffer[0] might lead to index out of bounds warnings. 198 return reinterpret_cast<void**>( 199 reinterpret_cast<char*>(node) + buffer_offset()); 200 } 201 }; 202 203 // A PtrQueueSet represents resources common to a set of pointer queues. 204 // In particular, the individual queues allocate buffers from this shared 205 // set, and return completed buffers to the set. 206 // All these variables are are protected by the TLOQ_CBL_mon. XXX ??? 207 class PtrQueueSet VALUE_OBJ_CLASS_SPEC { 208 protected: 209 Monitor* _cbl_mon; // Protects the fields below. 210 BufferNode* _completed_buffers_head; 211 BufferNode* _completed_buffers_tail; 212 int _n_completed_buffers; 213 int _process_completed_threshold; 214 volatile bool _process_completed; 215 216 // This (and the interpretation of the first element as a "next" 217 // pointer) are protected by the TLOQ_FL_lock. 218 Mutex* _fl_lock; 219 BufferNode* _buf_free_list; 220 size_t _buf_free_list_sz; 221 // Queue set can share a freelist. The _fl_owner variable 222 // specifies the owner. It is set to "this" by default. 223 PtrQueueSet* _fl_owner; 224 225 // The size of all buffers in the set. 226 size_t _sz; 227 228 bool _all_active; 229 230 // If true, notify_all on _cbl_mon when the threshold is reached. 231 bool _notify_when_complete; 232 233 // Maximum number of elements allowed on completed queue: after that, 234 // enqueuer does the work itself. Zero indicates no maximum. 235 int _max_completed_queue; 236 int _completed_queue_padding; 237 238 int completed_buffers_list_length(); 239 void assert_completed_buffer_list_len_correct_locked(); 240 void assert_completed_buffer_list_len_correct(); 241 242 protected: 243 // A mutator thread does the the work of processing a buffer. 244 // Returns "true" iff the work is complete (and the buffer may be 245 // deallocated). 246 virtual bool mut_process_buffer(void** buf) { 247 ShouldNotReachHere(); 248 return false; 249 } 250 251 // Create an empty ptr queue set. 252 PtrQueueSet(bool notify_when_complete = false); 253 ~PtrQueueSet(); 254 255 // Because of init-order concerns, we can't pass these as constructor 256 // arguments. 257 void initialize(Monitor* cbl_mon, 258 Mutex* fl_lock, 282 bool process_completed_buffers() { return _process_completed; } 283 void set_process_completed(bool x) { _process_completed = x; } 284 285 bool is_active() { return _all_active; } 286 287 // Set the buffer size. Should be called before any "enqueue" operation 288 // can be called. And should only be called once. 289 void set_buffer_size(size_t sz); 290 291 // Get the buffer size. 292 size_t buffer_size() { return _sz; } 293 294 // Get/Set the number of completed buffers that triggers log processing. 295 void set_process_completed_threshold(int sz) { _process_completed_threshold = sz; } 296 int process_completed_threshold() const { return _process_completed_threshold; } 297 298 // Must only be called at a safe point. Indicates that the buffer free 299 // list size may be reduced, if that is deemed desirable. 300 void reduce_free_list(); 301 302 int completed_buffers_num() { return _n_completed_buffers; } 303 304 void merge_bufferlists(PtrQueueSet* src); 305 306 void set_max_completed_queue(int m) { _max_completed_queue = m; } 307 int max_completed_queue() { return _max_completed_queue; } 308 309 void set_completed_queue_padding(int padding) { _completed_queue_padding = padding; } 310 int completed_queue_padding() { return _completed_queue_padding; } 311 312 // Notify the consumer if the number of buffers crossed the threshold 313 void notify_if_necessary(); 314 }; 315 316 #endif // SHARE_VM_GC_G1_PTRQUEUE_HPP | 192 reinterpret_cast<char*>(buffer) - buffer_offset()); 193 } 194 195 // Return the buffer for node. 196 static void** make_buffer_from_node(BufferNode *node) { 197 // &_buffer[0] might lead to index out of bounds warnings. 198 return reinterpret_cast<void**>( 199 reinterpret_cast<char*>(node) + buffer_offset()); 200 } 201 }; 202 203 // A PtrQueueSet represents resources common to a set of pointer queues. 204 // In particular, the individual queues allocate buffers from this shared 205 // set, and return completed buffers to the set. 206 // All these variables are are protected by the TLOQ_CBL_mon. XXX ??? 207 class PtrQueueSet VALUE_OBJ_CLASS_SPEC { 208 protected: 209 Monitor* _cbl_mon; // Protects the fields below. 210 BufferNode* _completed_buffers_head; 211 BufferNode* _completed_buffers_tail; 212 size_t _n_completed_buffers; 213 int _process_completed_threshold; 214 volatile bool _process_completed; 215 216 // This (and the interpretation of the first element as a "next" 217 // pointer) are protected by the TLOQ_FL_lock. 218 Mutex* _fl_lock; 219 BufferNode* _buf_free_list; 220 size_t _buf_free_list_sz; 221 // Queue set can share a freelist. The _fl_owner variable 222 // specifies the owner. It is set to "this" by default. 223 PtrQueueSet* _fl_owner; 224 225 // The size of all buffers in the set. 226 size_t _sz; 227 228 bool _all_active; 229 230 // If true, notify_all on _cbl_mon when the threshold is reached. 231 bool _notify_when_complete; 232 233 // Maximum number of elements allowed on completed queue: after that, 234 // enqueuer does the work itself. Zero indicates no maximum. 235 int _max_completed_queue; 236 size_t _completed_queue_padding; 237 238 size_t completed_buffers_list_length(); 239 void assert_completed_buffer_list_len_correct_locked(); 240 void assert_completed_buffer_list_len_correct(); 241 242 protected: 243 // A mutator thread does the the work of processing a buffer. 244 // Returns "true" iff the work is complete (and the buffer may be 245 // deallocated). 246 virtual bool mut_process_buffer(void** buf) { 247 ShouldNotReachHere(); 248 return false; 249 } 250 251 // Create an empty ptr queue set. 252 PtrQueueSet(bool notify_when_complete = false); 253 ~PtrQueueSet(); 254 255 // Because of init-order concerns, we can't pass these as constructor 256 // arguments. 257 void initialize(Monitor* cbl_mon, 258 Mutex* fl_lock, 282 bool process_completed_buffers() { return _process_completed; } 283 void set_process_completed(bool x) { _process_completed = x; } 284 285 bool is_active() { return _all_active; } 286 287 // Set the buffer size. Should be called before any "enqueue" operation 288 // can be called. And should only be called once. 289 void set_buffer_size(size_t sz); 290 291 // Get the buffer size. 292 size_t buffer_size() { return _sz; } 293 294 // Get/Set the number of completed buffers that triggers log processing. 295 void set_process_completed_threshold(int sz) { _process_completed_threshold = sz; } 296 int process_completed_threshold() const { return _process_completed_threshold; } 297 298 // Must only be called at a safe point. Indicates that the buffer free 299 // list size may be reduced, if that is deemed desirable. 300 void reduce_free_list(); 301 302 size_t completed_buffers_num() { return _n_completed_buffers; } 303 304 void merge_bufferlists(PtrQueueSet* src); 305 306 void set_max_completed_queue(int m) { _max_completed_queue = m; } 307 int max_completed_queue() { return _max_completed_queue; } 308 309 void set_completed_queue_padding(size_t padding) { _completed_queue_padding = padding; } 310 size_t completed_queue_padding() { return _completed_queue_padding; } 311 312 // Notify the consumer if the number of buffers crossed the threshold 313 void notify_if_necessary(); 314 }; 315 316 #endif // SHARE_VM_GC_G1_PTRQUEUE_HPP |