hotspot/src/share/vm/gc/g1/suspendibleThreadSet.cpp
changeset 37188 390e3a2e7cee
parent 30764 fec48bf5a827
equal deleted inserted replaced
37185:7fd17c40a180 37188:390e3a2e7cee
     1 /*
     1 /*
     2  * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "gc/g1/suspendibleThreadSet.hpp"
    26 #include "gc/g1/suspendibleThreadSet.hpp"
    27 #include "runtime/mutexLocker.hpp"
    27 #include "runtime/mutexLocker.hpp"
       
    28 #include "runtime/semaphore.hpp"
    28 #include "runtime/thread.inline.hpp"
    29 #include "runtime/thread.inline.hpp"
    29 
    30 
    30 uint   SuspendibleThreadSet::_nthreads          = 0;
    31 uint   SuspendibleThreadSet::_nthreads          = 0;
    31 uint   SuspendibleThreadSet::_nthreads_stopped  = 0;
    32 uint   SuspendibleThreadSet::_nthreads_stopped  = 0;
    32 bool   SuspendibleThreadSet::_suspend_all       = false;
    33 bool   SuspendibleThreadSet::_suspend_all       = false;
    33 double SuspendibleThreadSet::_suspend_all_start = 0.0;
    34 double SuspendibleThreadSet::_suspend_all_start = 0.0;
       
    35 
       
    36 static Semaphore* _synchronize_wakeup = NULL;
       
    37 
       
    38 void SuspendibleThreadSet_init() {
       
    39   assert(_synchronize_wakeup == NULL, "STS already initialized");
       
    40   _synchronize_wakeup = new Semaphore();
       
    41 }
       
    42 
       
    43 bool SuspendibleThreadSet::is_synchronized() {
       
    44   assert_lock_strong(STS_lock);
       
    45   assert(_nthreads_stopped <= _nthreads, "invariant");
       
    46   return _nthreads_stopped == _nthreads;
       
    47 }
    34 
    48 
    35 void SuspendibleThreadSet::join() {
    49 void SuspendibleThreadSet::join() {
    36   assert(!Thread::current()->is_suspendible_thread(), "Thread already joined");
    50   assert(!Thread::current()->is_suspendible_thread(), "Thread already joined");
    37   MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
    51   MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
    38   while (_suspend_all) {
    52   while (_suspend_all) {
    46   assert(Thread::current()->is_suspendible_thread(), "Thread not joined");
    60   assert(Thread::current()->is_suspendible_thread(), "Thread not joined");
    47   MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
    61   MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
    48   assert(_nthreads > 0, "Invalid");
    62   assert(_nthreads > 0, "Invalid");
    49   DEBUG_ONLY(Thread::current()->clear_suspendible_thread();)
    63   DEBUG_ONLY(Thread::current()->clear_suspendible_thread();)
    50   _nthreads--;
    64   _nthreads--;
    51   if (_suspend_all) {
    65   if (_suspend_all && is_synchronized()) {
    52     ml.notify_all();
    66     // This leave completes a request, so inform the requestor.
       
    67     _synchronize_wakeup->signal();
    53   }
    68   }
    54 }
    69 }
    55 
    70 
    56 void SuspendibleThreadSet::yield() {
    71 void SuspendibleThreadSet::yield() {
    57   assert(Thread::current()->is_suspendible_thread(), "Must have joined");
    72   assert(Thread::current()->is_suspendible_thread(), "Must have joined");
       
    73   MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
    58   if (_suspend_all) {
    74   if (_suspend_all) {
    59     MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
    75     _nthreads_stopped++;
    60     if (_suspend_all) {
    76     if (is_synchronized()) {
    61       _nthreads_stopped++;
    77       if (ConcGCYieldTimeout > 0) {
    62       if (_nthreads_stopped == _nthreads) {
    78         double now = os::elapsedTime();
    63         if (ConcGCYieldTimeout > 0) {
    79         guarantee((now - _suspend_all_start) * 1000.0 < (double)ConcGCYieldTimeout, "Long delay");
    64           double now = os::elapsedTime();
       
    65           guarantee((now - _suspend_all_start) * 1000.0 < (double)ConcGCYieldTimeout, "Long delay");
       
    66         }
       
    67       }
    80       }
    68       ml.notify_all();
    81       // This yield completes the request, so inform the requestor.
    69       while (_suspend_all) {
    82       _synchronize_wakeup->signal();
    70         ml.wait(Mutex::_no_safepoint_check_flag);
       
    71       }
       
    72       assert(_nthreads_stopped > 0, "Invalid");
       
    73       _nthreads_stopped--;
       
    74       ml.notify_all();
       
    75     }
    83     }
       
    84     while (_suspend_all) {
       
    85       ml.wait(Mutex::_no_safepoint_check_flag);
       
    86     }
       
    87     assert(_nthreads_stopped > 0, "Invalid");
       
    88     _nthreads_stopped--;
    76   }
    89   }
    77 }
    90 }
    78 
    91 
    79 void SuspendibleThreadSet::synchronize() {
    92 void SuspendibleThreadSet::synchronize() {
    80   assert(Thread::current()->is_VM_thread(), "Must be the VM thread");
    93   assert(Thread::current()->is_VM_thread(), "Must be the VM thread");
    81   if (ConcGCYieldTimeout > 0) {
    94   if (ConcGCYieldTimeout > 0) {
    82     _suspend_all_start = os::elapsedTime();
    95     _suspend_all_start = os::elapsedTime();
    83   }
    96   }
       
    97   {
       
    98     MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
       
    99     assert(!_suspend_all, "Only one at a time");
       
   100     _suspend_all = true;
       
   101     if (is_synchronized()) {
       
   102       return;
       
   103     }
       
   104   } // Release lock before semaphore wait.
       
   105 
       
   106   // Semaphore initial count is zero.  To reach here, there must be at
       
   107   // least one not yielded thread in the set, e.g. is_synchronized()
       
   108   // was false before the lock was released.  A thread in the set will
       
   109   // signal the semaphore iff it is the last to yield or leave while
       
   110   // there is an active suspend request.  So there will be exactly one
       
   111   // signal, which will increment the semaphore count to one, which
       
   112   // will then be consumed by this wait, returning it to zero.  No
       
   113   // thread can exit yield or enter the set until desynchronize is
       
   114   // called, so there are no further opportunities for the semaphore
       
   115   // being signaled until we get back here again for some later
       
   116   // synchronize call.  Hence, there is no need to re-check for
       
   117   // is_synchronized after the wait; it will always be true there.
       
   118   _synchronize_wakeup->wait();
       
   119 
       
   120 #ifdef ASSERT
    84   MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
   121   MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
    85   assert(!_suspend_all, "Only one at a time");
   122   assert(_suspend_all, "STS not synchronizing");
    86   _suspend_all = true;
   123   assert(is_synchronized(), "STS not synchronized");
    87   while (_nthreads_stopped < _nthreads) {
   124 #endif
    88     ml.wait(Mutex::_no_safepoint_check_flag);
       
    89   }
       
    90 }
   125 }
    91 
   126 
    92 void SuspendibleThreadSet::desynchronize() {
   127 void SuspendibleThreadSet::desynchronize() {
    93   assert(Thread::current()->is_VM_thread(), "Must be the VM thread");
   128   assert(Thread::current()->is_VM_thread(), "Must be the VM thread");
    94   MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
   129   MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
    95   assert(_nthreads_stopped == _nthreads, "Invalid");
   130   assert(_suspend_all, "STS not synchronizing");
       
   131   assert(is_synchronized(), "STS not synchronized");
    96   _suspend_all = false;
   132   _suspend_all = false;
    97   ml.notify_all();
   133   ml.notify_all();
    98 }
   134 }