< prev index next >

src/hotspot/share/runtime/threadSMR.cpp

Print this page


   1 /*
   2  * Copyright (c) 2017, 2019, 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  *


 933     // This list is smaller so no need to check for a "longest" update.
 934   }
 935 
 936   // Final _java_thread_list will not generate a "Threads::remove" mesg.
 937   log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::remove: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list));
 938 
 939   ThreadsList *old_list = ThreadsSMRSupport::xchg_java_thread_list(new_list);
 940   ThreadsSMRSupport::free_list(old_list);
 941 }
 942 
 943 // See note for clear_delete_notify().
 944 //
 945 void ThreadsSMRSupport::set_delete_notify() {
 946   Atomic::inc(&_delete_notify);
 947 }
 948 
 949 // Safely delete a JavaThread when it is no longer in use by a
 950 // ThreadsListHandle.
 951 //
 952 void ThreadsSMRSupport::smr_delete(JavaThread *thread) {
 953   assert(!Threads_lock->owned_by_self(), "sanity");
 954 
 955   bool has_logged_once = false;
 956   elapsedTimer timer;
 957   if (EnableThreadSMRStatistics) {
 958     timer.start();
 959   }
 960 



















 961   while (true) {
 962     {
 963       // Will not make a safepoint check because this JavaThread
 964       // is not on the current ThreadsList.
 965       MutexLocker ml(Threads_lock);
 966       // Cannot use a MonitorLocker helper here because we have
 967       // to drop the Threads_lock first if we wait.
 968       ThreadsSMRSupport::delete_lock()->lock_without_safepoint_check();
 969       // Set the delete_notify flag after we grab delete_lock
 970       // and before we scan hazard ptrs because we're doing
 971       // double-check locking in release_stable_list().
 972       ThreadsSMRSupport::set_delete_notify();
 973 
 974       if (!is_a_protected_JavaThread(thread)) {
 975         // This is the common case.
 976         ThreadsSMRSupport::clear_delete_notify();
 977         ThreadsSMRSupport::delete_lock()->unlock();
 978         break;
 979       }
 980       if (!has_logged_once) {
 981         has_logged_once = true;
 982         log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is not deleted.", os::current_thread_id(), p2i(thread));
 983         if (log_is_enabled(Debug, os, thread)) {
 984           ScanHazardPtrPrintMatchingThreadsClosure scan_cl(thread);
 985           threads_do(&scan_cl);
 986           ThreadsList* current = _to_delete_list;
 987           while (current != NULL) {
 988             if (current->_nested_handle_cnt != 0 && current->includes(thread)) {
 989               log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: found nested hazard pointer to thread=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread));
 990             }
 991             current = current->next_list();
 992           }
 993         }
 994       }
 995     } // We have to drop the Threads_lock to wait or delete the thread
 996 
 997     if (EnableThreadSMRStatistics) {
 998       _delete_lock_wait_cnt++;
 999       if (_delete_lock_wait_cnt > _delete_lock_wait_max) {
1000         _delete_lock_wait_max = _delete_lock_wait_cnt;
1001       }
1002     }
1003     // Wait for a release_stable_list() call before we check again. No
1004     // safepoint check, no timeout, and not as suspend equivalent flag
1005     // because this JavaThread is not on the Threads list.
1006     ThreadsSMRSupport::delete_lock()->wait_without_safepoint_check();
1007     if (EnableThreadSMRStatistics) {
1008       _delete_lock_wait_cnt--;
1009     }
1010 
1011     ThreadsSMRSupport::clear_delete_notify();
1012     ThreadsSMRSupport::delete_lock()->unlock();
1013     // Retry the whole scenario.
1014   }
1015 
1016   delete thread;
1017   if (EnableThreadSMRStatistics) {
1018     timer.stop();
1019     uint millis = (uint)timer.milliseconds();
1020     ThreadsSMRSupport::inc_deleted_thread_cnt();
1021     ThreadsSMRSupport::add_deleted_thread_times(millis);
1022     ThreadsSMRSupport::update_deleted_thread_time_max(millis);
1023   }
1024 
1025   log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is deleted.", os::current_thread_id(), p2i(thread));
1026 }
1027 
1028 // Apply the closure to all threads in the system, with a snapshot of
1029 // all JavaThreads provided by the list parameter.
1030 void ThreadsSMRSupport::threads_do(ThreadClosure *tc, ThreadsList *list) {
1031   list->threads_do(tc);
1032   Threads::non_java_threads_do(tc);
1033 }
1034 
1035 // Apply the closure to all threads in the system.
1036 void ThreadsSMRSupport::threads_do(ThreadClosure *tc) {
1037   threads_do(tc, _java_thread_list);
1038 }
1039 
1040 
1041 // Debug, logging, and printing stuff at the end:
1042 
1043 // Print SMR info for a SafeThreadsListPtr to a given output stream.
1044 void SafeThreadsListPtr::print_on(outputStream* st) {
1045   if (this == _thread->_threads_list_ptr) {


   1 /*
   2  * Copyright (c) 2017, 2020, 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  *


 933     // This list is smaller so no need to check for a "longest" update.
 934   }
 935 
 936   // Final _java_thread_list will not generate a "Threads::remove" mesg.
 937   log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::remove: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list));
 938 
 939   ThreadsList *old_list = ThreadsSMRSupport::xchg_java_thread_list(new_list);
 940   ThreadsSMRSupport::free_list(old_list);
 941 }
 942 
 943 // See note for clear_delete_notify().
 944 //
 945 void ThreadsSMRSupport::set_delete_notify() {
 946   Atomic::inc(&_delete_notify);
 947 }
 948 
 949 // Safely delete a JavaThread when it is no longer in use by a
 950 // ThreadsListHandle.
 951 //
 952 void ThreadsSMRSupport::smr_delete(JavaThread *thread) {



 953   elapsedTimer timer;
 954   if (EnableThreadSMRStatistics) {
 955     timer.start();
 956   }
 957 
 958   wait_until_not_protected(thread);
 959 
 960   delete thread;
 961   if (EnableThreadSMRStatistics) {
 962     timer.stop();
 963     uint millis = (uint)timer.milliseconds();
 964     ThreadsSMRSupport::inc_deleted_thread_cnt();
 965     ThreadsSMRSupport::add_deleted_thread_times(millis);
 966     ThreadsSMRSupport::update_deleted_thread_time_max(millis);
 967   }
 968 
 969   log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is deleted.", os::current_thread_id(), p2i(thread));
 970 }
 971 
 972 void ThreadsSMRSupport::wait_until_not_protected(JavaThread *thread) {
 973   assert(!Threads_lock->owned_by_self(), "sanity");
 974 
 975   bool has_logged_once = false;
 976 
 977   while (true) {
 978     {
 979       // Will not make a safepoint check because this JavaThread
 980       // is not on the current ThreadsList.
 981       MutexLocker ml(Threads_lock);
 982       // Cannot use a MonitorLocker helper here because we have
 983       // to drop the Threads_lock first if we wait.
 984       ThreadsSMRSupport::delete_lock()->lock_without_safepoint_check();
 985       // Set the delete_notify flag after we grab delete_lock
 986       // and before we scan hazard ptrs because we're doing
 987       // double-check locking in release_stable_list().
 988       ThreadsSMRSupport::set_delete_notify();
 989 
 990       if (!is_a_protected_JavaThread(thread)) {
 991         // This is the common case.
 992         ThreadsSMRSupport::clear_delete_notify();
 993         ThreadsSMRSupport::delete_lock()->unlock();
 994         break;
 995       }
 996       if (!has_logged_once) {
 997         has_logged_once = true;
 998         log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::wait_until_not_protected: thread=" INTPTR_FORMAT " is not deleted.", os::current_thread_id(), p2i(thread));
 999         if (log_is_enabled(Debug, os, thread)) {
1000           ScanHazardPtrPrintMatchingThreadsClosure scan_cl(thread);
1001           threads_do(&scan_cl);
1002           ThreadsList* current = _to_delete_list;
1003           while (current != NULL) {
1004             if (current->_nested_handle_cnt != 0 && current->includes(thread)) {
1005               log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::wait_until_not_protected: found nested hazard pointer to thread=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread));
1006             }
1007             current = current->next_list();
1008           }
1009         }
1010       }
1011     } // We have to drop the Threads_lock to wait or delete the thread
1012 
1013     if (EnableThreadSMRStatistics) {
1014       _delete_lock_wait_cnt++;
1015       if (_delete_lock_wait_cnt > _delete_lock_wait_max) {
1016         _delete_lock_wait_max = _delete_lock_wait_cnt;
1017       }
1018     }
1019     // Wait for a release_stable_list() call before we check again. No
1020     // safepoint check, no timeout, and not as suspend equivalent flag
1021     // because this JavaThread is not on the Threads list.
1022     ThreadsSMRSupport::delete_lock()->wait_without_safepoint_check();
1023     if (EnableThreadSMRStatistics) {
1024       _delete_lock_wait_cnt--;
1025     }
1026 
1027     ThreadsSMRSupport::clear_delete_notify();
1028     ThreadsSMRSupport::delete_lock()->unlock();
1029     // Retry the whole scenario.
1030   }











1031 }
1032 
1033 // Apply the closure to all threads in the system, with a snapshot of
1034 // all JavaThreads provided by the list parameter.
1035 void ThreadsSMRSupport::threads_do(ThreadClosure *tc, ThreadsList *list) {
1036   list->threads_do(tc);
1037   Threads::non_java_threads_do(tc);
1038 }
1039 
1040 // Apply the closure to all threads in the system.
1041 void ThreadsSMRSupport::threads_do(ThreadClosure *tc) {
1042   threads_do(tc, _java_thread_list);
1043 }
1044 
1045 
1046 // Debug, logging, and printing stuff at the end:
1047 
1048 // Print SMR info for a SafeThreadsListPtr to a given output stream.
1049 void SafeThreadsListPtr::print_on(outputStream* st) {
1050   if (this == _thread->_threads_list_ptr) {


< prev index next >