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