src/share/vm/gc_implementation/shared/concurrentGCThread.cpp

Tue, 05 Apr 2011 14:12:31 -0700

author
trims
date
Tue, 05 Apr 2011 14:12:31 -0700
changeset 2708
1d1603768966
parent 2497
3582bf76420e
child 2964
2a241e764894
permissions
-rw-r--r--

7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
Summary: Update the copyright to be 2010 on all changed files in OpenJDK
Reviewed-by: ohair

     1 /*
     2  * Copyright (c) 2001, 2011, 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  */
    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"
    35 // CopyrightVersion 1.2
    37 int  ConcurrentGCThread::_CGC_flag            = CGC_nil;
    39 SuspendibleThreadSet ConcurrentGCThread::_sts;
    41 ConcurrentGCThread::ConcurrentGCThread() :
    42   _should_terminate(false), _has_terminated(false) {
    43   _sts.initialize();
    44 };
    46 void ConcurrentGCThread::stopWorldAndDo(VoidClosure* op) {
    47   MutexLockerEx x(Heap_lock,
    48                   Mutex::_no_safepoint_check_flag);
    49   // warning("CGC: about to try stopping world");
    50   SafepointSynchronize::begin();
    51   // warning("CGC: successfully stopped world");
    52   op->do_void();
    53   SafepointSynchronize::end();
    54   // warning("CGC: successfully restarted world");
    55 }
    57 void ConcurrentGCThread::safepoint_synchronize() {
    58   _sts.suspend_all();
    59 }
    61 void ConcurrentGCThread::safepoint_desynchronize() {
    62   _sts.resume_all();
    63 }
    65 void ConcurrentGCThread::create_and_start() {
    66   if (os::create_thread(this, os::cgc_thread)) {
    67     // XXX: need to set this to low priority
    68     // unless "agressive mode" set; priority
    69     // should be just less than that of VMThread.
    70     os::set_priority(this, NearMaxPriority);
    71     if (!_should_terminate && !DisableStartThread) {
    72       os::start_thread(this);
    73     }
    74   }
    75 }
    77 void ConcurrentGCThread::initialize_in_thread() {
    78   this->record_stack_base_and_size();
    79   this->initialize_thread_local_storage();
    80   this->set_active_handles(JNIHandleBlock::allocate_block());
    81   // From this time Thread::current() should be working.
    82   assert(this == Thread::current(), "just checking");
    83 }
    85 void ConcurrentGCThread::wait_for_universe_init() {
    86   MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
    87   while (!is_init_completed() && !_should_terminate) {
    88     CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200);
    89   }
    90 }
    92 void ConcurrentGCThread::terminate() {
    93   // Signal that it is terminated
    94   {
    95     MutexLockerEx mu(Terminator_lock,
    96                      Mutex::_no_safepoint_check_flag);
    97     _has_terminated = true;
    98     Terminator_lock->notify();
    99   }
   101   // Thread destructor usually does this..
   102   ThreadLocalStorage::set_thread(NULL);
   103 }
   106 void SuspendibleThreadSet::initialize_work() {
   107   MutexLocker x(STS_init_lock);
   108   if (!_initialized) {
   109     _m             = new Monitor(Mutex::leaf,
   110                                  "SuspendibleThreadSetLock", true);
   111     _async         = 0;
   112     _async_stop    = false;
   113     _async_stopped = 0;
   114     _initialized   = true;
   115   }
   116 }
   118 void SuspendibleThreadSet::join() {
   119   initialize();
   120   MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
   121   while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
   122   _async++;
   123   assert(_async > 0, "Huh.");
   124 }
   126 void SuspendibleThreadSet::leave() {
   127   assert(_initialized, "Must be initialized.");
   128   MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
   129   _async--;
   130   assert(_async >= 0, "Huh.");
   131   if (_async_stop) _m->notify_all();
   132 }
   134 void SuspendibleThreadSet::yield(const char* id) {
   135   assert(_initialized, "Must be initialized.");
   136   if (_async_stop) {
   137     MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
   138     if (_async_stop) {
   139       _async_stopped++;
   140       assert(_async_stopped > 0, "Huh.");
   141       if (_async_stopped == _async) {
   142         if (ConcGCYieldTimeout > 0) {
   143           double now = os::elapsedTime();
   144           guarantee((now - _suspend_all_start) * 1000.0 <
   145                     (double)ConcGCYieldTimeout,
   146                     "Long delay; whodunit?");
   147         }
   148       }
   149       _m->notify_all();
   150       while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
   151       _async_stopped--;
   152       assert(_async >= 0, "Huh");
   153       _m->notify_all();
   154     }
   155   }
   156 }
   158 void SuspendibleThreadSet::suspend_all() {
   159   initialize();  // If necessary.
   160   if (ConcGCYieldTimeout > 0) {
   161     _suspend_all_start = os::elapsedTime();
   162   }
   163   MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
   164   assert(!_async_stop, "Only one at a time.");
   165   _async_stop = true;
   166   while (_async_stopped < _async) _m->wait(Mutex::_no_safepoint_check_flag);
   167 }
   169 void SuspendibleThreadSet::resume_all() {
   170   assert(_initialized, "Must be initialized.");
   171   MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
   172   assert(_async_stopped == _async, "Huh.");
   173   _async_stop = false;
   174   _m->notify_all();
   175 }
   177 static void _sltLoop(JavaThread* thread, TRAPS) {
   178   SurrogateLockerThread* slt = (SurrogateLockerThread*)thread;
   179   slt->loop();
   180 }
   182 SurrogateLockerThread::SurrogateLockerThread() :
   183   JavaThread(&_sltLoop),
   184   _monitor(Mutex::nonleaf, "SLTMonitor"),
   185   _buffer(empty)
   186 {}
   188 SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {
   189   klassOop k =
   190     SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(),
   191                                       true, CHECK_NULL);
   192   instanceKlassHandle klass (THREAD, k);
   193   instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
   195   const char thread_name[] = "Surrogate Locker Thread (Concurrent GC)";
   196   Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL);
   198   // Initialize thread_oop to put it into the system threadGroup
   199   Handle thread_group (THREAD, Universe::system_thread_group());
   200   JavaValue result(T_VOID);
   201   JavaCalls::call_special(&result, thread_oop,
   202                           klass,
   203                           vmSymbols::object_initializer_name(),
   204                           vmSymbols::threadgroup_string_void_signature(),
   205                           thread_group,
   206                           string,
   207                           CHECK_NULL);
   209   SurrogateLockerThread* res;
   210   {
   211     MutexLocker mu(Threads_lock);
   212     res = new SurrogateLockerThread();
   214     // At this point it may be possible that no osthread was created for the
   215     // JavaThread due to lack of memory. We would have to throw an exception
   216     // in that case. However, since this must work and we do not allow
   217     // exceptions anyway, check and abort if this fails.
   218     if (res == NULL || res->osthread() == NULL) {
   219       vm_exit_during_initialization("java.lang.OutOfMemoryError",
   220                                     "unable to create new native thread");
   221     }
   222     java_lang_Thread::set_thread(thread_oop(), res);
   223     java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
   224     java_lang_Thread::set_daemon(thread_oop());
   226     res->set_threadObj(thread_oop());
   227     Threads::add(res);
   228     Thread::start(res);
   229   }
   230   os::yield(); // This seems to help with initial start-up of SLT
   231   return res;
   232 }
   234 void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) {
   235   MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
   236   assert(_buffer == empty, "Should be empty");
   237   assert(msg != empty, "empty message");
   238   _buffer = msg;
   239   while (_buffer != empty) {
   240     _monitor.notify();
   241     _monitor.wait(Mutex::_no_safepoint_check_flag);
   242   }
   243 }
   245 // ======= Surrogate Locker Thread =============
   247 void SurrogateLockerThread::loop() {
   248   BasicLock pll_basic_lock;
   249   SLT_msg_type msg;
   250   debug_only(unsigned int owned = 0;)
   252   while (/* !isTerminated() */ 1) {
   253     {
   254       MutexLocker x(&_monitor);
   255       // Since we are a JavaThread, we can't be here at a safepoint.
   256       assert(!SafepointSynchronize::is_at_safepoint(),
   257              "SLT is a JavaThread");
   258       // wait for msg buffer to become non-empty
   259       while (_buffer == empty) {
   260         _monitor.notify();
   261         _monitor.wait();
   262       }
   263       msg = _buffer;
   264     }
   265     switch(msg) {
   266       case acquirePLL: {
   267         instanceRefKlass::acquire_pending_list_lock(&pll_basic_lock);
   268         debug_only(owned++;)
   269         break;
   270       }
   271       case releaseAndNotifyPLL: {
   272         assert(owned > 0, "Don't have PLL");
   273         instanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock);
   274         debug_only(owned--;)
   275         break;
   276       }
   277       case empty:
   278       default: {
   279         guarantee(false,"Unexpected message in _buffer");
   280         break;
   281       }
   282     }
   283     {
   284       MutexLocker x(&_monitor);
   285       // Since we are a JavaThread, we can't be here at a safepoint.
   286       assert(!SafepointSynchronize::is_at_safepoint(),
   287              "SLT is a JavaThread");
   288       _buffer = empty;
   289       _monitor.notify();
   290     }
   291   }
   292   assert(!_monitor.owned_by_self(), "Should unlock before exit.");
   293 }
   296 // ===== STS Access From Outside CGCT =====
   298 void ConcurrentGCThread::stsYield(const char* id) {
   299   assert( Thread::current()->is_ConcurrentGC_thread(),
   300           "only a conc GC thread can call this" );
   301   _sts.yield(id);
   302 }
   304 bool ConcurrentGCThread::stsShouldYield() {
   305   assert( Thread::current()->is_ConcurrentGC_thread(),
   306           "only a conc GC thread can call this" );
   307   return _sts.should_yield();
   308 }
   310 void ConcurrentGCThread::stsJoin() {
   311   assert( Thread::current()->is_ConcurrentGC_thread(),
   312           "only a conc GC thread can call this" );
   313   _sts.join();
   314 }
   316 void ConcurrentGCThread::stsLeave() {
   317   assert( Thread::current()->is_ConcurrentGC_thread(),
   318           "only a conc GC thread can call this" );
   319   _sts.leave();
   320 }

mercurial