1 /*
   2  * Copyright (c) 2001, 2012, 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_implementation/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 
  35 // CopyrightVersion 1.2
  36 
  37 int  ConcurrentGCThread::_CGC_flag            = CGC_nil;
  38 
  39 ConcurrentGCThread::ConcurrentGCThread() :
  40   _should_terminate(false), _has_terminated(false) {
  41 };
  42 
  43 void ConcurrentGCThread::create_and_start() {
  44   if (os::create_thread(this, os::cgc_thread)) {
  45     // XXX: need to set this to low priority
  46     // unless "agressive mode" set; priority
  47     // should be just less than that of VMThread.
  48     os::set_priority(this, NearMaxPriority);
  49     if (!_should_terminate && !DisableStartThread) {
  50       os::start_thread(this);
  51     }
  52   }
  53 }
  54 
  55 void ConcurrentGCThread::initialize_in_thread() {
  56   this->record_stack_base_and_size();
  57   this->initialize_thread_local_storage();
  58   this->set_active_handles(JNIHandleBlock::allocate_block());
  59   // From this time Thread::current() should be working.
  60   assert(this == Thread::current(), "just checking");
  61 }
  62 
  63 void ConcurrentGCThread::wait_for_universe_init() {
  64   MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
  65   while (!is_init_completed() && !_should_terminate) {
  66     CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200);
  67   }
  68 }
  69 
  70 void ConcurrentGCThread::terminate() {
  71   // Signal that it is terminated
  72   {
  73     MutexLockerEx mu(Terminator_lock,
  74                      Mutex::_no_safepoint_check_flag);
  75     _has_terminated = true;
  76     Terminator_lock->notify();
  77   }
  78 
  79   // Thread destructor usually does this..
  80   ThreadLocalStorage::set_thread(NULL);
  81 }
  82 
  83 static void _sltLoop(JavaThread* thread, TRAPS) {
  84   SurrogateLockerThread* slt = (SurrogateLockerThread*)thread;
  85   slt->loop();
  86 }
  87 
  88 SurrogateLockerThread::SurrogateLockerThread() :
  89   JavaThread(&_sltLoop),
  90   _monitor(Mutex::nonleaf, "SLTMonitor"),
  91   _buffer(empty)
  92 {}
  93 
  94 SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {
  95   Klass* k =
  96     SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(),
  97                                       true, CHECK_NULL);
  98   instanceKlassHandle klass (THREAD, k);
  99   instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
 100 
 101   const char thread_name[] = "Surrogate Locker Thread (Concurrent GC)";
 102   Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL);
 103 
 104   // Initialize thread_oop to put it into the system threadGroup
 105   Handle thread_group (THREAD, Universe::system_thread_group());
 106   JavaValue result(T_VOID);
 107   JavaCalls::call_special(&result, thread_oop,
 108                           klass,
 109                           vmSymbols::object_initializer_name(),
 110                           vmSymbols::threadgroup_string_void_signature(),
 111                           thread_group,
 112                           string,
 113                           CHECK_NULL);
 114 
 115   SurrogateLockerThread* res;
 116   {
 117     MutexLocker mu(Threads_lock);
 118     res = new SurrogateLockerThread();
 119 
 120     // At this point it may be possible that no osthread was created for the
 121     // JavaThread due to lack of memory. We would have to throw an exception
 122     // in that case. However, since this must work and we do not allow
 123     // exceptions anyway, check and abort if this fails.
 124     if (res == NULL || res->osthread() == NULL) {
 125       vm_exit_during_initialization("java.lang.OutOfMemoryError",
 126                                     "unable to create new native thread");
 127     }
 128     java_lang_Thread::set_thread(thread_oop(), res);
 129     java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
 130     java_lang_Thread::set_daemon(thread_oop());
 131 
 132     res->set_threadObj(thread_oop());
 133     Threads::add(res);
 134     Thread::start(res);
 135   }
 136   os::yield(); // This seems to help with initial start-up of SLT
 137   return res;
 138 }
 139 
 140 void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) {
 141   MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
 142   assert(_buffer == empty, "Should be empty");
 143   assert(msg != empty, "empty message");
 144   assert(!Heap_lock->owned_by_self(), "Heap_lock owned by requesting thread");
 145 
 146   _buffer = msg;
 147   while (_buffer != empty) {
 148     _monitor.notify();
 149     _monitor.wait(Mutex::_no_safepoint_check_flag);
 150   }
 151 }
 152 
 153 // ======= Surrogate Locker Thread =============
 154 
 155 void SurrogateLockerThread::loop() {
 156   BasicLock pll_basic_lock;
 157   SLT_msg_type msg;
 158   debug_only(unsigned int owned = 0;)
 159 
 160   while (/* !isTerminated() */ 1) {
 161     {
 162       MutexLocker x(&_monitor);
 163       // Since we are a JavaThread, we can't be here at a safepoint.
 164       assert(!SafepointSynchronize::is_at_safepoint(),
 165              "SLT is a JavaThread");
 166       // wait for msg buffer to become non-empty
 167       while (_buffer == empty) {
 168         _monitor.notify();
 169         _monitor.wait();
 170       }
 171       msg = _buffer;
 172     }
 173     switch(msg) {
 174       case acquirePLL: {
 175         InstanceRefKlass::acquire_pending_list_lock(&pll_basic_lock);
 176         debug_only(owned++;)
 177         break;
 178       }
 179       case releaseAndNotifyPLL: {
 180         assert(owned > 0, "Don't have PLL");
 181         InstanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock);
 182         debug_only(owned--;)
 183         break;
 184       }
 185       case empty:
 186       default: {
 187         guarantee(false,"Unexpected message in _buffer");
 188         break;
 189       }
 190     }
 191     {
 192       MutexLocker x(&_monitor);
 193       // Since we are a JavaThread, we can't be here at a safepoint.
 194       assert(!SafepointSynchronize::is_at_safepoint(),
 195              "SLT is a JavaThread");
 196       _buffer = empty;
 197       _monitor.notify();
 198     }
 199   }
 200   assert(!_monitor.owned_by_self(), "Should unlock before exit.");
 201 }