Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp @ 19083:09292c24d555
LSStackSlotAllocator: hide inner class.
author | Josef Eisl <josef.eisl@jku.at> |
---|---|
date | Sat, 31 Jan 2015 11:07:15 +0100 |
parents | 52b4284cb496 |
children |
rev | line source |
---|---|
0 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
14223
diff
changeset
|
2 * Copyright (c) 2001, 2014, 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)) { | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
14223
diff
changeset
|
114 warning("Couldn't bind CMS thread to processor " UINTX_FORMAT, CPUForCMSThread); |
0 | 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; | |
10405 | 143 GCCause::Cause cause = _collector->_full_gc_requested ? |
144 _collector->_full_gc_cause : GCCause::_cms_concurrent_mark; | |
145 _collector->collect_in_background(false, cause); | |
0 | 146 } |
147 assert(_should_terminate, "just checking"); | |
148 // Check that the state of any protocol for synchronization | |
149 // between background (CMS) and foreground collector is "clean" | |
150 // (i.e. will not potentially block the foreground collector, | |
151 // requiring action by us). | |
152 verify_ok_to_terminate(); | |
153 // Signal that it is terminated | |
154 { | |
155 MutexLockerEx mu(Terminator_lock, | |
156 Mutex::_no_safepoint_check_flag); | |
157 assert(_cmst == this, "Weird!"); | |
158 _cmst = NULL; | |
159 Terminator_lock->notify(); | |
160 } | |
161 | |
162 // Thread destructor usually does this.. | |
163 ThreadLocalStorage::set_thread(NULL); | |
164 } | |
165 | |
166 #ifndef PRODUCT | |
167 void ConcurrentMarkSweepThread::verify_ok_to_terminate() const { | |
168 assert(!(CGC_lock->owned_by_self() || cms_thread_has_cms_token() || | |
169 cms_thread_wants_cms_token()), | |
170 "Must renounce all worldly possessions and desires for nirvana"); | |
171 _collector->verify_ok_to_terminate(); | |
172 } | |
173 #endif | |
174 | |
175 // create and start a new ConcurrentMarkSweep Thread for given CMS generation | |
176 ConcurrentMarkSweepThread* ConcurrentMarkSweepThread::start(CMSCollector* collector) { | |
177 if (!_should_terminate) { | |
178 assert(cmst() == NULL, "start() called twice?"); | |
179 ConcurrentMarkSweepThread* th = new ConcurrentMarkSweepThread(collector); | |
180 assert(cmst() == th, "Where did the just-created CMS thread go?"); | |
181 return th; | |
182 } | |
183 return NULL; | |
184 } | |
185 | |
186 void ConcurrentMarkSweepThread::stop() { | |
187 if (CMSIncrementalMode) { | |
188 // Disable incremental mode and wake up the thread so it notices the change. | |
189 disable_icms(); | |
190 start_icms(); | |
191 } | |
192 // it is ok to take late safepoints here, if needed | |
193 { | |
194 MutexLockerEx x(Terminator_lock); | |
195 _should_terminate = true; | |
196 } | |
197 { // Now post a notify on CGC_lock so as to nudge | |
198 // CMS thread(s) that might be slumbering in | |
199 // sleepBeforeNextCycle. | |
200 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); | |
201 CGC_lock->notify_all(); | |
202 } | |
203 { // Now wait until (all) CMS thread(s) have exited | |
204 MutexLockerEx x(Terminator_lock); | |
205 while(cmst() != NULL) { | |
206 Terminator_lock->wait(); | |
207 } | |
208 } | |
209 } | |
210 | |
211 void ConcurrentMarkSweepThread::threads_do(ThreadClosure* tc) { | |
212 assert(tc != NULL, "Null ThreadClosure"); | |
213 if (_cmst != NULL) { | |
214 tc->do_thread(_cmst); | |
215 } | |
216 assert(Universe::is_fully_initialized(), | |
217 "Called too early, make sure heap is fully initialized"); | |
218 if (_collector != NULL) { | |
219 AbstractWorkGang* gang = _collector->conc_workers(); | |
220 if (gang != NULL) { | |
221 gang->threads_do(tc); | |
222 } | |
223 } | |
224 } | |
225 | |
226 void ConcurrentMarkSweepThread::print_on(outputStream* st) const { | |
227 st->print("\"%s\" ", name()); | |
228 Thread::print_on(st); | |
229 st->cr(); | |
230 } | |
231 | |
232 void ConcurrentMarkSweepThread::print_all_on(outputStream* st) { | |
233 if (_cmst != NULL) { | |
234 _cmst->print_on(st); | |
6766 | 235 st->cr(); |
0 | 236 } |
237 if (_collector != NULL) { | |
238 AbstractWorkGang* gang = _collector->conc_workers(); | |
239 if (gang != NULL) { | |
240 gang->print_worker_threads_on(st); | |
241 } | |
242 } | |
243 } | |
244 | |
245 void ConcurrentMarkSweepThread::synchronize(bool is_cms_thread) { | |
246 assert(UseConcMarkSweepGC, "just checking"); | |
247 | |
248 MutexLockerEx x(CGC_lock, | |
249 Mutex::_no_safepoint_check_flag); | |
250 if (!is_cms_thread) { | |
251 assert(Thread::current()->is_VM_thread(), "Not a VM thread"); | |
252 CMSSynchronousYieldRequest yr; | |
253 while (CMS_flag_is_set(CMS_cms_has_token)) { | |
254 // indicate that we want to get the token | |
255 set_CMS_flag(CMS_vm_wants_token); | |
256 CGC_lock->wait(true); | |
257 } | |
258 // claim the token and proceed | |
259 clear_CMS_flag(CMS_vm_wants_token); | |
260 set_CMS_flag(CMS_vm_has_token); | |
261 } else { | |
262 assert(Thread::current()->is_ConcurrentGC_thread(), | |
263 "Not a CMS thread"); | |
264 // The following barrier assumes there's only one CMS thread. | |
265 // This will need to be modified is there are more CMS threads than one. | |
266 while (CMS_flag_is_set(CMS_vm_has_token | CMS_vm_wants_token)) { | |
267 set_CMS_flag(CMS_cms_wants_token); | |
268 CGC_lock->wait(true); | |
269 } | |
270 // claim the token | |
271 clear_CMS_flag(CMS_cms_wants_token); | |
272 set_CMS_flag(CMS_cms_has_token); | |
273 } | |
274 } | |
275 | |
276 void ConcurrentMarkSweepThread::desynchronize(bool is_cms_thread) { | |
277 assert(UseConcMarkSweepGC, "just checking"); | |
278 | |
279 MutexLockerEx x(CGC_lock, | |
280 Mutex::_no_safepoint_check_flag); | |
281 if (!is_cms_thread) { | |
282 assert(Thread::current()->is_VM_thread(), "Not a VM thread"); | |
283 assert(CMS_flag_is_set(CMS_vm_has_token), "just checking"); | |
284 clear_CMS_flag(CMS_vm_has_token); | |
285 if (CMS_flag_is_set(CMS_cms_wants_token)) { | |
286 // wake-up a waiting CMS thread | |
287 CGC_lock->notify(); | |
288 } | |
289 assert(!CMS_flag_is_set(CMS_vm_has_token | CMS_vm_wants_token), | |
290 "Should have been cleared"); | |
291 } else { | |
292 assert(Thread::current()->is_ConcurrentGC_thread(), | |
293 "Not a CMS thread"); | |
294 assert(CMS_flag_is_set(CMS_cms_has_token), "just checking"); | |
295 clear_CMS_flag(CMS_cms_has_token); | |
296 if (CMS_flag_is_set(CMS_vm_wants_token)) { | |
297 // wake-up a waiting VM thread | |
298 CGC_lock->notify(); | |
299 } | |
300 assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token), | |
301 "Should have been cleared"); | |
302 } | |
303 } | |
304 | |
8679
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
305 // Wait until any cms_lock event |
1887
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
306 void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) { |
0 | 307 MutexLockerEx x(CGC_lock, |
308 Mutex::_no_safepoint_check_flag); | |
1887
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
309 if (_should_terminate || _collector->_full_gc_requested) { |
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
310 return; |
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
311 } |
0 | 312 set_CMS_flag(CMS_cms_wants_token); // to provoke notifies |
1887
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
313 CGC_lock->wait(Mutex::_no_safepoint_check_flag, t_millis); |
0 | 314 clear_CMS_flag(CMS_cms_wants_token); |
315 assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token), | |
316 "Should not be set"); | |
317 } | |
318 | |
8679
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
319 // 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
|
320 // or a timeout, whichever is earlier. |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
321 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
|
322 // 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
|
323 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
|
324 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
325 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
326 double start_time_secs = os::elapsedTime(); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
327 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
|
328 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
329 // Total collections count before waiting loop |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
330 unsigned int before_count; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
331 { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
332 MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
333 before_count = gch->total_collections(); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
334 } |
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 unsigned int loop_count = 0; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
337 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
338 while(!_should_terminate) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
339 double now_time = os::elapsedTime(); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
340 long wait_time_millis; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
341 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
342 if(t_millis != 0) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
343 // New wait limit |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
344 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
|
345 if(wait_time_millis <= 0) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
346 // Wait time is over |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
347 break; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
348 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
349 } else { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
350 // No wait limit, wait if necessary forever |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
351 wait_time_millis = 0; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
352 } |
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 // Wait until the next event or the remaining timeout |
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 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
357 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
358 if (_should_terminate || _collector->_full_gc_requested) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
359 return; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
360 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
361 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
|
362 assert(t_millis == 0 || wait_time_millis > 0, "Sanity"); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
363 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
|
364 clear_CMS_flag(CMS_cms_wants_token); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
365 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
|
366 "Should not be set"); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
367 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
368 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
369 // 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
|
370 if(t_millis != 0 && os::elapsedTime() >= end_time_secs) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
371 // Wait time is over |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
372 break; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
373 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
374 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
375 // Total collections count after the event |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
376 unsigned int after_count; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
377 { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
378 MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
379 after_count = gch->total_collections(); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
380 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
381 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
382 if(before_count != after_count) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
383 // There was a collection - success |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
384 break; |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
385 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
386 |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
387 // Too many loops warning |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
388 if(++loop_count == 0) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
389 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
|
390 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
391 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
392 } |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
393 |
0 | 394 void ConcurrentMarkSweepThread::sleepBeforeNextCycle() { |
395 while (!_should_terminate) { | |
396 if (CMSIncrementalMode) { | |
397 icms_wait(); | |
8679
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
398 if(CMSWaitDuration >= 0) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
399 // 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
|
400 // request or a timeout, whichever is earlier. |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
401 wait_on_cms_lock_for_scavenge(CMSWaitDuration); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
402 } |
0 | 403 return; |
404 } else { | |
8679
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
405 if(CMSWaitDuration >= 0) { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
406 // 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
|
407 // request or a timeout, whichever is earlier. |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
408 wait_on_cms_lock_for_scavenge(CMSWaitDuration); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
409 } else { |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
410 // 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
|
411 wait_on_cms_lock(CMSCheckInterval); |
a252e688abcf
7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents:
6766
diff
changeset
|
412 } |
0 | 413 } |
414 // Check if we should start a CMS collection cycle | |
415 if (_collector->shouldConcurrentCollect()) { | |
416 return; | |
417 } | |
418 // .. collection criterion not yet met, let's go back | |
419 // and wait some more | |
420 } | |
421 } | |
422 | |
423 // Incremental CMS | |
424 void ConcurrentMarkSweepThread::start_icms() { | |
425 assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); | |
426 MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); | |
427 trace_state("start_icms"); | |
428 _should_run = true; | |
429 iCMS_lock->notify_all(); | |
430 } | |
431 | |
432 void ConcurrentMarkSweepThread::stop_icms() { | |
433 assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); | |
434 MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); | |
435 if (!_should_stop) { | |
436 trace_state("stop_icms"); | |
437 _should_stop = true; | |
438 _should_run = false; | |
439 asynchronous_yield_request(); | |
440 iCMS_lock->notify_all(); | |
441 } | |
442 } | |
443 | |
444 void ConcurrentMarkSweepThread::icms_wait() { | |
445 assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); | |
2365
a181f3a124dd
6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents:
1972
diff
changeset
|
446 if (_should_stop && icms_is_enabled()) { |
0 | 447 MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); |
448 trace_state("pause_icms"); | |
449 _collector->stats().stop_cms_timer(); | |
2365
a181f3a124dd
6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents:
1972
diff
changeset
|
450 while(!_should_run && icms_is_enabled()) { |
0 | 451 iCMS_lock->wait(Mutex::_no_safepoint_check_flag); |
452 } | |
453 _collector->stats().start_cms_timer(); | |
454 _should_stop = false; | |
455 trace_state("pause_icms end"); | |
456 } | |
457 } | |
458 | |
459 // Note: this method, although exported by the ConcurrentMarkSweepThread, | |
460 // which is a non-JavaThread, can only be called by a JavaThread. | |
461 // Currently this is done at vm creation time (post-vm-init) by the | |
462 // main/Primordial (Java)Thread. | |
463 // XXX Consider changing this in the future to allow the CMS thread | |
464 // itself to create this thread? | |
465 void ConcurrentMarkSweepThread::makeSurrogateLockerThread(TRAPS) { | |
466 assert(UseConcMarkSweepGC, "SLT thread needed only for CMS GC"); | |
467 assert(_slt == NULL, "SLT already created"); | |
468 _slt = SurrogateLockerThread::make(THREAD); | |
469 } |