annotate src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp @ 8733:9def4075da6d

8008079: G1: Add nextObject routine to CMBitMapRO and replace nextWord Summary: Update the task local finger to the start of the next object when marking aborts, in order to avoid the redundant scanning of all 0's when the marking task restarts, if otherwise updating to the next word. In addition, reuse the routine nextObject() in routine iterate(). Reviewed-by: johnc, ysr Contributed-by: tamao <tao.mao@oracle.com>
author tamao
date Tue, 05 Mar 2013 15:36:56 -0800
parents b9a9ed0f8eeb
children 63a4eb8bcd23
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
6842
b9a9ed0f8eeb 7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents: 6197
diff changeset
2 * Copyright (c) 2002, 2012, 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;
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
48 class IdleGCTask;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // A free list of Monitor*'s.
a61af66fc99e Initial load
duke
parents:
diff changeset
50 class MonitorSupply;
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // Forward declarations of classes referenced in this file via pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
53 class GCTaskThread;
a61af66fc99e Initial load
duke
parents:
diff changeset
54 class Mutex;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 class Monitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
56 class ThreadClosure;
a61af66fc99e Initial load
duke
parents:
diff changeset
57
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // The abstract base GCTask.
a61af66fc99e Initial load
duke
parents:
diff changeset
59 class GCTask : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // Known kinds of GCTasks, for predicates.
a61af66fc99e Initial load
duke
parents:
diff changeset
62 class Kind : AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
63 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
64 enum kind {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 unknown_task,
a61af66fc99e Initial load
duke
parents:
diff changeset
66 ordinary_task,
a61af66fc99e Initial load
duke
parents:
diff changeset
67 barrier_task,
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
68 noop_task,
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
69 idle_task
0
a61af66fc99e Initial load
duke
parents:
diff changeset
70 };
a61af66fc99e Initial load
duke
parents:
diff changeset
71 static const char* to_string(kind value);
a61af66fc99e Initial load
duke
parents:
diff changeset
72 };
a61af66fc99e Initial load
duke
parents:
diff changeset
73 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // Instance state.
a61af66fc99e Initial load
duke
parents:
diff changeset
75 const Kind::kind _kind; // For runtime type checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
76 const uint _affinity; // Which worker should run task.
a61af66fc99e Initial load
duke
parents:
diff changeset
77 GCTask* _newer; // Tasks are on doubly-linked ...
a61af66fc99e Initial load
duke
parents:
diff changeset
78 GCTask* _older; // ... lists.
a61af66fc99e Initial load
duke
parents:
diff changeset
79 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
80 virtual char* name() { return (char *)"task"; }
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // Abstract do_it method
a61af66fc99e Initial load
duke
parents:
diff changeset
83 virtual void do_it(GCTaskManager* manager, uint which) = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
85 Kind::kind kind() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
86 return _kind;
a61af66fc99e Initial load
duke
parents:
diff changeset
87 }
a61af66fc99e Initial load
duke
parents:
diff changeset
88 uint affinity() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 return _affinity;
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91 GCTask* newer() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
92 return _newer;
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94 void set_newer(GCTask* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 _newer = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
96 }
a61af66fc99e Initial load
duke
parents:
diff changeset
97 GCTask* older() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 return _older;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 }
a61af66fc99e Initial load
duke
parents:
diff changeset
100 void set_older(GCTask* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
101 _older = p;
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // Predicates.
a61af66fc99e Initial load
duke
parents:
diff changeset
104 bool is_ordinary_task() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 return kind()==Kind::ordinary_task;
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107 bool is_barrier_task() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 return kind()==Kind::barrier_task;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110 bool is_noop_task() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 return kind()==Kind::noop_task;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 }
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
113 bool is_idle_task() const {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
114 return kind()==Kind::idle_task;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
115 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
116 void print(const char* message) const PRODUCT_RETURN;
a61af66fc99e Initial load
duke
parents:
diff changeset
117 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // Constructors: Only create subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // An ordinary GCTask.
a61af66fc99e Initial load
duke
parents:
diff changeset
120 GCTask();
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // A GCTask of a particular kind, usually barrier or noop.
a61af66fc99e Initial load
duke
parents:
diff changeset
122 GCTask(Kind::kind kind);
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // An ordinary GCTask with an affinity.
a61af66fc99e Initial load
duke
parents:
diff changeset
124 GCTask(uint affinity);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // A GCTask of a particular kind, with and affinity.
a61af66fc99e Initial load
duke
parents:
diff changeset
126 GCTask(Kind::kind kind, uint affinity);
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // We want a virtual destructor because virtual methods,
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // but since ResourceObj's don't have their destructors
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // called, we don't have one at all. Instead we have
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // this method, which gets called by subclasses to clean up.
a61af66fc99e Initial load
duke
parents:
diff changeset
131 virtual void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // Methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
133 void initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
134 };
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // A doubly-linked list of GCTasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // The list is not synchronized, because sometimes we want to
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // build up a list and then make it available to other threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // See also: SynchronizedGCTaskQueue.
a61af66fc99e Initial load
duke
parents:
diff changeset
140 class GCTaskQueue : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // Instance state.
a61af66fc99e Initial load
duke
parents:
diff changeset
143 GCTask* _insert_end; // Tasks are enqueued at this end.
a61af66fc99e Initial load
duke
parents:
diff changeset
144 GCTask* _remove_end; // Tasks are dequeued from this end.
a61af66fc99e Initial load
duke
parents:
diff changeset
145 uint _length; // The current length of the queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
146 const bool _is_c_heap_obj; // Is this a CHeapObj?
a61af66fc99e Initial load
duke
parents:
diff changeset
147 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // Create as ResourceObj.
a61af66fc99e Initial load
duke
parents:
diff changeset
150 static GCTaskQueue* create();
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Create as CHeapObj.
a61af66fc99e Initial load
duke
parents:
diff changeset
152 static GCTaskQueue* create_on_c_heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // Destroyer.
a61af66fc99e Initial load
duke
parents:
diff changeset
154 static void destroy(GCTaskQueue* that);
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // These just examine the state of the queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
157 bool is_empty() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 assert(((insert_end() == NULL && remove_end() == NULL) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
159 (insert_end() != NULL && remove_end() != NULL)),
a61af66fc99e Initial load
duke
parents:
diff changeset
160 "insert_end and remove_end don't match");
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
161 assert((insert_end() != NULL) || (_length == 0), "Not empty");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
162 return insert_end() == NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
164 uint length() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 return _length;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // Methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // Enqueue one task.
a61af66fc99e Initial load
duke
parents:
diff changeset
169 void enqueue(GCTask* task);
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // Enqueue a list of tasks. Empties the argument list.
a61af66fc99e Initial load
duke
parents:
diff changeset
171 void enqueue(GCTaskQueue* list);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // Dequeue one task.
a61af66fc99e Initial load
duke
parents:
diff changeset
173 GCTask* dequeue();
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // Dequeue one task, preferring one with affinity.
a61af66fc99e Initial load
duke
parents:
diff changeset
175 GCTask* dequeue(uint affinity);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // Constructor. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
178 GCTaskQueue(bool on_c_heap);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // Destructor-like method.
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // Because ResourceMark doesn't call destructors.
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // This method cleans up like one.
a61af66fc99e Initial load
duke
parents:
diff changeset
182 virtual void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
184 GCTask* insert_end() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 return _insert_end;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187 void set_insert_end(GCTask* value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 _insert_end = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190 GCTask* remove_end() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 return _remove_end;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193 void set_remove_end(GCTask* value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
194 _remove_end = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196 void increment_length() {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 _length += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199 void decrement_length() {
a61af66fc99e Initial load
duke
parents:
diff changeset
200 _length -= 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202 void set_length(uint value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
203 _length = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205 bool is_c_heap_obj() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 return _is_c_heap_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // Methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
209 void initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
210 GCTask* remove(); // Remove from remove end.
a61af66fc99e Initial load
duke
parents:
diff changeset
211 GCTask* remove(GCTask* task); // Remove from the middle.
a61af66fc99e Initial load
duke
parents:
diff changeset
212 void print(const char* message) const PRODUCT_RETURN;
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
213 // Debug support
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
214 void verify_length() const PRODUCT_RETURN;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
215 };
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // A GCTaskQueue that can be synchronized.
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // This "has-a" GCTaskQueue and a mutex to do the exclusion.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 4095
diff changeset
219 class SynchronizedGCTaskQueue : public CHeapObj<mtGC> {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
220 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // Instance state.
a61af66fc99e Initial load
duke
parents:
diff changeset
222 GCTaskQueue* _unsynchronized_queue; // Has-a unsynchronized queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
223 Monitor * _lock; // Lock to control access.
a61af66fc99e Initial load
duke
parents:
diff changeset
224 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
226 static SynchronizedGCTaskQueue* create(GCTaskQueue* queue, Monitor * lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 return new SynchronizedGCTaskQueue(queue, lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
229 static void destroy(SynchronizedGCTaskQueue* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 if (that != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
231 delete that;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
235 GCTaskQueue* unsynchronized_queue() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 return _unsynchronized_queue;
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238 Monitor * lock() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 return _lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // GCTaskQueue wrapper methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // These check that you hold the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // and then call the method on the queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
244 bool is_empty() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 guarantee(own_lock(), "don't own the lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
246 return unsynchronized_queue()->is_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248 void enqueue(GCTask* task) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 guarantee(own_lock(), "don't own the lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
250 unsynchronized_queue()->enqueue(task);
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252 void enqueue(GCTaskQueue* list) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 guarantee(own_lock(), "don't own the lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
254 unsynchronized_queue()->enqueue(list);
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256 GCTask* dequeue() {
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()->dequeue();
a61af66fc99e Initial load
duke
parents:
diff changeset
259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
260 GCTask* dequeue(uint affinity) {
a61af66fc99e Initial load
duke
parents:
diff changeset
261 guarantee(own_lock(), "don't own the lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
262 return unsynchronized_queue()->dequeue(affinity);
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264 uint length() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 guarantee(own_lock(), "don't own the lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
266 return unsynchronized_queue()->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // For guarantees.
a61af66fc99e Initial load
duke
parents:
diff changeset
269 bool own_lock() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
270 return lock()->owned_by_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
272 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
273 // Constructor. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
274 SynchronizedGCTaskQueue(GCTaskQueue* queue, Monitor * lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
275 // Destructor. Not virtual because no virtuals.
a61af66fc99e Initial load
duke
parents:
diff changeset
276 ~SynchronizedGCTaskQueue();
a61af66fc99e Initial load
duke
parents:
diff changeset
277 };
a61af66fc99e Initial load
duke
parents:
diff changeset
278
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // This is an abstract base class for getting notifications
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // when a GCTaskManager is done.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 4095
diff changeset
281 class NotifyDoneClosure : public CHeapObj<mtGC> {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
282 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // The notification callback method.
a61af66fc99e Initial load
duke
parents:
diff changeset
284 virtual void notify(GCTaskManager* manager) = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
285 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
286 // Constructor.
a61af66fc99e Initial load
duke
parents:
diff changeset
287 NotifyDoneClosure() {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // Virtual destructor because virtual methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
291 virtual ~NotifyDoneClosure() {
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
294 };
a61af66fc99e Initial load
duke
parents:
diff changeset
295
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
296 // Dynamic number of GC threads
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
297 //
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
298 // GC threads wait in get_task() for work (i.e., a task) to perform.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
299 // When the number of GC threads was static, the number of tasks
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
300 // created to do a job was equal to or greater than the maximum
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
301 // number of GC threads (ParallelGCThreads). The job might be divided
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
302 // into a number of tasks greater than the number of GC threads for
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
303 // load balancing (i.e., over partitioning). The last task to be
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
304 // executed by a GC thread in a job is a work stealing task. A
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
305 // GC thread that gets a work stealing task continues to execute
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
306 // that task until the job is done. In the static number of GC theads
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
307 // case, tasks are added to a queue (FIFO). The work stealing tasks are
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
308 // the last to be added. Once the tasks are added, the GC threads grab
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
309 // a task and go. A single thread can do all the non-work stealing tasks
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
310 // and then execute a work stealing and wait for all the other GC threads
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
311 // to execute their work stealing task.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
312 // In the dynamic number of GC threads implementation, idle-tasks are
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
313 // created to occupy the non-participating or "inactive" threads. An
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
314 // idle-task makes the GC thread wait on a barrier that is part of the
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
315 // GCTaskManager. The GC threads that have been "idled" in a IdleGCTask
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
316 // are released once all the active GC threads have finished their work
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
317 // stealing tasks. The GCTaskManager does not wait for all the "idled"
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
318 // GC threads to resume execution. When those GC threads do resume
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
319 // execution in the course of the thread scheduling, they call get_tasks()
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
320 // as all the other GC threads do. Because all the "idled" threads are
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
321 // not required to execute in order to finish a job, it is possible for
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
322 // a GC thread to still be "idled" when the next job is started. Such
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
323 // a thread stays "idled" for the next job. This can result in a new
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
324 // job not having all the expected active workers. For example if on
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
325 // job requests 4 active workers out of a total of 10 workers so the
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
326 // remaining 6 are "idled", if the next job requests 6 active workers
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
327 // but all 6 of the "idled" workers are still idle, then the next job
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
328 // will only get 4 active workers.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
329 // The implementation for the parallel old compaction phase has an
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
330 // added complication. In the static case parold partitions the chunks
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
331 // ready to be filled into stacks, one for each GC thread. A GC thread
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
332 // executing a draining task (drains the stack of ready chunks)
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
333 // claims a stack according to it's id (the unique ordinal value assigned
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
334 // to each GC thread). In the dynamic case not all GC threads will
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
335 // actively participate so stacks with ready to fill chunks can only be
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
336 // given to the active threads. An initial implementation chose stacks
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
337 // number 1-n to get the ready chunks and required that GC threads
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
338 // 1-n be the active workers. This was undesirable because it required
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
339 // certain threads to participate. In the final implementation a
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
340 // list of stacks equal in number to the active workers are filled
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
341 // with ready chunks. GC threads that participate get a stack from
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
342 // the task (DrainStacksCompactionTask), empty the stack, and then add it to a
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
343 // recycling list at the end of the task. If the same GC thread gets
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
344 // a second task, it gets a second stack to drain and returns it. The
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
345 // stacks are added to a recycling list so that later stealing tasks
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
346 // for this tasks can get a stack from the recycling list. Stealing tasks
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
347 // use the stacks in its work in a way similar to the draining tasks.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
348 // A thread is not guaranteed to get anything but a stealing task and
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
349 // a thread that only gets a stealing task has to get a stack. A failed
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
350 // implementation tried to have the GC threads keep the stack they used
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
351 // during a draining task for later use in the stealing task but that didn't
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
352 // work because as noted a thread is not guaranteed to get a draining task.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
353 //
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
354 // For PSScavenge and ParCompactionManager the GC threads are
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
355 // held in the GCTaskThread** _thread array in GCTaskManager.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
356
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
357
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 4095
diff changeset
358 class GCTaskManager : public CHeapObj<mtGC> {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
359 friend class ParCompactionManager;
a61af66fc99e Initial load
duke
parents:
diff changeset
360 friend class PSParallelCompact;
a61af66fc99e Initial load
duke
parents:
diff changeset
361 friend class PSScavenge;
a61af66fc99e Initial load
duke
parents:
diff changeset
362 friend class PSRefProcTaskExecutor;
a61af66fc99e Initial load
duke
parents:
diff changeset
363 friend class RefProcTaskExecutor;
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
364 friend class GCTaskThread;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
365 friend class IdleGCTask;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
366 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // Instance state.
a61af66fc99e Initial load
duke
parents:
diff changeset
368 NotifyDoneClosure* _ndc; // Notify on completion.
a61af66fc99e Initial load
duke
parents:
diff changeset
369 const uint _workers; // Number of workers.
a61af66fc99e Initial load
duke
parents:
diff changeset
370 Monitor* _monitor; // Notification of changes.
a61af66fc99e Initial load
duke
parents:
diff changeset
371 SynchronizedGCTaskQueue* _queue; // Queue of tasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
372 GCTaskThread** _thread; // Array of worker threads.
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
373 uint _active_workers; // Number of active workers.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
374 uint _busy_workers; // Number of busy workers.
a61af66fc99e Initial load
duke
parents:
diff changeset
375 uint _blocking_worker; // The worker that's blocking.
a61af66fc99e Initial load
duke
parents:
diff changeset
376 bool* _resource_flag; // Array of flag per threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
377 uint _delivered_tasks; // Count of delivered tasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
378 uint _completed_tasks; // Count of completed tasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
379 uint _barriers; // Count of barrier tasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
380 uint _emptied_queue; // Times we emptied the queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
381 NoopGCTask* _noop_task; // The NoopGCTask instance.
a61af66fc99e Initial load
duke
parents:
diff changeset
382 uint _noop_tasks; // Count of noop tasks.
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
383 WaitForBarrierGCTask* _idle_inactive_task;// Task for inactive workers
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
384 volatile uint _idle_workers; // Number of idled workers
0
a61af66fc99e Initial load
duke
parents:
diff changeset
385 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
387 static GCTaskManager* create(uint workers) {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 return new GCTaskManager(workers);
a61af66fc99e Initial load
duke
parents:
diff changeset
389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
390 static GCTaskManager* create(uint workers, NotifyDoneClosure* ndc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 return new GCTaskManager(workers, ndc);
a61af66fc99e Initial load
duke
parents:
diff changeset
392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
393 static void destroy(GCTaskManager* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 if (that != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
395 delete that;
a61af66fc99e Initial load
duke
parents:
diff changeset
396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
399 uint busy_workers() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
400 return _busy_workers;
a61af66fc99e Initial load
duke
parents:
diff changeset
401 }
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
402 volatile uint idle_workers() const {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
403 return _idle_workers;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
404 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // Pun between Monitor* and Mutex*
a61af66fc99e Initial load
duke
parents:
diff changeset
406 Monitor* monitor() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 return _monitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
409 Monitor * lock() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
410 return _monitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
411 }
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
412 WaitForBarrierGCTask* idle_inactive_task() {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
413 return _idle_inactive_task;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
414 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // Methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // Add the argument task to be run.
a61af66fc99e Initial load
duke
parents:
diff changeset
417 void add_task(GCTask* task);
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // Add a list of tasks. Removes task from the argument list.
a61af66fc99e Initial load
duke
parents:
diff changeset
419 void add_list(GCTaskQueue* list);
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // Claim a task for argument worker.
a61af66fc99e Initial load
duke
parents:
diff changeset
421 GCTask* get_task(uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // Note the completion of a task by the argument worker.
a61af66fc99e Initial load
duke
parents:
diff changeset
423 void note_completion(uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // Is the queue blocked from handing out new tasks?
a61af66fc99e Initial load
duke
parents:
diff changeset
425 bool is_blocked() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
426 return (blocking_worker() != sentinel_worker());
a61af66fc99e Initial load
duke
parents:
diff changeset
427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // Request that all workers release their resources.
a61af66fc99e Initial load
duke
parents:
diff changeset
429 void release_all_resources();
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // Ask if a particular worker should release its resources.
a61af66fc99e Initial load
duke
parents:
diff changeset
431 bool should_release_resources(uint which); // Predicate.
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // Note the release of resources by the argument worker.
a61af66fc99e Initial load
duke
parents:
diff changeset
433 void note_release(uint which);
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
434 // Create IdleGCTasks for inactive workers and start workers
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
435 void task_idle_workers();
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
436 // Release the workers in IdleGCTasks
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
437 void release_idle_workers();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
438 // Constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // A sentinel worker identifier.
a61af66fc99e Initial load
duke
parents:
diff changeset
440 static uint sentinel_worker() {
a61af66fc99e Initial load
duke
parents:
diff changeset
441 return (uint) -1; // Why isn't there a max_uint?
a61af66fc99e Initial load
duke
parents:
diff changeset
442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // Execute the task queue and wait for the completion.
a61af66fc99e Initial load
duke
parents:
diff changeset
445 void execute_and_wait(GCTaskQueue* list);
a61af66fc99e Initial load
duke
parents:
diff changeset
446
a61af66fc99e Initial load
duke
parents:
diff changeset
447 void print_task_time_stamps();
a61af66fc99e Initial load
duke
parents:
diff changeset
448 void print_threads_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
449 void threads_do(ThreadClosure* tc);
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // Constructors. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
453 // Create a GCTaskManager with the appropriate number of workers.
a61af66fc99e Initial load
duke
parents:
diff changeset
454 GCTaskManager(uint workers);
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // Create a GCTaskManager that calls back when there's no more work.
a61af66fc99e Initial load
duke
parents:
diff changeset
456 GCTaskManager(uint workers, NotifyDoneClosure* ndc);
a61af66fc99e Initial load
duke
parents:
diff changeset
457 // Make virtual if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
458 ~GCTaskManager();
a61af66fc99e Initial load
duke
parents:
diff changeset
459 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
460 uint workers() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
461 return _workers;
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
463 void set_active_workers(uint v) {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
464 assert(v <= _workers, "Trying to set more workers active than there are");
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
465 _active_workers = MIN2(v, _workers);
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
466 assert(v != 0, "Trying to set active workers to 0");
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
467 _active_workers = MAX2(1U, _active_workers);
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
468 }
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
469 // Sets the number of threads that will be used in a collection
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
470 void set_active_gang();
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
471
0
a61af66fc99e Initial load
duke
parents:
diff changeset
472 NotifyDoneClosure* notify_done_closure() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
473 return _ndc;
a61af66fc99e Initial load
duke
parents:
diff changeset
474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
475 SynchronizedGCTaskQueue* queue() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 return _queue;
a61af66fc99e Initial load
duke
parents:
diff changeset
477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
478 NoopGCTask* noop_task() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
479 return _noop_task;
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // Bounds-checking per-thread data accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
482 GCTaskThread* thread(uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
483 void set_thread(uint which, GCTaskThread* value);
a61af66fc99e Initial load
duke
parents:
diff changeset
484 bool resource_flag(uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
485 void set_resource_flag(uint which, bool value);
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // Modifier methods with some semantics.
a61af66fc99e Initial load
duke
parents:
diff changeset
487 // Is any worker blocking handing out new tasks?
a61af66fc99e Initial load
duke
parents:
diff changeset
488 uint blocking_worker() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
489 return _blocking_worker;
a61af66fc99e Initial load
duke
parents:
diff changeset
490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
491 void set_blocking_worker(uint value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
492 _blocking_worker = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
494 void set_unblocked() {
a61af66fc99e Initial load
duke
parents:
diff changeset
495 set_blocking_worker(sentinel_worker());
a61af66fc99e Initial load
duke
parents:
diff changeset
496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
497 // Count of busy workers.
a61af66fc99e Initial load
duke
parents:
diff changeset
498 void reset_busy_workers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
499 _busy_workers = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
501 uint increment_busy_workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
502 uint decrement_busy_workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // Count of tasks delivered to workers.
a61af66fc99e Initial load
duke
parents:
diff changeset
504 uint delivered_tasks() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
505 return _delivered_tasks;
a61af66fc99e Initial load
duke
parents:
diff changeset
506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
507 void increment_delivered_tasks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
508 _delivered_tasks += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510 void reset_delivered_tasks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
511 _delivered_tasks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // Count of tasks completed by workers.
a61af66fc99e Initial load
duke
parents:
diff changeset
514 uint completed_tasks() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 return _completed_tasks;
a61af66fc99e Initial load
duke
parents:
diff changeset
516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
517 void increment_completed_tasks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
518 _completed_tasks += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
520 void reset_completed_tasks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
521 _completed_tasks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // Count of barrier tasks completed.
a61af66fc99e Initial load
duke
parents:
diff changeset
524 uint barriers() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
525 return _barriers;
a61af66fc99e Initial load
duke
parents:
diff changeset
526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
527 void increment_barriers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
528 _barriers += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
530 void reset_barriers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 _barriers = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
533 // Count of how many times the queue has emptied.
a61af66fc99e Initial load
duke
parents:
diff changeset
534 uint emptied_queue() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
535 return _emptied_queue;
a61af66fc99e Initial load
duke
parents:
diff changeset
536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
537 void increment_emptied_queue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
538 _emptied_queue += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
540 void reset_emptied_queue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 _emptied_queue = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // Count of the number of noop tasks we've handed out,
a61af66fc99e Initial load
duke
parents:
diff changeset
544 // e.g., to handle resource release requests.
a61af66fc99e Initial load
duke
parents:
diff changeset
545 uint noop_tasks() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
546 return _noop_tasks;
a61af66fc99e Initial load
duke
parents:
diff changeset
547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
548 void increment_noop_tasks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
549 _noop_tasks += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
551 void reset_noop_tasks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
552 _noop_tasks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
553 }
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
554 void increment_idle_workers() {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
555 _idle_workers++;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
556 }
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
557 void decrement_idle_workers() {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
558 _idle_workers--;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
559 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // Other methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
561 void initialize();
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
562
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
563 public:
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
564 // Return true if all workers are currently active.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
565 bool all_workers_active() { return workers() == active_workers(); }
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
566 uint active_workers() const {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
567 return _active_workers;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
568 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
569 };
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 //
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // Some exemplary GCTasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
573 //
a61af66fc99e Initial load
duke
parents:
diff changeset
574
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // A noop task that does nothing,
a61af66fc99e Initial load
duke
parents:
diff changeset
576 // except take us around the GCTaskThread loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
577 class NoopGCTask : public GCTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
578 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
579 const bool _is_c_heap_obj; // Is this a CHeapObj?
a61af66fc99e Initial load
duke
parents:
diff changeset
580 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
581 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
582 static NoopGCTask* create();
a61af66fc99e Initial load
duke
parents:
diff changeset
583 static NoopGCTask* create_on_c_heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
584 static void destroy(NoopGCTask* that);
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
585
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
586 virtual char* name() { return (char *)"noop task"; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // Methods from GCTask.
a61af66fc99e Initial load
duke
parents:
diff changeset
588 void do_it(GCTaskManager* manager, uint which) {
a61af66fc99e Initial load
duke
parents:
diff changeset
589 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
591 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // Constructor.
a61af66fc99e Initial load
duke
parents:
diff changeset
593 NoopGCTask(bool on_c_heap) :
a61af66fc99e Initial load
duke
parents:
diff changeset
594 GCTask(GCTask::Kind::noop_task),
a61af66fc99e Initial load
duke
parents:
diff changeset
595 _is_c_heap_obj(on_c_heap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
596 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // Destructor-like method.
a61af66fc99e Initial load
duke
parents:
diff changeset
599 void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
601 bool is_c_heap_obj() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
602 return _is_c_heap_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
604 };
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // A BarrierGCTask blocks other tasks from starting,
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // and waits until it is the only task running.
a61af66fc99e Initial load
duke
parents:
diff changeset
608 class BarrierGCTask : public GCTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
609 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
611 static BarrierGCTask* create() {
a61af66fc99e Initial load
duke
parents:
diff changeset
612 return new BarrierGCTask();
a61af66fc99e Initial load
duke
parents:
diff changeset
613 }
a61af66fc99e Initial load
duke
parents:
diff changeset
614 static void destroy(BarrierGCTask* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
615 if (that != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
616 that->destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
617 delete that;
a61af66fc99e Initial load
duke
parents:
diff changeset
618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // Methods from GCTask.
a61af66fc99e Initial load
duke
parents:
diff changeset
621 void do_it(GCTaskManager* manager, uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
622 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // Constructor. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
624 BarrierGCTask() :
a61af66fc99e Initial load
duke
parents:
diff changeset
625 GCTask(GCTask::Kind::barrier_task) {
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // Destructor-like method.
a61af66fc99e Initial load
duke
parents:
diff changeset
629 void destruct();
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
630
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
631 virtual char* name() { return (char *)"barrier task"; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // Methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // Wait for this to be the only task running.
a61af66fc99e Initial load
duke
parents:
diff changeset
634 void do_it_internal(GCTaskManager* manager, uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
635 };
a61af66fc99e Initial load
duke
parents:
diff changeset
636
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // A ReleasingBarrierGCTask is a BarrierGCTask
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // that tells all the tasks to release their resource areas.
a61af66fc99e Initial load
duke
parents:
diff changeset
639 class ReleasingBarrierGCTask : public BarrierGCTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
640 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
642 static ReleasingBarrierGCTask* create() {
a61af66fc99e Initial load
duke
parents:
diff changeset
643 return new ReleasingBarrierGCTask();
a61af66fc99e Initial load
duke
parents:
diff changeset
644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
645 static void destroy(ReleasingBarrierGCTask* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
646 if (that != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
647 that->destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
648 delete that;
a61af66fc99e Initial load
duke
parents:
diff changeset
649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
650 }
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // Methods from GCTask.
a61af66fc99e Initial load
duke
parents:
diff changeset
652 void do_it(GCTaskManager* manager, uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
653 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // Constructor. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
655 ReleasingBarrierGCTask() :
a61af66fc99e Initial load
duke
parents:
diff changeset
656 BarrierGCTask() {
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
658 }
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // Destructor-like method.
a61af66fc99e Initial load
duke
parents:
diff changeset
660 void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
661 };
a61af66fc99e Initial load
duke
parents:
diff changeset
662
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // A NotifyingBarrierGCTask is a BarrierGCTask
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // that calls a notification method when it is the only task running.
a61af66fc99e Initial load
duke
parents:
diff changeset
665 class NotifyingBarrierGCTask : public BarrierGCTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
666 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // Instance state.
a61af66fc99e Initial load
duke
parents:
diff changeset
668 NotifyDoneClosure* _ndc; // The callback object.
a61af66fc99e Initial load
duke
parents:
diff changeset
669 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
671 static NotifyingBarrierGCTask* create(NotifyDoneClosure* ndc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
672 return new NotifyingBarrierGCTask(ndc);
a61af66fc99e Initial load
duke
parents:
diff changeset
673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
674 static void destroy(NotifyingBarrierGCTask* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
675 if (that != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
676 that->destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
677 delete that;
a61af66fc99e Initial load
duke
parents:
diff changeset
678 }
a61af66fc99e Initial load
duke
parents:
diff changeset
679 }
a61af66fc99e Initial load
duke
parents:
diff changeset
680 // Methods from GCTask.
a61af66fc99e Initial load
duke
parents:
diff changeset
681 void do_it(GCTaskManager* manager, uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
682 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
683 // Constructor. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
684 NotifyingBarrierGCTask(NotifyDoneClosure* ndc) :
a61af66fc99e Initial load
duke
parents:
diff changeset
685 BarrierGCTask(),
a61af66fc99e Initial load
duke
parents:
diff changeset
686 _ndc(ndc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
687 assert(notify_done_closure() != NULL, "can't notify on NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // Destructor-like method.
a61af66fc99e Initial load
duke
parents:
diff changeset
690 void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // Accessor.
a61af66fc99e Initial load
duke
parents:
diff changeset
692 NotifyDoneClosure* notify_done_closure() const { return _ndc; }
a61af66fc99e Initial load
duke
parents:
diff changeset
693 };
a61af66fc99e Initial load
duke
parents:
diff changeset
694
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // A WaitForBarrierGCTask is a BarrierGCTask
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // with a method you can call to wait until
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // the BarrierGCTask is done.
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // This may cover many of the uses of NotifyingBarrierGCTasks.
a61af66fc99e Initial load
duke
parents:
diff changeset
699 class WaitForBarrierGCTask : public BarrierGCTask {
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
700 friend class GCTaskManager;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
701 friend class IdleGCTask;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
702 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
703 // Instance state.
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
704 Monitor* _monitor; // Guard and notify changes.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
705 volatile bool _should_wait; // true=>wait, false=>proceed.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
706 const bool _is_c_heap_obj; // Was allocated on the heap.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
707 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
708 virtual char* name() { return (char *) "waitfor-barrier-task"; }
a61af66fc99e Initial load
duke
parents:
diff changeset
709
a61af66fc99e Initial load
duke
parents:
diff changeset
710 // Factory create and destroy methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
711 static WaitForBarrierGCTask* create();
a61af66fc99e Initial load
duke
parents:
diff changeset
712 static WaitForBarrierGCTask* create_on_c_heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
713 static void destroy(WaitForBarrierGCTask* that);
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // Methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
715 void do_it(GCTaskManager* manager, uint which);
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
716 void wait_for(bool reset);
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
717 void set_should_wait(bool value) {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
718 _should_wait = value;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
719 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
720 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // Constructor. Clients use factory, but there might be subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
722 WaitForBarrierGCTask(bool on_c_heap);
a61af66fc99e Initial load
duke
parents:
diff changeset
723 // Destructor-like method.
a61af66fc99e Initial load
duke
parents:
diff changeset
724 void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
725 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
726 Monitor* monitor() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 return _monitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
729 bool should_wait() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
730 return _should_wait;
a61af66fc99e Initial load
duke
parents:
diff changeset
731 }
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
732 bool is_c_heap_obj() {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
733 return _is_c_heap_obj;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
734 }
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
735 };
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
736
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
737 // Task that is used to idle a GC task when fewer than
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
738 // the maximum workers are wanted.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
739 class IdleGCTask : public GCTask {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
740 const bool _is_c_heap_obj; // Was allocated on the heap.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
741 public:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
742 bool is_c_heap_obj() {
a61af66fc99e Initial load
duke
parents:
diff changeset
743 return _is_c_heap_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
744 }
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
745 // Factory create and destroy methods.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
746 static IdleGCTask* create();
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
747 static IdleGCTask* create_on_c_heap();
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
748 static void destroy(IdleGCTask* that);
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
749
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
750 virtual char* name() { return (char *)"idle task"; }
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
751 // Methods from GCTask.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
752 virtual void do_it(GCTaskManager* manager, uint which);
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
753 protected:
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
754 // Constructor.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
755 IdleGCTask(bool on_c_heap) :
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
756 GCTask(GCTask::Kind::idle_task),
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
757 _is_c_heap_obj(on_c_heap) {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
758 // Nothing to do.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
759 }
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
760 // Destructor-like method.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 1972
diff changeset
761 void destruct();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
762 };
a61af66fc99e Initial load
duke
parents:
diff changeset
763
a61af66fc99e Initial load
duke
parents:
diff changeset
764 class MonitorSupply : public AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
765 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
766 // State.
a61af66fc99e Initial load
duke
parents:
diff changeset
767 // Control multi-threaded access.
a61af66fc99e Initial load
duke
parents:
diff changeset
768 static Mutex* _lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
769 // The list of available Monitor*'s.
a61af66fc99e Initial load
duke
parents:
diff changeset
770 static GrowableArray<Monitor*>* _freelist;
a61af66fc99e Initial load
duke
parents:
diff changeset
771 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // Reserve a Monitor*.
a61af66fc99e Initial load
duke
parents:
diff changeset
773 static Monitor* reserve();
a61af66fc99e Initial load
duke
parents:
diff changeset
774 // Release a Monitor*.
a61af66fc99e Initial load
duke
parents:
diff changeset
775 static void release(Monitor* instance);
a61af66fc99e Initial load
duke
parents:
diff changeset
776 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // Accessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
778 static Mutex* lock() {
a61af66fc99e Initial load
duke
parents:
diff changeset
779 return _lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
780 }
a61af66fc99e Initial load
duke
parents:
diff changeset
781 static GrowableArray<Monitor*>* freelist() {
a61af66fc99e Initial load
duke
parents:
diff changeset
782 return _freelist;
a61af66fc99e Initial load
duke
parents:
diff changeset
783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
784 };
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
785
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
786 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GCTASKMANAGER_HPP