1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,311 @@ 1.4 +/* 1.5 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "classfile/systemDictionary.hpp" 1.30 +#include "gc_implementation/shared/concurrentGCThread.hpp" 1.31 +#include "oops/instanceRefKlass.hpp" 1.32 +#include "oops/oop.inline.hpp" 1.33 +#include "runtime/init.hpp" 1.34 +#include "runtime/interfaceSupport.hpp" 1.35 +#include "runtime/java.hpp" 1.36 +#include "runtime/javaCalls.hpp" 1.37 + 1.38 +// CopyrightVersion 1.2 1.39 + 1.40 +int ConcurrentGCThread::_CGC_flag = CGC_nil; 1.41 + 1.42 +SuspendibleThreadSet ConcurrentGCThread::_sts; 1.43 + 1.44 +ConcurrentGCThread::ConcurrentGCThread() : 1.45 + _should_terminate(false), _has_terminated(false) { 1.46 + _sts.initialize(); 1.47 +}; 1.48 + 1.49 +void ConcurrentGCThread::safepoint_synchronize() { 1.50 + _sts.suspend_all(); 1.51 +} 1.52 + 1.53 +void ConcurrentGCThread::safepoint_desynchronize() { 1.54 + _sts.resume_all(); 1.55 +} 1.56 + 1.57 +void ConcurrentGCThread::create_and_start() { 1.58 + if (os::create_thread(this, os::cgc_thread)) { 1.59 + // XXX: need to set this to low priority 1.60 + // unless "agressive mode" set; priority 1.61 + // should be just less than that of VMThread. 1.62 + os::set_priority(this, NearMaxPriority); 1.63 + if (!_should_terminate && !DisableStartThread) { 1.64 + os::start_thread(this); 1.65 + } 1.66 + } 1.67 +} 1.68 + 1.69 +void ConcurrentGCThread::initialize_in_thread() { 1.70 + this->record_stack_base_and_size(); 1.71 + this->initialize_thread_local_storage(); 1.72 + this->set_active_handles(JNIHandleBlock::allocate_block()); 1.73 + // From this time Thread::current() should be working. 1.74 + assert(this == Thread::current(), "just checking"); 1.75 +} 1.76 + 1.77 +void ConcurrentGCThread::wait_for_universe_init() { 1.78 + MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); 1.79 + while (!is_init_completed() && !_should_terminate) { 1.80 + CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200); 1.81 + } 1.82 +} 1.83 + 1.84 +void ConcurrentGCThread::terminate() { 1.85 + // Signal that it is terminated 1.86 + { 1.87 + MutexLockerEx mu(Terminator_lock, 1.88 + Mutex::_no_safepoint_check_flag); 1.89 + _has_terminated = true; 1.90 + Terminator_lock->notify(); 1.91 + } 1.92 + 1.93 + // Thread destructor usually does this.. 1.94 + ThreadLocalStorage::set_thread(NULL); 1.95 +} 1.96 + 1.97 + 1.98 +void SuspendibleThreadSet::initialize_work() { 1.99 + MutexLocker x(STS_init_lock); 1.100 + if (!_initialized) { 1.101 + _m = new Monitor(Mutex::leaf, 1.102 + "SuspendibleThreadSetLock", true); 1.103 + _async = 0; 1.104 + _async_stop = false; 1.105 + _async_stopped = 0; 1.106 + _initialized = true; 1.107 + } 1.108 +} 1.109 + 1.110 +void SuspendibleThreadSet::join() { 1.111 + initialize(); 1.112 + MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); 1.113 + while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag); 1.114 + _async++; 1.115 + assert(_async > 0, "Huh."); 1.116 +} 1.117 + 1.118 +void SuspendibleThreadSet::leave() { 1.119 + assert(_initialized, "Must be initialized."); 1.120 + MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); 1.121 + _async--; 1.122 + assert(_async >= 0, "Huh."); 1.123 + if (_async_stop) _m->notify_all(); 1.124 +} 1.125 + 1.126 +void SuspendibleThreadSet::yield(const char* id) { 1.127 + assert(_initialized, "Must be initialized."); 1.128 + if (_async_stop) { 1.129 + MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); 1.130 + if (_async_stop) { 1.131 + _async_stopped++; 1.132 + assert(_async_stopped > 0, "Huh."); 1.133 + if (_async_stopped == _async) { 1.134 + if (ConcGCYieldTimeout > 0) { 1.135 + double now = os::elapsedTime(); 1.136 + guarantee((now - _suspend_all_start) * 1000.0 < 1.137 + (double)ConcGCYieldTimeout, 1.138 + "Long delay; whodunit?"); 1.139 + } 1.140 + } 1.141 + _m->notify_all(); 1.142 + while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag); 1.143 + _async_stopped--; 1.144 + assert(_async >= 0, "Huh"); 1.145 + _m->notify_all(); 1.146 + } 1.147 + } 1.148 +} 1.149 + 1.150 +void SuspendibleThreadSet::suspend_all() { 1.151 + initialize(); // If necessary. 1.152 + if (ConcGCYieldTimeout > 0) { 1.153 + _suspend_all_start = os::elapsedTime(); 1.154 + } 1.155 + MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); 1.156 + assert(!_async_stop, "Only one at a time."); 1.157 + _async_stop = true; 1.158 + while (_async_stopped < _async) _m->wait(Mutex::_no_safepoint_check_flag); 1.159 +} 1.160 + 1.161 +void SuspendibleThreadSet::resume_all() { 1.162 + assert(_initialized, "Must be initialized."); 1.163 + MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); 1.164 + assert(_async_stopped == _async, "Huh."); 1.165 + _async_stop = false; 1.166 + _m->notify_all(); 1.167 +} 1.168 + 1.169 +static void _sltLoop(JavaThread* thread, TRAPS) { 1.170 + SurrogateLockerThread* slt = (SurrogateLockerThread*)thread; 1.171 + slt->loop(); 1.172 +} 1.173 + 1.174 +SurrogateLockerThread::SurrogateLockerThread() : 1.175 + JavaThread(&_sltLoop), 1.176 + _monitor(Mutex::nonleaf, "SLTMonitor"), 1.177 + _buffer(empty) 1.178 +{} 1.179 + 1.180 +SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) { 1.181 + Klass* k = 1.182 + SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), 1.183 + true, CHECK_NULL); 1.184 + instanceKlassHandle klass (THREAD, k); 1.185 + instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL); 1.186 + 1.187 + const char thread_name[] = "Surrogate Locker Thread (Concurrent GC)"; 1.188 + Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL); 1.189 + 1.190 + // Initialize thread_oop to put it into the system threadGroup 1.191 + Handle thread_group (THREAD, Universe::system_thread_group()); 1.192 + JavaValue result(T_VOID); 1.193 + JavaCalls::call_special(&result, thread_oop, 1.194 + klass, 1.195 + vmSymbols::object_initializer_name(), 1.196 + vmSymbols::threadgroup_string_void_signature(), 1.197 + thread_group, 1.198 + string, 1.199 + CHECK_NULL); 1.200 + 1.201 + SurrogateLockerThread* res; 1.202 + { 1.203 + MutexLocker mu(Threads_lock); 1.204 + res = new SurrogateLockerThread(); 1.205 + 1.206 + // At this point it may be possible that no osthread was created for the 1.207 + // JavaThread due to lack of memory. We would have to throw an exception 1.208 + // in that case. However, since this must work and we do not allow 1.209 + // exceptions anyway, check and abort if this fails. 1.210 + if (res == NULL || res->osthread() == NULL) { 1.211 + vm_exit_during_initialization("java.lang.OutOfMemoryError", 1.212 + "unable to create new native thread"); 1.213 + } 1.214 + java_lang_Thread::set_thread(thread_oop(), res); 1.215 + java_lang_Thread::set_priority(thread_oop(), NearMaxPriority); 1.216 + java_lang_Thread::set_daemon(thread_oop()); 1.217 + 1.218 + res->set_threadObj(thread_oop()); 1.219 + Threads::add(res); 1.220 + Thread::start(res); 1.221 + } 1.222 + os::yield(); // This seems to help with initial start-up of SLT 1.223 + return res; 1.224 +} 1.225 + 1.226 +void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) { 1.227 + MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag); 1.228 + assert(_buffer == empty, "Should be empty"); 1.229 + assert(msg != empty, "empty message"); 1.230 + assert(!Heap_lock->owned_by_self(), "Heap_lock owned by requesting thread"); 1.231 + 1.232 + _buffer = msg; 1.233 + while (_buffer != empty) { 1.234 + _monitor.notify(); 1.235 + _monitor.wait(Mutex::_no_safepoint_check_flag); 1.236 + } 1.237 +} 1.238 + 1.239 +// ======= Surrogate Locker Thread ============= 1.240 + 1.241 +void SurrogateLockerThread::loop() { 1.242 + BasicLock pll_basic_lock; 1.243 + SLT_msg_type msg; 1.244 + debug_only(unsigned int owned = 0;) 1.245 + 1.246 + while (/* !isTerminated() */ 1) { 1.247 + { 1.248 + MutexLocker x(&_monitor); 1.249 + // Since we are a JavaThread, we can't be here at a safepoint. 1.250 + assert(!SafepointSynchronize::is_at_safepoint(), 1.251 + "SLT is a JavaThread"); 1.252 + // wait for msg buffer to become non-empty 1.253 + while (_buffer == empty) { 1.254 + _monitor.notify(); 1.255 + _monitor.wait(); 1.256 + } 1.257 + msg = _buffer; 1.258 + } 1.259 + switch(msg) { 1.260 + case acquirePLL: { 1.261 + InstanceRefKlass::acquire_pending_list_lock(&pll_basic_lock); 1.262 + debug_only(owned++;) 1.263 + break; 1.264 + } 1.265 + case releaseAndNotifyPLL: { 1.266 + assert(owned > 0, "Don't have PLL"); 1.267 + InstanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock); 1.268 + debug_only(owned--;) 1.269 + break; 1.270 + } 1.271 + case empty: 1.272 + default: { 1.273 + guarantee(false,"Unexpected message in _buffer"); 1.274 + break; 1.275 + } 1.276 + } 1.277 + { 1.278 + MutexLocker x(&_monitor); 1.279 + // Since we are a JavaThread, we can't be here at a safepoint. 1.280 + assert(!SafepointSynchronize::is_at_safepoint(), 1.281 + "SLT is a JavaThread"); 1.282 + _buffer = empty; 1.283 + _monitor.notify(); 1.284 + } 1.285 + } 1.286 + assert(!_monitor.owned_by_self(), "Should unlock before exit."); 1.287 +} 1.288 + 1.289 + 1.290 +// ===== STS Access From Outside CGCT ===== 1.291 + 1.292 +void ConcurrentGCThread::stsYield(const char* id) { 1.293 + assert( Thread::current()->is_ConcurrentGC_thread(), 1.294 + "only a conc GC thread can call this" ); 1.295 + _sts.yield(id); 1.296 +} 1.297 + 1.298 +bool ConcurrentGCThread::stsShouldYield() { 1.299 + assert( Thread::current()->is_ConcurrentGC_thread(), 1.300 + "only a conc GC thread can call this" ); 1.301 + return _sts.should_yield(); 1.302 +} 1.303 + 1.304 +void ConcurrentGCThread::stsJoin() { 1.305 + assert( Thread::current()->is_ConcurrentGC_thread(), 1.306 + "only a conc GC thread can call this" ); 1.307 + _sts.join(); 1.308 +} 1.309 + 1.310 +void ConcurrentGCThread::stsLeave() { 1.311 + assert( Thread::current()->is_ConcurrentGC_thread(), 1.312 + "only a conc GC thread can call this" ); 1.313 + _sts.leave(); 1.314 +}