1 /*
   2  * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
   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  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "gc/shared/concurrentGCThread.hpp"
  28 #include "oops/instanceRefKlass.hpp"
  29 #include "oops/oop.inline.hpp"
  30 #include "runtime/init.hpp"
  31 #include "runtime/interfaceSupport.hpp"
  32 #include "runtime/java.hpp"
  33 #include "runtime/javaCalls.hpp"
  34 #include "runtime/os.hpp"
  35 
  36 ConcurrentGCThread::ConcurrentGCThread() :
  37   _should_terminate(false), _has_terminated(false) {
  38 };
  39 
  40 void ConcurrentGCThread::create_and_start() {
  41   if (os::create_thread(this, os::cgc_thread)) {
  42     // XXX: need to set this to low priority
  43     // unless "aggressive mode" set; priority
  44     // should be just less than that of VMThread.
  45     os::set_priority(this, NearMaxPriority);
  46     if (!_should_terminate && !DisableStartThread) {
  47       os::start_thread(this);
  48     }
  49   }
  50 }
  51 
  52 void ConcurrentGCThread::initialize_in_thread() {
  53   this->record_stack_base_and_size();
  54   this->initialize_named_thread();
  55   this->set_active_handles(JNIHandleBlock::allocate_block());
  56   // From this time Thread::current() should be working.
  57   assert(this == Thread::current(), "just checking");
  58 }
  59 
  60 void ConcurrentGCThread::wait_for_universe_init() {
  61   MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
  62   while (!is_init_completed() && !_should_terminate) {
  63     CGC_lock->wait(Mutex::_no_safepoint_check_flag, 1);
  64   }
  65 }
  66 
  67 void ConcurrentGCThread::terminate() {
  68   assert(_should_terminate, "Should only be called on terminate request.");
  69   // Signal that it is terminated
  70   {
  71     MutexLockerEx mu(Terminator_lock,
  72                      Mutex::_no_safepoint_check_flag);
  73     _has_terminated = true;
  74     Terminator_lock->notify();
  75   }
  76 }
  77 
  78 void ConcurrentGCThread::run() {
  79   initialize_in_thread();
  80   wait_for_universe_init();
  81 
  82   run_service();
  83 
  84   terminate();
  85 }
  86 
  87 void ConcurrentGCThread::stop() {
  88   // it is ok to take late safepoints here, if needed
  89   {
  90     MutexLockerEx mu(Terminator_lock);
  91     _should_terminate = true;
  92   }
  93 
  94   stop_service();
  95 
  96   {
  97     MutexLockerEx mu(Terminator_lock);
  98     while (!_has_terminated) {
  99       Terminator_lock->wait();
 100     }
 101   }
 102 }
 103 
 104 static void _sltLoop(JavaThread* thread, TRAPS) {
 105   SurrogateLockerThread* slt = (SurrogateLockerThread*)thread;
 106   slt->loop();
 107 }
 108 
 109 SurrogateLockerThread::SurrogateLockerThread() :
 110   JavaThread(&_sltLoop),
 111   _monitor(Mutex::nonleaf, "SLTMonitor", false,
 112            Monitor::_safepoint_check_sometimes),
 113   _buffer(empty)
 114 {}
 115 
 116 SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {
 117   Klass* k =
 118     SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(),
 119                                       true, CHECK_NULL);
 120   instanceKlassHandle klass (THREAD, k);
 121   instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
 122 
 123   const char thread_name[] = "Surrogate Locker Thread (Concurrent GC)";
 124   Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL);
 125 
 126   // Initialize thread_oop to put it into the system threadGroup
 127   Handle thread_group (THREAD, Universe::system_thread_group());
 128   JavaValue result(T_VOID);
 129   JavaCalls::call_special(&result, thread_oop,
 130                           klass,
 131                           vmSymbols::object_initializer_name(),
 132                           vmSymbols::threadgroup_string_void_signature(),
 133                           thread_group,
 134                           string,
 135                           CHECK_NULL);
 136 
 137   SurrogateLockerThread* res;
 138   {
 139     MutexLocker mu(Threads_lock);
 140     res = new SurrogateLockerThread();
 141 
 142     // At this point it may be possible that no osthread was created for the
 143     // JavaThread due to lack of memory. We would have to throw an exception
 144     // in that case. However, since this must work and we do not allow
 145     // exceptions anyway, check and abort if this fails.
 146     if (res == NULL || res->osthread() == NULL) {
 147       vm_exit_during_initialization("java.lang.OutOfMemoryError",
 148                                     os::native_thread_creation_failed_msg());
 149     }
 150     java_lang_Thread::set_thread(thread_oop(), res);
 151     java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
 152     java_lang_Thread::set_daemon(thread_oop());
 153 
 154     res->set_threadObj(thread_oop());
 155     Threads::add(res);
 156     Thread::start(res);
 157   }
 158   os::naked_yield(); // This seems to help with initial start-up of SLT
 159   return res;
 160 }
 161 
 162 void SurrogateLockerThread::report_missing_slt() {
 163   vm_exit_during_initialization(
 164     "GC before GC support fully initialized: "
 165     "SLT is needed but has not yet been created.");
 166   ShouldNotReachHere();
 167 }
 168 
 169 void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) {
 170   MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
 171   assert(_buffer == empty, "Should be empty");
 172   assert(msg != empty, "empty message");
 173   assert(!Heap_lock->owned_by_self(), "Heap_lock owned by requesting thread");
 174 
 175   _buffer = msg;
 176   while (_buffer != empty) {
 177     _monitor.notify();
 178     _monitor.wait(Mutex::_no_safepoint_check_flag);
 179   }
 180 }
 181 
 182 // ======= Surrogate Locker Thread =============
 183 
 184 void SurrogateLockerThread::loop() {
 185   BasicLock pll_basic_lock;
 186   SLT_msg_type msg;
 187   debug_only(unsigned int owned = 0;)
 188 
 189   while (/* !isTerminated() */ 1) {
 190     {
 191       MutexLocker x(&_monitor);
 192       // Since we are a JavaThread, we can't be here at a safepoint.
 193       assert(!SafepointSynchronize::is_at_safepoint(),
 194              "SLT is a JavaThread");
 195       // wait for msg buffer to become non-empty
 196       while (_buffer == empty) {
 197         _monitor.notify();
 198         _monitor.wait();
 199       }
 200       msg = _buffer;
 201     }
 202     switch(msg) {
 203       case acquirePLL: {
 204         InstanceRefKlass::acquire_pending_list_lock(&pll_basic_lock);
 205         debug_only(owned++;)
 206         break;
 207       }
 208       case releaseAndNotifyPLL: {
 209         assert(owned > 0, "Don't have PLL");
 210         InstanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock);
 211         debug_only(owned--;)
 212         break;
 213       }
 214       case empty:
 215       default: {
 216         guarantee(false,"Unexpected message in _buffer");
 217         break;
 218       }
 219     }
 220     {
 221       MutexLocker x(&_monitor);
 222       // Since we are a JavaThread, we can't be here at a safepoint.
 223       assert(!SafepointSynchronize::is_at_safepoint(),
 224              "SLT is a JavaThread");
 225       _buffer = empty;
 226       _monitor.notify();
 227     }
 228   }
 229   assert(!_monitor.owned_by_self(), "Should unlock before exit.");
 230 }