annotate src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp @ 2149:7e37af9d69ef

7011379: G1: overly long concurrent marking cycles Summary: This changeset introduces filtering of SATB buffers at the point when they are about to be enqueued. If this filtering clears enough entries on each buffer, the buffer can then be re-used and not enqueued. This cuts down the number of SATB buffers that need to be processed by the concurrent marking threads. Reviewed-by: johnc, ysr
author tonyp
date Wed, 19 Jan 2011 09:35:17 -0500
parents f95d63e2154a
children bca17e38de00
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
2 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
25 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GCTASKMANAGER_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GCTASKMANAGER_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "runtime/mutex.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "utilities/growableArray.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30
0
a61af66fc99e Initial load
duke
parents:
diff changeset
31 //
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // The GCTaskManager is a queue of GCTasks, and accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // to allow the queue to be accessed from many threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
34 //
a61af66fc99e Initial load
duke
parents:
diff changeset
35
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // Forward declarations of types defined in this file.
a61af66fc99e Initial load
duke
parents:
diff changeset
37 class GCTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 class GCTaskQueue;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 class SynchronizedGCTaskQueue;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 class GCTaskManager;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 class NotifyDoneClosure;
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // Some useful subclasses of GCTask. You can also make up your own.
a61af66fc99e Initial load
duke
parents:
diff changeset
43 class NoopGCTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
44 class BarrierGCTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 class ReleasingBarrierGCTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 class NotifyingBarrierGCTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
47 class WaitForBarrierGCTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // A free list of Monitor*'s.
a61af66fc99e Initial load
duke
parents:
diff changeset
49 class MonitorSupply;
a61af66fc99e Initial load
duke
parents:
diff changeset
50
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // Forward declarations of classes referenced in this file via pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
52 class GCTaskThread;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 class Mutex;
a61af66fc99e Initial load
duke
parents:
diff changeset
54 class Monitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 class ThreadClosure;
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // The abstract base GCTask.
a61af66fc99e Initial load
duke
parents:
diff changeset
58 class GCTask : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
59 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // Known kinds of GCTasks, for predicates.
a61af66fc99e Initial load
duke
parents:
diff changeset
61 class Kind : AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
62 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
63 enum kind {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 unknown_task,
a61af66fc99e Initial load
duke
parents:
diff changeset
65 ordinary_task,
a61af66fc99e Initial load
duke
parents:
diff changeset
66 barrier_task,
a61af66fc99e Initial load
duke
parents:
diff changeset
67 noop_task
a61af66fc99e Initial load
duke
parents:
diff changeset
68 };
a61af66fc99e Initial load
duke
parents:
diff changeset
69 static const char* to_string(kind value);
a61af66fc99e Initial load
duke
parents:
diff changeset
70 };
a61af66fc99e Initial load
duke
parents:
diff changeset
71 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // Instance state.
a61af66fc99e Initial load
duke
parents:
diff changeset
73 const Kind::kind _kind; // For runtime type checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
74 const uint _affinity; // Which worker should run task.
a61af66fc99e Initial load
duke
parents:
diff changeset
75 GCTask* _newer; // Tasks are on doubly-linked ...
a61af66fc99e Initial load
duke
parents:
diff changeset
76 GCTask* _older; // ... lists.
a61af66fc99e Initial load
duke
parents:
diff changeset
77 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
78 virtual char* name() { return (char *)"task"; }
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // Abstract do_it method
a61af66fc99e Initial load
duke
parents:
diff changeset
81 virtual void do_it(GCTaskManager* manager, uint which) = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
83 Kind::kind kind() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 return _kind;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86 uint affinity() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 return _affinity;
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89 GCTask* newer() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
90 return _newer;
a61af66fc99e Initial load
duke
parents:
diff changeset
91 }
a61af66fc99e Initial load
duke
parents:
diff changeset
92 void set_newer(GCTask* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
93 _newer = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95 GCTask* older() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 return _older;
a61af66fc99e Initial load
duke
parents:
diff changeset
97 }
a61af66fc99e Initial load
duke
parents:
diff changeset
98 void set_older(GCTask* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 _older = p;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // Predicates.
a61af66fc99e Initial load
duke
parents:
diff changeset
102 bool is_ordinary_task() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
103 return kind()==Kind::ordinary_task;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105 bool is_barrier_task() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
106 return kind()==Kind::barrier_task;
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108 bool is_noop_task() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 return kind()==Kind::noop_task;
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111 void print(const char* message) const PRODUCT_RETURN;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // Constructors: Only create subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // An ordinary GCTask.
a61af66fc99e Initial load
duke
parents:
diff changeset
115 GCTask();
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // A GCTask of a particular kind, usually barrier or noop.
a61af66fc99e Initial load
duke
parents:
diff changeset
117 GCTask(Kind::kind kind);
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // An ordinary GCTask with an affinity.
a61af66fc99e Initial load
duke
parents:
diff changeset
119 GCTask(uint affinity);
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // A GCTask of a particular kind, with and affinity.
a61af66fc99e Initial load
duke
parents:
diff changeset
121 GCTask(Kind::kind kind, uint affinity);
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // We want a virtual destructor because virtual methods,
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // but since ResourceObj's don't have their destructors
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // called, we don't have one at all. Instead we have
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // this method, which gets called by subclasses to clean up.
a61af66fc99e Initial load
duke
parents:
diff changeset
126 virtual void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // Methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
128 void initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
129 };
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // A doubly-linked list of GCTasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // The list is not synchronized, because sometimes we want to
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // build up a list and then make it available to other threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
134 // See also: SynchronizedGCTaskQueue.
a61af66fc99e Initial load
duke
parents:
diff changeset
135 class GCTaskQueue : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // Instance state.
a61af66fc99e Initial load
duke
parents:
diff changeset
138 GCTask* _insert_end; // Tasks are enqueued at this end.
a61af66fc99e Initial load
duke
parents:
diff changeset
139 GCTask* _remove_end; // Tasks are dequeued from this end.
a61af66fc99e Initial load
duke
parents:
diff changeset
140 uint _length; // The current length of the queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
141 const bool _is_c_heap_obj; // Is this a CHeapObj?
a61af66fc99e Initial load
duke
parents:
diff changeset
142 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // Create as ResourceObj.
a61af66fc99e Initial load
duke
parents:
diff changeset
145 static GCTaskQueue* create();
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // Create as CHeapObj.
a61af66fc99e Initial load
duke
parents:
diff changeset
147 static GCTaskQueue* create_on_c_heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // Destroyer.
a61af66fc99e Initial load
duke
parents:
diff changeset
149 static void destroy(GCTaskQueue* that);
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // These just examine the state of the queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
152 bool is_empty() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
153 assert(((insert_end() == NULL && remove_end() == NULL) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
154 (insert_end() != NULL && remove_end() != NULL)),
a61af66fc99e Initial load
duke
parents:
diff changeset
155 "insert_end and remove_end don't match");
a61af66fc99e Initial load
duke
parents:
diff changeset
156 return insert_end() == NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
158 uint length() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
159 return _length;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // Methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // Enqueue one task.
a61af66fc99e Initial load
duke
parents:
diff changeset
163 void enqueue(GCTask* task);
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // Enqueue a list of tasks. Empties the argument list.
a61af66fc99e Initial load
duke
parents:
diff changeset
165 void enqueue(GCTaskQueue* list);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // Dequeue one task.
a61af66fc99e Initial load
duke
parents:
diff changeset
167 GCTask* dequeue();
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // Dequeue one task, preferring one with affinity.
a61af66fc99e Initial load
duke
parents:
diff changeset
169 GCTask* dequeue(uint affinity);
a61af66fc99e Initial load
duke
parents:
diff changeset
170 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Constructor. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
172 GCTaskQueue(bool on_c_heap);
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // Destructor-like method.
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // Because ResourceMark doesn't call destructors.
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // This method cleans up like one.
a61af66fc99e Initial load
duke
parents:
diff changeset
176 virtual void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
178 GCTask* insert_end() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
179 return _insert_end;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
181 void set_insert_end(GCTask* value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 _insert_end = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
184 GCTask* remove_end() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 return _remove_end;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187 void set_remove_end(GCTask* value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 _remove_end = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190 void increment_length() {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 _length += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193 void decrement_length() {
a61af66fc99e Initial load
duke
parents:
diff changeset
194 _length -= 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196 void set_length(uint value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 _length = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199 bool is_c_heap_obj() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
200 return _is_c_heap_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // Methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
203 void initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
204 GCTask* remove(); // Remove from remove end.
a61af66fc99e Initial load
duke
parents:
diff changeset
205 GCTask* remove(GCTask* task); // Remove from the middle.
a61af66fc99e Initial load
duke
parents:
diff changeset
206 void print(const char* message) const PRODUCT_RETURN;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 };
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // A GCTaskQueue that can be synchronized.
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // This "has-a" GCTaskQueue and a mutex to do the exclusion.
a61af66fc99e Initial load
duke
parents:
diff changeset
211 class SynchronizedGCTaskQueue : public CHeapObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // Instance state.
a61af66fc99e Initial load
duke
parents:
diff changeset
214 GCTaskQueue* _unsynchronized_queue; // Has-a unsynchronized queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
215 Monitor * _lock; // Lock to control access.
a61af66fc99e Initial load
duke
parents:
diff changeset
216 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
218 static SynchronizedGCTaskQueue* create(GCTaskQueue* queue, Monitor * lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 return new SynchronizedGCTaskQueue(queue, lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221 static void destroy(SynchronizedGCTaskQueue* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 if (that != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
223 delete that;
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
227 GCTaskQueue* unsynchronized_queue() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
228 return _unsynchronized_queue;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
230 Monitor * lock() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
231 return _lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 // GCTaskQueue wrapper methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // These check that you hold the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // and then call the method on the queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
236 bool is_empty() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 guarantee(own_lock(), "don't own the lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
238 return unsynchronized_queue()->is_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
240 void enqueue(GCTask* task) {
a61af66fc99e Initial load
duke
parents:
diff changeset
241 guarantee(own_lock(), "don't own the lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
242 unsynchronized_queue()->enqueue(task);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
244 void enqueue(GCTaskQueue* list) {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 guarantee(own_lock(), "don't own the lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
246 unsynchronized_queue()->enqueue(list);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248 GCTask* dequeue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 guarantee(own_lock(), "don't own the lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
250 return unsynchronized_queue()->dequeue();
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252 GCTask* dequeue(uint affinity) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 guarantee(own_lock(), "don't own the lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
254 return unsynchronized_queue()->dequeue(affinity);
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256 uint length() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
257 guarantee(own_lock(), "don't own the lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
258 return unsynchronized_queue()->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // For guarantees.
a61af66fc99e Initial load
duke
parents:
diff changeset
261 bool own_lock() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 return lock()->owned_by_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // Constructor. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
266 SynchronizedGCTaskQueue(GCTaskQueue* queue, Monitor * lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // Destructor. Not virtual because no virtuals.
a61af66fc99e Initial load
duke
parents:
diff changeset
268 ~SynchronizedGCTaskQueue();
a61af66fc99e Initial load
duke
parents:
diff changeset
269 };
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // This is an abstract base class for getting notifications
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // when a GCTaskManager is done.
a61af66fc99e Initial load
duke
parents:
diff changeset
273 class NotifyDoneClosure : public CHeapObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
274 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
275 // The notification callback method.
a61af66fc99e Initial load
duke
parents:
diff changeset
276 virtual void notify(GCTaskManager* manager) = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
277 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // Constructor.
a61af66fc99e Initial load
duke
parents:
diff changeset
279 NotifyDoneClosure() {
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // Virtual destructor because virtual methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
283 virtual ~NotifyDoneClosure() {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 };
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288 class GCTaskManager : public CHeapObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 friend class ParCompactionManager;
a61af66fc99e Initial load
duke
parents:
diff changeset
290 friend class PSParallelCompact;
a61af66fc99e Initial load
duke
parents:
diff changeset
291 friend class PSScavenge;
a61af66fc99e Initial load
duke
parents:
diff changeset
292 friend class PSRefProcTaskExecutor;
a61af66fc99e Initial load
duke
parents:
diff changeset
293 friend class RefProcTaskExecutor;
a61af66fc99e Initial load
duke
parents:
diff changeset
294 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // Instance state.
a61af66fc99e Initial load
duke
parents:
diff changeset
296 NotifyDoneClosure* _ndc; // Notify on completion.
a61af66fc99e Initial load
duke
parents:
diff changeset
297 const uint _workers; // Number of workers.
a61af66fc99e Initial load
duke
parents:
diff changeset
298 Monitor* _monitor; // Notification of changes.
a61af66fc99e Initial load
duke
parents:
diff changeset
299 SynchronizedGCTaskQueue* _queue; // Queue of tasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
300 GCTaskThread** _thread; // Array of worker threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
301 uint _busy_workers; // Number of busy workers.
a61af66fc99e Initial load
duke
parents:
diff changeset
302 uint _blocking_worker; // The worker that's blocking.
a61af66fc99e Initial load
duke
parents:
diff changeset
303 bool* _resource_flag; // Array of flag per threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
304 uint _delivered_tasks; // Count of delivered tasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
305 uint _completed_tasks; // Count of completed tasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
306 uint _barriers; // Count of barrier tasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
307 uint _emptied_queue; // Times we emptied the queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
308 NoopGCTask* _noop_task; // The NoopGCTask instance.
a61af66fc99e Initial load
duke
parents:
diff changeset
309 uint _noop_tasks; // Count of noop tasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
310 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
312 static GCTaskManager* create(uint workers) {
a61af66fc99e Initial load
duke
parents:
diff changeset
313 return new GCTaskManager(workers);
a61af66fc99e Initial load
duke
parents:
diff changeset
314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
315 static GCTaskManager* create(uint workers, NotifyDoneClosure* ndc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
316 return new GCTaskManager(workers, ndc);
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318 static void destroy(GCTaskManager* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
319 if (that != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 delete that;
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
324 uint busy_workers() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 return _busy_workers;
a61af66fc99e Initial load
duke
parents:
diff changeset
326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // Pun between Monitor* and Mutex*
a61af66fc99e Initial load
duke
parents:
diff changeset
328 Monitor* monitor() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 return _monitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331 Monitor * lock() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
332 return _monitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // Methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // Add the argument task to be run.
a61af66fc99e Initial load
duke
parents:
diff changeset
336 void add_task(GCTask* task);
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // Add a list of tasks. Removes task from the argument list.
a61af66fc99e Initial load
duke
parents:
diff changeset
338 void add_list(GCTaskQueue* list);
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // Claim a task for argument worker.
a61af66fc99e Initial load
duke
parents:
diff changeset
340 GCTask* get_task(uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // Note the completion of a task by the argument worker.
a61af66fc99e Initial load
duke
parents:
diff changeset
342 void note_completion(uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
343 // Is the queue blocked from handing out new tasks?
a61af66fc99e Initial load
duke
parents:
diff changeset
344 bool is_blocked() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
345 return (blocking_worker() != sentinel_worker());
a61af66fc99e Initial load
duke
parents:
diff changeset
346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // Request that all workers release their resources.
a61af66fc99e Initial load
duke
parents:
diff changeset
348 void release_all_resources();
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // Ask if a particular worker should release its resources.
a61af66fc99e Initial load
duke
parents:
diff changeset
350 bool should_release_resources(uint which); // Predicate.
a61af66fc99e Initial load
duke
parents:
diff changeset
351 // Note the release of resources by the argument worker.
a61af66fc99e Initial load
duke
parents:
diff changeset
352 void note_release(uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // Constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // A sentinel worker identifier.
a61af66fc99e Initial load
duke
parents:
diff changeset
355 static uint sentinel_worker() {
a61af66fc99e Initial load
duke
parents:
diff changeset
356 return (uint) -1; // Why isn't there a max_uint?
a61af66fc99e Initial load
duke
parents:
diff changeset
357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
358
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // Execute the task queue and wait for the completion.
a61af66fc99e Initial load
duke
parents:
diff changeset
360 void execute_and_wait(GCTaskQueue* list);
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 void print_task_time_stamps();
a61af66fc99e Initial load
duke
parents:
diff changeset
363 void print_threads_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
364 void threads_do(ThreadClosure* tc);
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // Constructors. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // Create a GCTaskManager with the appropriate number of workers.
a61af66fc99e Initial load
duke
parents:
diff changeset
369 GCTaskManager(uint workers);
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // Create a GCTaskManager that calls back when there's no more work.
a61af66fc99e Initial load
duke
parents:
diff changeset
371 GCTaskManager(uint workers, NotifyDoneClosure* ndc);
a61af66fc99e Initial load
duke
parents:
diff changeset
372 // Make virtual if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
373 ~GCTaskManager();
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
375 uint workers() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 return _workers;
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378 NotifyDoneClosure* notify_done_closure() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 return _ndc;
a61af66fc99e Initial load
duke
parents:
diff changeset
380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
381 SynchronizedGCTaskQueue* queue() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 return _queue;
a61af66fc99e Initial load
duke
parents:
diff changeset
383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
384 NoopGCTask* noop_task() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
385 return _noop_task;
a61af66fc99e Initial load
duke
parents:
diff changeset
386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // Bounds-checking per-thread data accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
388 GCTaskThread* thread(uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
389 void set_thread(uint which, GCTaskThread* value);
a61af66fc99e Initial load
duke
parents:
diff changeset
390 bool resource_flag(uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
391 void set_resource_flag(uint which, bool value);
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // Modifier methods with some semantics.
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // Is any worker blocking handing out new tasks?
a61af66fc99e Initial load
duke
parents:
diff changeset
394 uint blocking_worker() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
395 return _blocking_worker;
a61af66fc99e Initial load
duke
parents:
diff changeset
396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
397 void set_blocking_worker(uint value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
398 _blocking_worker = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
400 void set_unblocked() {
a61af66fc99e Initial load
duke
parents:
diff changeset
401 set_blocking_worker(sentinel_worker());
a61af66fc99e Initial load
duke
parents:
diff changeset
402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // Count of busy workers.
a61af66fc99e Initial load
duke
parents:
diff changeset
404 void reset_busy_workers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
405 _busy_workers = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
407 uint increment_busy_workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
408 uint decrement_busy_workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // Count of tasks delivered to workers.
a61af66fc99e Initial load
duke
parents:
diff changeset
410 uint delivered_tasks() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
411 return _delivered_tasks;
a61af66fc99e Initial load
duke
parents:
diff changeset
412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
413 void increment_delivered_tasks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
414 _delivered_tasks += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
416 void reset_delivered_tasks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
417 _delivered_tasks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // Count of tasks completed by workers.
a61af66fc99e Initial load
duke
parents:
diff changeset
420 uint completed_tasks() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
421 return _completed_tasks;
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423 void increment_completed_tasks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
424 _completed_tasks += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
426 void reset_completed_tasks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
427 _completed_tasks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429 // Count of barrier tasks completed.
a61af66fc99e Initial load
duke
parents:
diff changeset
430 uint barriers() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
431 return _barriers;
a61af66fc99e Initial load
duke
parents:
diff changeset
432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
433 void increment_barriers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
434 _barriers += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
435 }
a61af66fc99e Initial load
duke
parents:
diff changeset
436 void reset_barriers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
437 _barriers = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // Count of how many times the queue has emptied.
a61af66fc99e Initial load
duke
parents:
diff changeset
440 uint emptied_queue() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
441 return _emptied_queue;
a61af66fc99e Initial load
duke
parents:
diff changeset
442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
443 void increment_emptied_queue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
444 _emptied_queue += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
446 void reset_emptied_queue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
447 _emptied_queue = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
449 // Count of the number of noop tasks we've handed out,
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // e.g., to handle resource release requests.
a61af66fc99e Initial load
duke
parents:
diff changeset
451 uint noop_tasks() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
452 return _noop_tasks;
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454 void increment_noop_tasks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
455 _noop_tasks += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
457 void reset_noop_tasks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 _noop_tasks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // Other methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
461 void initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
462 };
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 //
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // Some exemplary GCTasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
466 //
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // A noop task that does nothing,
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // except take us around the GCTaskThread loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
470 class NoopGCTask : public GCTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
471 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
472 const bool _is_c_heap_obj; // Is this a CHeapObj?
a61af66fc99e Initial load
duke
parents:
diff changeset
473 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
475 static NoopGCTask* create();
a61af66fc99e Initial load
duke
parents:
diff changeset
476 static NoopGCTask* create_on_c_heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
477 static void destroy(NoopGCTask* that);
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // Methods from GCTask.
a61af66fc99e Initial load
duke
parents:
diff changeset
479 void do_it(GCTaskManager* manager, uint which) {
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // Constructor.
a61af66fc99e Initial load
duke
parents:
diff changeset
484 NoopGCTask(bool on_c_heap) :
a61af66fc99e Initial load
duke
parents:
diff changeset
485 GCTask(GCTask::Kind::noop_task),
a61af66fc99e Initial load
duke
parents:
diff changeset
486 _is_c_heap_obj(on_c_heap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
487 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
489 // Destructor-like method.
a61af66fc99e Initial load
duke
parents:
diff changeset
490 void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
492 bool is_c_heap_obj() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
493 return _is_c_heap_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
495 };
a61af66fc99e Initial load
duke
parents:
diff changeset
496
a61af66fc99e Initial load
duke
parents:
diff changeset
497 // A BarrierGCTask blocks other tasks from starting,
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // and waits until it is the only task running.
a61af66fc99e Initial load
duke
parents:
diff changeset
499 class BarrierGCTask : public GCTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
502 static BarrierGCTask* create() {
a61af66fc99e Initial load
duke
parents:
diff changeset
503 return new BarrierGCTask();
a61af66fc99e Initial load
duke
parents:
diff changeset
504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
505 static void destroy(BarrierGCTask* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
506 if (that != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
507 that->destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
508 delete that;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // Methods from GCTask.
a61af66fc99e Initial load
duke
parents:
diff changeset
512 void do_it(GCTaskManager* manager, uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
513 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // Constructor. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
515 BarrierGCTask() :
a61af66fc99e Initial load
duke
parents:
diff changeset
516 GCTask(GCTask::Kind::barrier_task) {
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // Destructor-like method.
a61af66fc99e Initial load
duke
parents:
diff changeset
520 void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // Methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // Wait for this to be the only task running.
a61af66fc99e Initial load
duke
parents:
diff changeset
523 void do_it_internal(GCTaskManager* manager, uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
524 };
a61af66fc99e Initial load
duke
parents:
diff changeset
525
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // A ReleasingBarrierGCTask is a BarrierGCTask
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // that tells all the tasks to release their resource areas.
a61af66fc99e Initial load
duke
parents:
diff changeset
528 class ReleasingBarrierGCTask : public BarrierGCTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
529 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
530 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
531 static ReleasingBarrierGCTask* create() {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 return new ReleasingBarrierGCTask();
a61af66fc99e Initial load
duke
parents:
diff changeset
533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
534 static void destroy(ReleasingBarrierGCTask* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
535 if (that != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
536 that->destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
537 delete that;
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // Methods from GCTask.
a61af66fc99e Initial load
duke
parents:
diff changeset
541 void do_it(GCTaskManager* manager, uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
542 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // Constructor. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
544 ReleasingBarrierGCTask() :
a61af66fc99e Initial load
duke
parents:
diff changeset
545 BarrierGCTask() {
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // Destructor-like method.
a61af66fc99e Initial load
duke
parents:
diff changeset
549 void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
550 };
a61af66fc99e Initial load
duke
parents:
diff changeset
551
a61af66fc99e Initial load
duke
parents:
diff changeset
552 // A NotifyingBarrierGCTask is a BarrierGCTask
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // that calls a notification method when it is the only task running.
a61af66fc99e Initial load
duke
parents:
diff changeset
554 class NotifyingBarrierGCTask : public BarrierGCTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
555 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // Instance state.
a61af66fc99e Initial load
duke
parents:
diff changeset
557 NotifyDoneClosure* _ndc; // The callback object.
a61af66fc99e Initial load
duke
parents:
diff changeset
558 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
560 static NotifyingBarrierGCTask* create(NotifyDoneClosure* ndc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
561 return new NotifyingBarrierGCTask(ndc);
a61af66fc99e Initial load
duke
parents:
diff changeset
562 }
a61af66fc99e Initial load
duke
parents:
diff changeset
563 static void destroy(NotifyingBarrierGCTask* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
564 if (that != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
565 that->destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
566 delete that;
a61af66fc99e Initial load
duke
parents:
diff changeset
567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // Methods from GCTask.
a61af66fc99e Initial load
duke
parents:
diff changeset
570 void do_it(GCTaskManager* manager, uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
571 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // Constructor. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
573 NotifyingBarrierGCTask(NotifyDoneClosure* ndc) :
a61af66fc99e Initial load
duke
parents:
diff changeset
574 BarrierGCTask(),
a61af66fc99e Initial load
duke
parents:
diff changeset
575 _ndc(ndc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
576 assert(notify_done_closure() != NULL, "can't notify on NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
578 // Destructor-like method.
a61af66fc99e Initial load
duke
parents:
diff changeset
579 void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
580 // Accessor.
a61af66fc99e Initial load
duke
parents:
diff changeset
581 NotifyDoneClosure* notify_done_closure() const { return _ndc; }
a61af66fc99e Initial load
duke
parents:
diff changeset
582 };
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // A WaitForBarrierGCTask is a BarrierGCTask
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // with a method you can call to wait until
a61af66fc99e Initial load
duke
parents:
diff changeset
586 // the BarrierGCTask is done.
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // This may cover many of the uses of NotifyingBarrierGCTasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
588 class WaitForBarrierGCTask : public BarrierGCTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
589 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // Instance state.
a61af66fc99e Initial load
duke
parents:
diff changeset
591 Monitor* _monitor; // Guard and notify changes.
a61af66fc99e Initial load
duke
parents:
diff changeset
592 bool _should_wait; // true=>wait, false=>proceed.
a61af66fc99e Initial load
duke
parents:
diff changeset
593 const bool _is_c_heap_obj; // Was allocated on the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
594 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
595 virtual char* name() { return (char *) "waitfor-barrier-task"; }
a61af66fc99e Initial load
duke
parents:
diff changeset
596
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
598 static WaitForBarrierGCTask* create();
a61af66fc99e Initial load
duke
parents:
diff changeset
599 static WaitForBarrierGCTask* create_on_c_heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
600 static void destroy(WaitForBarrierGCTask* that);
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // Methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
602 void do_it(GCTaskManager* manager, uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
603 void wait_for();
a61af66fc99e Initial load
duke
parents:
diff changeset
604 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // Constructor. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
606 WaitForBarrierGCTask(bool on_c_heap);
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // Destructor-like method.
a61af66fc99e Initial load
duke
parents:
diff changeset
608 void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
610 Monitor* monitor() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 return _monitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
613 bool should_wait() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
614 return _should_wait;
a61af66fc99e Initial load
duke
parents:
diff changeset
615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
616 void set_should_wait(bool value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
617 _should_wait = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
619 bool is_c_heap_obj() {
a61af66fc99e Initial load
duke
parents:
diff changeset
620 return _is_c_heap_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
622 };
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 class MonitorSupply : public AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
625 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // State.
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // Control multi-threaded access.
a61af66fc99e Initial load
duke
parents:
diff changeset
628 static Mutex* _lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // The list of available Monitor*'s.
a61af66fc99e Initial load
duke
parents:
diff changeset
630 static GrowableArray<Monitor*>* _freelist;
a61af66fc99e Initial load
duke
parents:
diff changeset
631 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // Reserve a Monitor*.
a61af66fc99e Initial load
duke
parents:
diff changeset
633 static Monitor* reserve();
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // Release a Monitor*.
a61af66fc99e Initial load
duke
parents:
diff changeset
635 static void release(Monitor* instance);
a61af66fc99e Initial load
duke
parents:
diff changeset
636 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
638 static Mutex* lock() {
a61af66fc99e Initial load
duke
parents:
diff changeset
639 return _lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
640 }
a61af66fc99e Initial load
duke
parents:
diff changeset
641 static GrowableArray<Monitor*>* freelist() {
a61af66fc99e Initial load
duke
parents:
diff changeset
642 return _freelist;
a61af66fc99e Initial load
duke
parents:
diff changeset
643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
644 };
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
645
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
646 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GCTASKMANAGER_HPP