Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp @ 9693:d04944441454
cleaned up and simplified runtime call mechanisms
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 14 May 2013 21:33:37 +0200 |
parents | a252e688abcf |
children | f2110083203d |
rev | line source |
---|---|
0 | 1 /* |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
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 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp" | |
28 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" | |
29 #include "memory/genCollectedHeap.hpp" | |
30 #include "oops/instanceRefKlass.hpp" | |
31 #include "oops/oop.inline.hpp" | |
32 #include "runtime/init.hpp" | |
33 #include "runtime/interfaceSupport.hpp" | |
34 #include "runtime/java.hpp" | |
35 #include "runtime/javaCalls.hpp" | |
36 #include "runtime/mutexLocker.hpp" | |
37 #include "runtime/os.hpp" | |
38 #include "runtime/vmThread.hpp" | |
0 | 39 |
40 // ======= Concurrent Mark Sweep Thread ======== | |
41 | |
42 // The CMS thread is created when Concurrent Mark Sweep is used in the | |
43 // older of two generations in a generational memory system. | |
44 | |
45 ConcurrentMarkSweepThread* | |
46 ConcurrentMarkSweepThread::_cmst = NULL; | |
47 CMSCollector* ConcurrentMarkSweepThread::_collector = NULL; | |
48 bool ConcurrentMarkSweepThread::_should_terminate = false; | |
49 int ConcurrentMarkSweepThread::_CMS_flag = CMS_nil; | |
50 | |
51 volatile jint ConcurrentMarkSweepThread::_pending_yields = 0; | |
52 volatile jint ConcurrentMarkSweepThread::_pending_decrements = 0; | |
53 | |
2365
a181f3a124dd
6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents:
1972
diff
changeset
|
54 volatile jint ConcurrentMarkSweepThread::_icms_disabled = 0; |
0 | 55 volatile bool ConcurrentMarkSweepThread::_should_run = false; |
56 // When icms is enabled, the icms thread is stopped until explicitly | |
57 // started. | |
58 volatile bool ConcurrentMarkSweepThread::_should_stop = true; | |
59 | |
60 SurrogateLockerThread* | |
61 ConcurrentMarkSweepThread::_slt = NULL; | |
62 SurrogateLockerThread::SLT_msg_type | |
63 ConcurrentMarkSweepThread::_sltBuffer = SurrogateLockerThread::empty; | |
64 Monitor* | |
65 ConcurrentMarkSweepThread::_sltMonitor = NULL; | |
66 | |
67 ConcurrentMarkSweepThread::ConcurrentMarkSweepThread(CMSCollector* collector) | |
68 : ConcurrentGCThread() { | |
69 assert(UseConcMarkSweepGC, "UseConcMarkSweepGC should be set"); | |
70 assert(_cmst == NULL, "CMS thread already created"); | |
71 _cmst = this; | |
72 assert(_collector == NULL, "Collector already set"); | |
73 _collector = collector; | |
74 | |
75 set_name("Concurrent Mark-Sweep GC Thread"); | |
76 | |
77 if (os::create_thread(this, os::cgc_thread)) { | |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
78 // An old comment here said: "Priority should be just less |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
79 // than that of VMThread". Since the VMThread runs at |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
80 // NearMaxPriority, the old comment was inaccurate, but |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
81 // changing the default priority to NearMaxPriority-1 |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
82 // could change current behavior, so the default of |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
83 // NearMaxPriority stays in place. |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
84 // |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
85 // Note that there's a possibility of the VMThread |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
86 // starving if UseCriticalCMSThreadPriority is on. |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
87 // That won't happen on Solaris for various reasons, |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
88 // but may well happen on non-Solaris platforms. |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
89 int native_prio; |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
90 if (UseCriticalCMSThreadPriority) { |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
91 native_prio = os::java_to_os_priority[CriticalPriority]; |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
92 } else { |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
93 native_prio = os::java_to_os_priority[NearMaxPriority]; |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
94 } |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
95 os::set_native_priority(this, native_prio); |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
96 |
0 | 97 if (!DisableStartThread) { |
98 os::start_thread(this); | |
99 } | |
100 } | |
101 _sltMonitor = SLT_lock; | |
2365
a181f3a124dd
6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents:
1972
diff
changeset
|
102 assert(!CMSIncrementalMode || icms_is_enabled(), "Error"); |
0 | 103 } |
104 | |
105 void ConcurrentMarkSweepThread::run() { | |
106 assert(this == cmst(), "just checking"); | |
107 | |
108 this->record_stack_base_and_size(); | |
109 this->initialize_thread_local_storage(); | |
110 this->set_active_handles(JNIHandleBlock::allocate_block()); | |
111 // From this time Thread::current() should be working. | |
112 assert(this == Thread::current(), "just checking"); | |
113 if (BindCMSThreadToCPU && !os::bind_to_processor(CPUForCMSThread)) { | |
114 warning("Couldn't bind CMS thread to processor %u", CPUForCMSThread); | |
115 } | |
116 // Wait until Universe::is_fully_initialized() | |
117 { | |
118 CMSLoopCountWarn loopX("CMS::run", "waiting for " | |
119 "Universe::is_fully_initialized()", 2); | |
120 MutexLockerEx x(CGC_lock, true); | |
121 set_CMS_flag(CMS_cms_wants_token); | |
122 // Wait until Universe is initialized and all initialization is completed. | |
123 while (!is_init_completed() && !Universe::is_fully_initialized() && | |
124 !_should_terminate) { | |
125 CGC_lock->wait(true, 200); | |
126 loopX.tick(); | |
127 } | |
128 // Wait until the surrogate locker thread that will do | |
129 // pending list locking on our behalf has been created. | |
130 // We cannot start the SLT thread ourselves since we need | |
131 // to be a JavaThread to do so. | |
132 CMSLoopCountWarn loopY("CMS::run", "waiting for SLT installation", 2); | |
133 while (_slt == NULL && !_should_terminate) { | |
134 CGC_lock->wait(true, 200); | |
135 loopY.tick(); | |
136 } | |
137 clear_CMS_flag(CMS_cms_wants_token); | |
138 } | |
139 | |
140 while (!_should_terminate) { | |
141 sleepBeforeNextCycle(); | |
142 if (_should_terminate) break; | |
143 _collector->collect_in_background(false); // !clear_all_soft_refs | |
144 } | |
145 assert(_should_terminate, "just checking"); | |
146 // Check that the state of any protocol for synchronization | |
147 // between background (CMS) and foreground collector is "clean" | |
148 // (i.e. will not potentially block the foreground collector, | |
149 // requiring action by us). | |
150 verify_ok_to_terminate(); | |
151 // Signal that it is terminated | |
152 { | |
153 MutexLockerEx mu(Terminator_lock, | |
154 Mutex::_no_safepoint_check_flag); | |
155 assert(_cmst == this, "Weird!"); | |
156 _cmst = NULL; | |
157 Terminator_lock->notify(); | |
158 } | |
159 | |
160 // Thread destructor usually does this.. | |
161 ThreadLocalStorage::set_thread(NULL); | |
162 } | |
163 | |
164 #ifndef PRODUCT | |
165 void ConcurrentMarkSweepThread::verify_ok_to_terminate() const { | |
166 assert(!(CGC_lock->owned_by_self() || cms_thread_has_cms_token() || | |
167 cms_thread_wants_cms_token()), | |
168 "Must renounce all worldly possessions and desires for nirvana"); | |
169 _collector->verify_ok_to_terminate(); | |
170 } | |
171 #endif | |
172 | |
173 // create and start a new ConcurrentMarkSweep Thread for given CMS generation | |
174 ConcurrentMarkSweepThread* ConcurrentMarkSweepThread::start(CMSCollector* collector) { | |
175 if (!_should_terminate) { | |
176 assert(cmst() == NULL, "start() called twice?"); | |
177 ConcurrentMarkSweepThread* th = new ConcurrentMarkSweepThread(collector); | |
178 assert(cmst() == th, "Where did the just-created CMS thread go?"); | |
179 return th; | |
180 } | |
181 return NULL; | |
182 } | |
183 | |
184 void ConcurrentMarkSweepThread::stop() { | |
185 if (CMSIncrementalMode) { | |
186 // Disable incremental mode and wake up the thread so it notices the change. | |
187 disable_icms(); | |
188 start_icms(); | |
189 } | |
190 // it is ok to take late safepoints here, if needed | |
191 { | |
192 MutexLockerEx x(Terminator_lock); | |
193 _should_terminate = true; | |
194 } | |
195 { // Now post a notify on CGC_lock so as to nudge | |
196 // CMS thread(s) that might be slumbering in | |
197 // sleepBeforeNextCycle. | |
198 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); | |
199 CGC_lock->notify_all(); | |
200 } | |
201 { // Now wait until (all) CMS thread(s) have exited | |
202 MutexLockerEx x(Terminator_lock); | |
203 while(cmst() != NULL) { | |
204 Terminator_lock->wait(); | |
205 } | |
206 } | |
207 } | |
208 | |
209 void ConcurrentMarkSweepThread::threads_do(ThreadClosure* tc) { | |
210 assert(tc != NULL, "Null ThreadClosure"); | |
211 if (_cmst != NULL) { | |
212 tc->do_thread(_cmst); | |
213 } | |
214 assert(Universe::is_fully_initialized(), | |
215 "Called too early, make sure heap is fully initialized"); | |
216 if (_collector != NULL) { | |
217 AbstractWorkGang* gang = _collector->conc_workers(); | |
218 if (gang != NULL) { | |
219 gang->threads_do(tc); | |
220 } | |
221 } | |
222 } | |
223 | |
224 void ConcurrentMarkSweepThread::print_on(outputStream* st) const { | |
225 st->print("\"%s\" ", name()); | |
226 Thread::print_on(st); | |
227 st->cr(); | |
228 } | |
229 | |
230 void ConcurrentMarkSweepThread::print_all_on(outputStream* st) { | |
231 if (_cmst != NULL) { | |
232 _cmst->print_on(st); | |
6766 | 233 st->cr(); |
0 | 234 } |
235 if (_collector != NULL) { | |
236 AbstractWorkGang* gang = _collector->conc_workers(); | |
237 if (gang != NULL) { | |
238 gang->print_worker_threads_on(st); | |
239 } | |
240 } | |
241 } | |
242 | |
243 void ConcurrentMarkSweepThread::synchronize(bool is_cms_thread) { | |
244 assert(UseConcMarkSweepGC, "just checking"); | |
245 | |
246 MutexLockerEx x(CGC_lock, | |
247 Mutex::_no_safepoint_check_flag); | |
248 if (!is_cms_thread) { | |
249 assert(Thread::current()->is_VM_thread(), "Not a VM thread"); | |
250 CMSSynchronousYieldRequest yr; | |
251 while (CMS_flag_is_set(CMS_cms_has_token)) { | |
252 // indicate that we want to get the token | |
253 set_CMS_flag(CMS_vm_wants_token); | |
254 CGC_lock->wait(true); | |
255 } | |
256 // claim the token and proceed | |
257 clear_CMS_flag(CMS_vm_wants_token); | |
258 set_CMS_flag(CMS_vm_has_token); | |
259 } else { | |
260 assert(Thread::current()->is_ConcurrentGC_thread(), | |
261 "Not a CMS thread"); | |
262 // The following barrier assumes there's only one CMS thread. | |
263 // This will need to be modified is there are more CMS threads than one. | |
264 while (CMS_flag_is_set(CMS_vm_has_token | CMS_vm_wants_token)) { | |
265 set_CMS_flag(CMS_cms_wants_token); | |
266 CGC_lock->wait(true); | |
267 } | |
268 // claim the token | |
269 clear_CMS_flag(CMS_cms_wants_token); | |
270 set_CMS_flag(CMS_cms_has_token); | |
271 } | |
272 } | |
273 | |
274 void ConcurrentMarkSweepThread::desynchronize(bool is_cms_thread) { | |
275 assert(UseConcMarkSweepGC, "just checking"); | |
276 | |
277 MutexLockerEx x(CGC_lock, | |
278 Mutex::_no_safepoint_check_flag); | |
279 if (!is_cms_thread) { | |
280 assert(Thread::current()->is_VM_thread(), "Not a VM thread"); | |
281 assert(CMS_flag_is_set(CMS_vm_has_token), "just checking"); | |
282 clear_CMS_flag(CMS_vm_has_token); | |
283 if (CMS_flag_is_set(CMS_cms_wants_token)) { | |
284 // wake-up a waiting CMS thread | |
285 CGC_lock->notify(); | |
286 } | |
287 assert(!CMS_flag_is_set(CMS_vm_has_token | CMS_vm_wants_token), | |
288 "Should have been cleared"); | |
289 } else { | |
290 assert(Thread::current()->is_ConcurrentGC_thread(), | |
291 "Not a CMS thread"); | |
292 assert(CMS_flag_is_set(CMS_cms_has_token), "just checking"); | |
293 clear_CMS_flag(CMS_cms_has_token); | |
294 if (CMS_flag_is_set(CMS_vm_wants_token)) { | |
295 // wake-up a waiting VM thread | |
296 CGC_lock->notify(); | |
297 } | |
298 assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token), | |
299 "Should have been cleared"); | |
300 } | |
301 } | |
302 | |
8679
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
303 // Wait until any cms_lock event |
1887
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
304 void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) { |
0 | 305 MutexLockerEx x(CGC_lock, |
306 Mutex::_no_safepoint_check_flag); | |
1887
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
307 if (_should_terminate || _collector->_full_gc_requested) { |
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
308 return; |
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
309 } |
0 | 310 set_CMS_flag(CMS_cms_wants_token); // to provoke notifies |
1887
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
311 CGC_lock->wait(Mutex::_no_safepoint_check_flag, t_millis); |
0 | 312 clear_CMS_flag(CMS_cms_wants_token); |
313 assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token), | |
314 "Should not be set"); | |
315 } | |
316 | |
8679
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
317 // Wait until the next synchronous GC, a concurrent full gc request, |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
318 // or a timeout, whichever is earlier. |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
319 void ConcurrentMarkSweepThread::wait_on_cms_lock_for_scavenge(long t_millis) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
320 // Wait time in millis or 0 value representing infinite wait for a scavenge |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
321 assert(t_millis >= 0, "Wait time for scavenge should be 0 or positive"); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
322 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
323 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
324 double start_time_secs = os::elapsedTime(); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
325 double end_time_secs = start_time_secs + (t_millis / ((double) MILLIUNITS)); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
326 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
327 // Total collections count before waiting loop |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
328 unsigned int before_count; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
329 { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
330 MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
331 before_count = gch->total_collections(); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
332 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
333 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
334 unsigned int loop_count = 0; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
335 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
336 while(!_should_terminate) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
337 double now_time = os::elapsedTime(); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
338 long wait_time_millis; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
339 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
340 if(t_millis != 0) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
341 // New wait limit |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
342 wait_time_millis = (long) ((end_time_secs - now_time) * MILLIUNITS); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
343 if(wait_time_millis <= 0) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
344 // Wait time is over |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
345 break; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
346 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
347 } else { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
348 // No wait limit, wait if necessary forever |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
349 wait_time_millis = 0; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
350 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
351 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
352 // Wait until the next event or the remaining timeout |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
353 { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
354 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
355 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
356 if (_should_terminate || _collector->_full_gc_requested) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
357 return; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
358 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
359 set_CMS_flag(CMS_cms_wants_token); // to provoke notifies |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
360 assert(t_millis == 0 || wait_time_millis > 0, "Sanity"); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
361 CGC_lock->wait(Mutex::_no_safepoint_check_flag, wait_time_millis); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
362 clear_CMS_flag(CMS_cms_wants_token); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
363 assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token), |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
364 "Should not be set"); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
365 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
366 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
367 // Extra wait time check before entering the heap lock to get the collection count |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
368 if(t_millis != 0 && os::elapsedTime() >= end_time_secs) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
369 // Wait time is over |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
370 break; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
371 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
372 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
373 // Total collections count after the event |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
374 unsigned int after_count; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
375 { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
376 MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
377 after_count = gch->total_collections(); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
378 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
379 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
380 if(before_count != after_count) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
381 // There was a collection - success |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
382 break; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
383 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
384 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
385 // Too many loops warning |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
386 if(++loop_count == 0) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
387 warning("wait_on_cms_lock_for_scavenge() has looped %u times", loop_count - 1); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
388 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
389 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
390 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
391 |
0 | 392 void ConcurrentMarkSweepThread::sleepBeforeNextCycle() { |
393 while (!_should_terminate) { | |
394 if (CMSIncrementalMode) { | |
395 icms_wait(); | |
8679
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
396 if(CMSWaitDuration >= 0) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
397 // Wait until the next synchronous GC, a concurrent full gc |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
398 // request or a timeout, whichever is earlier. |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
399 wait_on_cms_lock_for_scavenge(CMSWaitDuration); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
400 } |
0 | 401 return; |
402 } else { | |
8679
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
403 if(CMSWaitDuration >= 0) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
404 // Wait until the next synchronous GC, a concurrent full gc |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
405 // request or a timeout, whichever is earlier. |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
406 wait_on_cms_lock_for_scavenge(CMSWaitDuration); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
407 } else { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
408 // Wait until any cms_lock event or check interval not to call shouldConcurrentCollect permanently |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
409 wait_on_cms_lock(CMSCheckInterval); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
410 } |
0 | 411 } |
412 // Check if we should start a CMS collection cycle | |
413 if (_collector->shouldConcurrentCollect()) { | |
414 return; | |
415 } | |
416 // .. collection criterion not yet met, let's go back | |
417 // and wait some more | |
418 } | |
419 } | |
420 | |
421 // Incremental CMS | |
422 void ConcurrentMarkSweepThread::start_icms() { | |
423 assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); | |
424 MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); | |
425 trace_state("start_icms"); | |
426 _should_run = true; | |
427 iCMS_lock->notify_all(); | |
428 } | |
429 | |
430 void ConcurrentMarkSweepThread::stop_icms() { | |
431 assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); | |
432 MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); | |
433 if (!_should_stop) { | |
434 trace_state("stop_icms"); | |
435 _should_stop = true; | |
436 _should_run = false; | |
437 asynchronous_yield_request(); | |
438 iCMS_lock->notify_all(); | |
439 } | |
440 } | |
441 | |
442 void ConcurrentMarkSweepThread::icms_wait() { | |
443 assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); | |
2365
a181f3a124dd
6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents:
1972
diff
changeset
|
444 if (_should_stop && icms_is_enabled()) { |
0 | 445 MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); |
446 trace_state("pause_icms"); | |
447 _collector->stats().stop_cms_timer(); | |
2365
a181f3a124dd
6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents:
1972
diff
changeset
|
448 while(!_should_run && icms_is_enabled()) { |
0 | 449 iCMS_lock->wait(Mutex::_no_safepoint_check_flag); |
450 } | |
451 _collector->stats().start_cms_timer(); | |
452 _should_stop = false; | |
453 trace_state("pause_icms end"); | |
454 } | |
455 } | |
456 | |
457 // Note: this method, although exported by the ConcurrentMarkSweepThread, | |
458 // which is a non-JavaThread, can only be called by a JavaThread. | |
459 // Currently this is done at vm creation time (post-vm-init) by the | |
460 // main/Primordial (Java)Thread. | |
461 // XXX Consider changing this in the future to allow the CMS thread | |
462 // itself to create this thread? | |
463 void ConcurrentMarkSweepThread::makeSurrogateLockerThread(TRAPS) { | |
464 assert(UseConcMarkSweepGC, "SLT thread needed only for CMS GC"); | |
465 assert(_slt == NULL, "SLT already created"); | |
466 _slt = SurrogateLockerThread::make(THREAD); | |
467 } |