91 using PtrQueue::byte_width_of_active; |
92 using PtrQueue::byte_width_of_active; |
92 |
93 |
93 }; |
94 }; |
94 |
95 |
95 class SATBMarkQueueSet: public PtrQueueSet { |
96 class SATBMarkQueueSet: public PtrQueueSet { |
|
97 |
|
98 DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0); |
|
99 PaddedEnd<BufferNode::Stack> _list; |
|
100 volatile size_t _count_and_process_flag; |
|
101 // These are rarely (if ever) changed, so same cache line as count. |
|
102 size_t _process_completed_buffers_threshold; |
96 size_t _buffer_enqueue_threshold; |
103 size_t _buffer_enqueue_threshold; |
|
104 DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, 3 * sizeof(size_t)); |
|
105 |
|
106 BufferNode* get_completed_buffer(); |
|
107 void abandon_completed_buffers(); |
97 |
108 |
98 #ifdef ASSERT |
109 #ifdef ASSERT |
99 void dump_active_states(bool expected_active); |
110 void dump_active_states(bool expected_active); |
100 void verify_active_states(bool expected_active); |
111 void verify_active_states(bool expected_active); |
101 #endif // ASSERT |
112 #endif // ASSERT |
102 |
113 |
103 protected: |
114 protected: |
104 SATBMarkQueueSet(); |
115 SATBMarkQueueSet(BufferNode::Allocator* allocator); |
105 ~SATBMarkQueueSet() {} |
116 ~SATBMarkQueueSet(); |
106 |
117 |
107 template<typename Filter> |
118 template<typename Filter> |
108 void apply_filter(Filter filter, SATBMarkQueue* queue) { |
119 void apply_filter(Filter filter, SATBMarkQueue* queue) { |
109 queue->apply_filter(filter); |
120 queue->apply_filter(filter); |
110 } |
121 } |
111 |
|
112 void initialize(Monitor* cbl_mon, |
|
113 BufferNode::Allocator* allocator, |
|
114 size_t process_completed_buffers_threshold, |
|
115 uint buffer_enqueue_threshold_percentage); |
|
116 |
122 |
117 public: |
123 public: |
118 virtual SATBMarkQueue& satb_queue_for_thread(Thread* const t) const = 0; |
124 virtual SATBMarkQueue& satb_queue_for_thread(Thread* const t) const = 0; |
119 |
125 |
120 // Apply "set_active(active)" to all SATB queues in the set. It should be |
126 // Apply "set_active(active)" to all SATB queues in the set. It should be |
121 // called only with the world stopped. The method will assert that the |
127 // called only with the world stopped. The method will assert that the |
122 // SATB queues of all threads it visits, as well as the SATB queue |
128 // SATB queues of all threads it visits, as well as the SATB queue |
123 // set itself, has an active value same as expected_active. |
129 // set itself, has an active value same as expected_active. |
124 void set_active_all_threads(bool active, bool expected_active); |
130 void set_active_all_threads(bool active, bool expected_active); |
125 |
131 |
|
132 void set_process_completed_buffers_threshold(size_t value); |
|
133 |
126 size_t buffer_enqueue_threshold() const { return _buffer_enqueue_threshold; } |
134 size_t buffer_enqueue_threshold() const { return _buffer_enqueue_threshold; } |
|
135 void set_buffer_enqueue_threshold_percentage(uint value); |
|
136 |
127 virtual void filter(SATBMarkQueue* queue) = 0; |
137 virtual void filter(SATBMarkQueue* queue) = 0; |
128 |
138 |
129 // If there exists some completed buffer, pop and process it, and |
139 // If there exists some completed buffer, pop and process it, and |
130 // return true. Otherwise return false. Processing a buffer |
140 // return true. Otherwise return false. Processing a buffer |
131 // consists of applying the closure to the active range of the |
141 // consists of applying the closure to the active range of the |
132 // buffer; the leading entries may be excluded due to filtering. |
142 // buffer; the leading entries may be excluded due to filtering. |
133 bool apply_closure_to_completed_buffer(SATBBufferClosure* cl); |
143 bool apply_closure_to_completed_buffer(SATBBufferClosure* cl); |
|
144 |
|
145 virtual void enqueue_completed_buffer(BufferNode* node); |
|
146 |
|
147 // The number of buffers in the list. Racy and not updated atomically |
|
148 // with the set of completed buffers. |
|
149 size_t completed_buffers_num() const { |
|
150 return _count_and_process_flag >> 1; |
|
151 } |
|
152 |
|
153 // Return true if completed buffers should be processed. |
|
154 bool process_completed_buffers() const { |
|
155 return (_count_and_process_flag & 1) != 0; |
|
156 } |
134 |
157 |
135 #ifndef PRODUCT |
158 #ifndef PRODUCT |
136 // Helpful for debugging |
159 // Helpful for debugging |
137 void print_all(const char* msg); |
160 void print_all(const char* msg); |
138 #endif // PRODUCT |
161 #endif // PRODUCT |