src/hotspot/share/runtime/threadSMR.cpp
changeset 48105 8d15b1369c7a
child 48312 2a1413298af0
equal deleted inserted replaced
48096:513e0b467a92 48105:8d15b1369c7a
       
     1 /*
       
     2  * Copyright (c) 2017, 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 "memory/allocation.inline.hpp"
       
    27 #include "runtime/thread.inline.hpp"
       
    28 #include "runtime/threadSMR.hpp"
       
    29 #include "services/threadService.hpp"
       
    30 
       
    31 // 'entries + 1' so we always have at least one entry.
       
    32 ThreadsList::ThreadsList(int entries) : _length(entries), _threads(NEW_C_HEAP_ARRAY(JavaThread*, entries + 1, mtThread)), _next_list(NULL) {
       
    33   *(JavaThread**)(_threads + entries) = NULL;  // Make sure the extra entry is NULL.
       
    34 }
       
    35 
       
    36 ThreadsList::~ThreadsList() {
       
    37   FREE_C_HEAP_ARRAY(JavaThread*, _threads);
       
    38 }
       
    39 
       
    40 ThreadsListSetter::~ThreadsListSetter() {
       
    41   if (_target_needs_release) {
       
    42     // The hazard ptr in the target needs to be released.
       
    43     Threads::release_stable_list(_target);
       
    44   }
       
    45 }
       
    46 
       
    47 void ThreadsListSetter::set() {
       
    48   assert(_target->get_threads_hazard_ptr() == NULL, "hazard ptr should not already be set");
       
    49   (void) Threads::acquire_stable_list(_target, /* is_ThreadsListSetter */ true);
       
    50   _target_needs_release = true;
       
    51 }
       
    52 
       
    53 ThreadsListHandle::ThreadsListHandle(Thread *self) : _list(Threads::acquire_stable_list(self, /* is_ThreadsListSetter */ false)), _self(self) {
       
    54   assert(self == Thread::current(), "sanity check");
       
    55   if (EnableThreadSMRStatistics) {
       
    56     _timer.start();
       
    57   }
       
    58 }
       
    59 
       
    60 ThreadsListHandle::~ThreadsListHandle() {
       
    61   Threads::release_stable_list(_self);
       
    62   if (EnableThreadSMRStatistics) {
       
    63     _timer.stop();
       
    64     uint millis = (uint)_timer.milliseconds();
       
    65     Threads::inc_smr_tlh_cnt();
       
    66     Threads::add_smr_tlh_times(millis);
       
    67     Threads::update_smr_tlh_time_max(millis);
       
    68   }
       
    69 }
       
    70 
       
    71 // Convert an internal thread reference to a JavaThread found on the
       
    72 // associated ThreadsList. This ThreadsListHandle "protects" the
       
    73 // returned JavaThread *.
       
    74 //
       
    75 // If thread_oop_p is not NULL, then the caller wants to use the oop
       
    76 // after this call so the oop is returned. On success, *jt_pp is set
       
    77 // to the converted JavaThread * and true is returned. On error,
       
    78 // returns false.
       
    79 //
       
    80 bool ThreadsListHandle::cv_internal_thread_to_JavaThread(jobject jthread,
       
    81                                                          JavaThread ** jt_pp,
       
    82                                                          oop * thread_oop_p) {
       
    83   assert(this->list() != NULL, "must have a ThreadsList");
       
    84   assert(jt_pp != NULL, "must have a return JavaThread pointer");
       
    85   // thread_oop_p is optional so no assert()
       
    86 
       
    87   // The JVM_* interfaces don't allow a NULL thread parameter; JVM/TI
       
    88   // allows a NULL thread parameter to signify "current thread" which
       
    89   // allows us to avoid calling cv_external_thread_to_JavaThread().
       
    90   // The JVM_* interfaces have no such leeway.
       
    91 
       
    92   oop thread_oop = JNIHandles::resolve_non_null(jthread);
       
    93   // Looks like an oop at this point.
       
    94   if (thread_oop_p != NULL) {
       
    95     // Return the oop to the caller; the caller may still want
       
    96     // the oop even if this function returns false.
       
    97     *thread_oop_p = thread_oop;
       
    98   }
       
    99 
       
   100   JavaThread *java_thread = java_lang_Thread::thread(thread_oop);
       
   101   if (java_thread == NULL) {
       
   102     // The java.lang.Thread does not contain a JavaThread * so it has
       
   103     // not yet run or it has died.
       
   104     return false;
       
   105   }
       
   106   // Looks like a live JavaThread at this point.
       
   107 
       
   108   if (java_thread != JavaThread::current()) {
       
   109     // jthread is not for the current JavaThread so have to verify
       
   110     // the JavaThread * against the ThreadsList.
       
   111     if (EnableThreadSMRExtraValidityChecks && !includes(java_thread)) {
       
   112       // Not on the JavaThreads list so it is not alive.
       
   113       return false;
       
   114     }
       
   115   }
       
   116 
       
   117   // Return a live JavaThread that is "protected" by the
       
   118   // ThreadsListHandle in the caller.
       
   119   *jt_pp = java_thread;
       
   120   return true;
       
   121 }