Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/shared/concurrentGCThread.cpp @ 1842:6e0aac35bfa9
6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
Summary: Under certain circumstances a safepoint could happen between a JavaThread object being created and that object being added to the Java threads list. This could cause the active field of that thread's SATB queue to get out-of-sync with respect to the other Java threads. The solution is to activate the SATB queue, when necessary, before adding the thread to the Java threads list, not when the JavaThread object is created. The changeset also includes a small fix to rename the surrogate locker thread from "Surrogate Locker Thread (CMS)" to "Surrogate Locker Thread (Concurrent GC)" since it's also used in G1.
Reviewed-by: iveresov, ysr, johnc, jcoomes
author | tonyp |
---|---|
date | Fri, 01 Oct 2010 16:43:05 -0400 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
342 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
diff
changeset
|
2 * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. |
342 | 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:
844
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
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:
844
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
25 // CopyrightVersion 1.2 | |
26 | |
27 # include "incls/_precompiled.incl" | |
28 # include "incls/_concurrentGCThread.cpp.incl" | |
29 | |
30 int ConcurrentGCThread::_CGC_flag = CGC_nil; | |
31 | |
32 SuspendibleThreadSet ConcurrentGCThread::_sts; | |
33 | |
794 | 34 ConcurrentGCThread::ConcurrentGCThread() : |
35 _should_terminate(false), _has_terminated(false) { | |
342 | 36 _sts.initialize(); |
37 }; | |
38 | |
39 void ConcurrentGCThread::stopWorldAndDo(VoidClosure* op) { | |
40 MutexLockerEx x(Heap_lock, | |
41 Mutex::_no_safepoint_check_flag); | |
42 // warning("CGC: about to try stopping world"); | |
43 SafepointSynchronize::begin(); | |
44 // warning("CGC: successfully stopped world"); | |
45 op->do_void(); | |
46 SafepointSynchronize::end(); | |
47 // warning("CGC: successfully restarted world"); | |
48 } | |
49 | |
50 void ConcurrentGCThread::safepoint_synchronize() { | |
51 _sts.suspend_all(); | |
52 } | |
53 | |
54 void ConcurrentGCThread::safepoint_desynchronize() { | |
55 _sts.resume_all(); | |
56 } | |
57 | |
58 void ConcurrentGCThread::create_and_start() { | |
59 if (os::create_thread(this, os::cgc_thread)) { | |
60 // XXX: need to set this to low priority | |
61 // unless "agressive mode" set; priority | |
62 // should be just less than that of VMThread. | |
63 os::set_priority(this, NearMaxPriority); | |
64 if (!_should_terminate && !DisableStartThread) { | |
65 os::start_thread(this); | |
66 } | |
67 } | |
68 } | |
69 | |
70 void ConcurrentGCThread::initialize_in_thread() { | |
71 this->record_stack_base_and_size(); | |
72 this->initialize_thread_local_storage(); | |
73 this->set_active_handles(JNIHandleBlock::allocate_block()); | |
74 // From this time Thread::current() should be working. | |
75 assert(this == Thread::current(), "just checking"); | |
76 } | |
77 | |
78 void ConcurrentGCThread::wait_for_universe_init() { | |
79 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); | |
80 while (!is_init_completed() && !_should_terminate) { | |
81 CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200); | |
82 } | |
83 } | |
84 | |
85 void ConcurrentGCThread::terminate() { | |
86 // Signal that it is terminated | |
87 { | |
88 MutexLockerEx mu(Terminator_lock, | |
89 Mutex::_no_safepoint_check_flag); | |
90 _has_terminated = true; | |
91 Terminator_lock->notify(); | |
92 } | |
93 | |
94 // Thread destructor usually does this.. | |
95 ThreadLocalStorage::set_thread(NULL); | |
96 } | |
97 | |
98 | |
99 void SuspendibleThreadSet::initialize_work() { | |
100 MutexLocker x(STS_init_lock); | |
101 if (!_initialized) { | |
102 _m = new Monitor(Mutex::leaf, | |
103 "SuspendibleThreadSetLock", true); | |
104 _async = 0; | |
105 _async_stop = false; | |
106 _async_stopped = 0; | |
107 _initialized = true; | |
108 } | |
109 } | |
110 | |
111 void SuspendibleThreadSet::join() { | |
112 initialize(); | |
113 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); | |
114 while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag); | |
115 _async++; | |
116 assert(_async > 0, "Huh."); | |
117 } | |
118 | |
119 void SuspendibleThreadSet::leave() { | |
120 assert(_initialized, "Must be initialized."); | |
121 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); | |
122 _async--; | |
123 assert(_async >= 0, "Huh."); | |
124 if (_async_stop) _m->notify_all(); | |
125 } | |
126 | |
127 void SuspendibleThreadSet::yield(const char* id) { | |
128 assert(_initialized, "Must be initialized."); | |
129 if (_async_stop) { | |
130 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); | |
131 if (_async_stop) { | |
132 _async_stopped++; | |
133 assert(_async_stopped > 0, "Huh."); | |
134 if (_async_stopped == _async) { | |
135 if (ConcGCYieldTimeout > 0) { | |
136 double now = os::elapsedTime(); | |
137 guarantee((now - _suspend_all_start) * 1000.0 < | |
138 (double)ConcGCYieldTimeout, | |
139 "Long delay; whodunit?"); | |
140 } | |
141 } | |
142 _m->notify_all(); | |
143 while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag); | |
144 _async_stopped--; | |
145 assert(_async >= 0, "Huh"); | |
146 _m->notify_all(); | |
147 } | |
148 } | |
149 } | |
150 | |
151 void SuspendibleThreadSet::suspend_all() { | |
152 initialize(); // If necessary. | |
153 if (ConcGCYieldTimeout > 0) { | |
154 _suspend_all_start = os::elapsedTime(); | |
155 } | |
156 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); | |
157 assert(!_async_stop, "Only one at a time."); | |
158 _async_stop = true; | |
159 while (_async_stopped < _async) _m->wait(Mutex::_no_safepoint_check_flag); | |
160 } | |
161 | |
162 void SuspendibleThreadSet::resume_all() { | |
163 assert(_initialized, "Must be initialized."); | |
164 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); | |
165 assert(_async_stopped == _async, "Huh."); | |
166 _async_stop = false; | |
167 _m->notify_all(); | |
168 } | |
169 | |
170 static void _sltLoop(JavaThread* thread, TRAPS) { | |
171 SurrogateLockerThread* slt = (SurrogateLockerThread*)thread; | |
172 slt->loop(); | |
173 } | |
174 | |
175 SurrogateLockerThread::SurrogateLockerThread() : | |
176 JavaThread(&_sltLoop), | |
177 _monitor(Mutex::nonleaf, "SLTMonitor"), | |
178 _buffer(empty) | |
179 {} | |
180 | |
181 SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) { | |
182 klassOop k = | |
183 SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(), | |
184 true, CHECK_NULL); | |
185 instanceKlassHandle klass (THREAD, k); | |
186 instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL); | |
187 | |
1842
6e0aac35bfa9
6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents:
1552
diff
changeset
|
188 const char thread_name[] = "Surrogate Locker Thread (Concurrent GC)"; |
342 | 189 Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL); |
190 | |
191 // Initialize thread_oop to put it into the system threadGroup | |
192 Handle thread_group (THREAD, Universe::system_thread_group()); | |
193 JavaValue result(T_VOID); | |
194 JavaCalls::call_special(&result, thread_oop, | |
195 klass, | |
196 vmSymbolHandles::object_initializer_name(), | |
197 vmSymbolHandles::threadgroup_string_void_signature(), | |
198 thread_group, | |
199 string, | |
200 CHECK_NULL); | |
201 | |
202 SurrogateLockerThread* res; | |
203 { | |
204 MutexLocker mu(Threads_lock); | |
205 res = new SurrogateLockerThread(); | |
206 | |
207 // At this point it may be possible that no osthread was created for the | |
208 // JavaThread due to lack of memory. We would have to throw an exception | |
209 // in that case. However, since this must work and we do not allow | |
210 // exceptions anyway, check and abort if this fails. | |
211 if (res == NULL || res->osthread() == NULL) { | |
212 vm_exit_during_initialization("java.lang.OutOfMemoryError", | |
213 "unable to create new native thread"); | |
214 } | |
215 java_lang_Thread::set_thread(thread_oop(), res); | |
216 java_lang_Thread::set_priority(thread_oop(), NearMaxPriority); | |
217 java_lang_Thread::set_daemon(thread_oop()); | |
218 | |
219 res->set_threadObj(thread_oop()); | |
220 Threads::add(res); | |
221 Thread::start(res); | |
222 } | |
223 os::yield(); // This seems to help with initial start-up of SLT | |
224 return res; | |
225 } | |
226 | |
227 void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) { | |
228 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag); | |
229 assert(_buffer == empty, "Should be empty"); | |
230 assert(msg != empty, "empty message"); | |
231 _buffer = msg; | |
232 while (_buffer != empty) { | |
233 _monitor.notify(); | |
234 _monitor.wait(Mutex::_no_safepoint_check_flag); | |
235 } | |
236 } | |
237 | |
238 // ======= Surrogate Locker Thread ============= | |
239 | |
240 void SurrogateLockerThread::loop() { | |
241 BasicLock pll_basic_lock; | |
242 SLT_msg_type msg; | |
243 debug_only(unsigned int owned = 0;) | |
244 | |
245 while (/* !isTerminated() */ 1) { | |
246 { | |
247 MutexLocker x(&_monitor); | |
248 // Since we are a JavaThread, we can't be here at a safepoint. | |
249 assert(!SafepointSynchronize::is_at_safepoint(), | |
250 "SLT is a JavaThread"); | |
251 // wait for msg buffer to become non-empty | |
252 while (_buffer == empty) { | |
253 _monitor.notify(); | |
254 _monitor.wait(); | |
255 } | |
256 msg = _buffer; | |
257 } | |
258 switch(msg) { | |
259 case acquirePLL: { | |
260 instanceRefKlass::acquire_pending_list_lock(&pll_basic_lock); | |
261 debug_only(owned++;) | |
262 break; | |
263 } | |
264 case releaseAndNotifyPLL: { | |
265 assert(owned > 0, "Don't have PLL"); | |
266 instanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock); | |
267 debug_only(owned--;) | |
268 break; | |
269 } | |
270 case empty: | |
271 default: { | |
272 guarantee(false,"Unexpected message in _buffer"); | |
273 break; | |
274 } | |
275 } | |
276 { | |
277 MutexLocker x(&_monitor); | |
278 // Since we are a JavaThread, we can't be here at a safepoint. | |
279 assert(!SafepointSynchronize::is_at_safepoint(), | |
280 "SLT is a JavaThread"); | |
281 _buffer = empty; | |
282 _monitor.notify(); | |
283 } | |
284 } | |
285 assert(!_monitor.owned_by_self(), "Should unlock before exit."); | |
286 } | |
287 | |
288 | |
289 // ===== STS Access From Outside CGCT ===== | |
290 | |
291 void ConcurrentGCThread::stsYield(const char* id) { | |
292 assert( Thread::current()->is_ConcurrentGC_thread(), | |
293 "only a conc GC thread can call this" ); | |
294 _sts.yield(id); | |
295 } | |
296 | |
297 bool ConcurrentGCThread::stsShouldYield() { | |
298 assert( Thread::current()->is_ConcurrentGC_thread(), | |
299 "only a conc GC thread can call this" ); | |
300 return _sts.should_yield(); | |
301 } | |
302 | |
303 void ConcurrentGCThread::stsJoin() { | |
304 assert( Thread::current()->is_ConcurrentGC_thread(), | |
305 "only a conc GC thread can call this" ); | |
306 _sts.join(); | |
307 } | |
308 | |
309 void ConcurrentGCThread::stsLeave() { | |
310 assert( Thread::current()->is_ConcurrentGC_thread(), | |
311 "only a conc GC thread can call this" ); | |
312 _sts.leave(); | |
313 } |