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

Tue, 22 Sep 2009 14:06:10 -0700

author
xdono
date
Tue, 22 Sep 2009 14:06:10 -0700
changeset 1383
89e0543e1737
parent 1279
bd02caa94611
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6884624: Update copyright year
Summary: Update copyright for files that have been modified in 2009 through Septermber
Reviewed-by: tbell, ohair

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

mercurial