/*
 * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "classfile/javaClasses.inline.hpp"
#include "logging/logStream.hpp"
#include "memory/allocation.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/javaThread.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/orderAccess.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threads.hpp"
#include "runtime/threadSMR.inline.hpp"
#include "runtime/vmOperations.hpp"
#include "services/threadIdTable.hpp"
#include "services/threadService.hpp"
#include "utilities/copy.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/ostream.hpp"
#include "utilities/powerOfTwo.hpp"
#include "utilities/resourceHash.hpp"
#include "utilities/vmError.hpp"

// The '_cnt', '_max' and '_times" fields are enabled via
// -XX:+EnableThreadSMRStatistics:

// # of parallel threads in _delete_lock->wait().
// Impl note: Hard to imagine > 64K waiting threads so this could be 16-bit,
// but there is no nice 16-bit _FORMAT support.
uint                  ThreadsSMRSupport::_delete_lock_wait_cnt = 0;

// Max # of parallel threads in _delete_lock->wait().
// Impl note: See _delete_lock_wait_cnt note.
uint                  ThreadsSMRSupport::_delete_lock_wait_max = 0;

// Flag to indicate when an _delete_lock->notify() is needed.
// Impl note: See _delete_lock_wait_cnt note.
volatile uint         ThreadsSMRSupport::_delete_notify = 0;

// # of threads deleted over VM lifetime.
// Impl note: Atomically incremented over VM lifetime so use unsigned for more
// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc
// isn't available everywhere (or is it?).
volatile uint         ThreadsSMRSupport::_deleted_thread_cnt = 0;

// Max time in millis to delete a thread.
// Impl note: 16-bit might be too small on an overloaded machine. Use
// unsigned since this is a time value. Set via Atomic::cmpxchg() in a
// loop for correctness.
volatile uint         ThreadsSMRSupport::_deleted_thread_time_max = 0;

// Cumulative time in millis to delete threads.
// Impl note: Atomically added to over VM lifetime so use unsigned for more
// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc
// isn't available everywhere (or is it?).
volatile uint         ThreadsSMRSupport::_deleted_thread_times = 0;

// The bootstrap list is empty and cannot be freed.
ThreadsList ThreadsSMRSupport::_bootstrap_list{0};

// This is the VM's current "threads list" and it contains all of
// the JavaThreads the VM considers to be alive at this moment in
// time. The other ThreadsList objects in the VM contain past
// snapshots of the "threads list". _java_thread_list is initially
// set to _bootstrap_list so that we can detect when we have a very
// early use of a ThreadsListHandle.
ThreadsList* volatile ThreadsSMRSupport::_java_thread_list = &_bootstrap_list;

// # of ThreadsLists allocated over VM lifetime.
// Impl note: We allocate a new ThreadsList for every thread create and
// every thread delete so we need a bigger type than the
// _deleted_thread_cnt field.
uint64_t              ThreadsSMRSupport::_java_thread_list_alloc_cnt = 1;

// # of ThreadsLists freed over VM lifetime.
// Impl note: See _java_thread_list_alloc_cnt note.
uint64_t              ThreadsSMRSupport::_java_thread_list_free_cnt = 0;

// Max size ThreadsList allocated.
// Impl note: Max # of threads alive at one time should fit in unsigned 32-bit.
uint                  ThreadsSMRSupport::_java_thread_list_max = 0;

// Max # of nested ThreadsLists for a thread.
// Impl note: Hard to imagine > 64K nested ThreadsLists so this could be
// 16-bit, but there is no nice 16-bit _FORMAT support.
uint                  ThreadsSMRSupport::_nested_thread_list_max = 0;

// # of ThreadsListHandles deleted over VM lifetime.
// Impl note: Atomically incremented over VM lifetime so use unsigned for
// more range. There will be fewer ThreadsListHandles than threads so
// unsigned 32-bit should be fine.
volatile uint         ThreadsSMRSupport::_tlh_cnt = 0;

// Max time in millis to delete a ThreadsListHandle.
// Impl note: 16-bit might be too small on an overloaded machine. Use
// unsigned since this is a time value. Set via Atomic::cmpxchg() in a
// loop for correctness.
volatile uint         ThreadsSMRSupport::_tlh_time_max = 0;

// Cumulative time in millis to delete ThreadsListHandles.
// Impl note: Atomically added to over VM lifetime so use unsigned for more
// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc
// isn't available everywhere (or is it?).
volatile uint         ThreadsSMRSupport::_tlh_times = 0;

ThreadsList*          ThreadsSMRSupport::_to_delete_list = nullptr;

// # of parallel ThreadsLists on the to-delete list.
// Impl note: Hard to imagine > 64K ThreadsLists needing to be deleted so
// this could be 16-bit, but there is no nice 16-bit _FORMAT support.
uint                  ThreadsSMRSupport::_to_delete_list_cnt = 0;

// Max # of parallel ThreadsLists on the to-delete list.
// Impl note: See _to_delete_list_cnt note.
uint                  ThreadsSMRSupport::_to_delete_list_max = 0;

// 'inline' functions first so the definitions are before first use:

inline void ThreadsSMRSupport::add_deleted_thread_times(uint add_value) {
  Atomic::add(&_deleted_thread_times, add_value);
}

inline void ThreadsSMRSupport::inc_deleted_thread_cnt() {
  Atomic::inc(&_deleted_thread_cnt);
}

inline void ThreadsSMRSupport::inc_java_thread_list_alloc_cnt() {
  _java_thread_list_alloc_cnt++;
}

inline bool ThreadsSMRSupport::is_bootstrap_list(ThreadsList* list) {
  return list == &_bootstrap_list;
}

inline void ThreadsSMRSupport::update_deleted_thread_time_max(uint new_value) {
  while (true) {
    uint cur_value = _deleted_thread_time_max;
    if (new_value <= cur_value) {
      // No need to update max value so we're done.
      break;
    }
    if (Atomic::cmpxchg(&_deleted_thread_time_max, cur_value, new_value) == cur_value) {
      // Updated max value so we're done. Otherwise try it all again.
      break;
    }
  }
}

inline void ThreadsSMRSupport::update_java_thread_list_max(uint new_value) {
  if (new_value > _java_thread_list_max) {
    _java_thread_list_max = new_value;
  }
}

inline ThreadsList* ThreadsSMRSupport::xchg_java_thread_list(ThreadsList* new_list) {
  return (ThreadsList*)Atomic::xchg(&_java_thread_list, new_list);
}

// Hash table of pointers found by a scan. Used for collecting hazard
// pointers (ThreadsList references). Also used for collecting JavaThreads
// that are indirectly referenced by hazard ptrs. An instance of this
// class only contains one type of pointer.
//
class ThreadScanHashtable : public CHeapObj<mtThread> {
 private:
  static unsigned int ptr_hash(void * const& s1) {
    // 2654435761 = 2^32 * Phi (golden ratio)
    return (unsigned int)(((uint32_t)(uintptr_t)s1) * 2654435761u);
  }

  // ResourceHashtable SIZE is specified at compile time so we
  // use 1031 which is the first prime after 1024.
  typedef ResourceHashtable<void *, int, 1031,
                            AnyObj::C_HEAP, mtThread,
                            &ThreadScanHashtable::ptr_hash> PtrTable;
  PtrTable * _ptrs;

 public:
  // ResourceHashtable is passed to various functions and populated in
  // different places so we allocate it using C_HEAP to make it immune
  // from any ResourceMarks that happen to be in the code paths.
  ThreadScanHashtable() : _ptrs(new (mtThread) PtrTable()) {}

  ~ThreadScanHashtable() { delete _ptrs; }

  bool has_entry(void *pointer) {
    int *val_ptr = _ptrs->get(pointer);
    return val_ptr != nullptr && *val_ptr == 1;
  }

  void add_entry(void *pointer) {
    _ptrs->put(pointer, 1);
  }
};

// Closure to gather JavaThreads indirectly referenced by hazard ptrs
// (ThreadsList references) into a hash table. This closure handles part 2
// of the dance - adding all the JavaThreads referenced by the hazard
// pointer (ThreadsList reference) to the hash table.
//
class AddThreadHazardPointerThreadClosure : public ThreadClosure {
 private:
  ThreadScanHashtable *_table;

 public:
  AddThreadHazardPointerThreadClosure(ThreadScanHashtable *table) : _table(table) {}

  virtual void do_thread(Thread *thread) {
    if (!_table->has_entry((void*)thread)) {
      // The same JavaThread might be on more than one ThreadsList or
      // more than one thread might be using the same ThreadsList. In
      // either case, we only need a single entry for a JavaThread.
      _table->add_entry((void*)thread);
    }
  }
};

// Closure to gather JavaThreads indirectly referenced by hazard ptrs
// (ThreadsList references) into a hash table. This closure handles part 1
// of the dance - hazard ptr chain walking and dispatch to another
// closure.
//
class ScanHazardPtrGatherProtectedThreadsClosure : public ThreadClosure {
 private:
  ThreadScanHashtable *_table;
 public:
  ScanHazardPtrGatherProtectedThreadsClosure(ThreadScanHashtable *table) : _table(table) {}

  virtual void do_thread(Thread *thread) {
    assert_locked_or_safepoint(Threads_lock);

    if (thread == nullptr) return;

    // This code races with ThreadsSMRSupport::acquire_stable_list() which
    // is lock-free so we have to handle some special situations.
    //
    ThreadsList *current_list = nullptr;
    while (true) {
      current_list = thread->get_threads_hazard_ptr();
      // No hazard ptr so nothing more to do.
      if (current_list == nullptr) {
        return;
      }

      // If the hazard ptr is verified as stable (since it is not tagged),
      // then it is safe to use.
      if (!Thread::is_hazard_ptr_tagged(current_list)) break;

      // The hazard ptr is tagged as not yet verified as being stable
      // so we are racing with acquire_stable_list(). This exchange
      // attempts to invalidate the hazard ptr. If we win the race,
      // then we can ignore this unstable hazard ptr and the other
      // thread will retry the attempt to publish a stable hazard ptr.
      // If we lose the race, then we retry our attempt to look at the
      // hazard ptr.
      if (thread->cmpxchg_threads_hazard_ptr(nullptr, current_list) == current_list) return;
    }

    assert(ThreadsList::is_valid(current_list), "current_list="
           INTPTR_FORMAT " is not valid!", p2i(current_list));

    // The current JavaThread has a hazard ptr (ThreadsList reference)
    // which might be _java_thread_list or it might be an older
    // ThreadsList that has been removed but not freed. In either case,
    // the hazard ptr is protecting all the JavaThreads on that
    // ThreadsList.
    AddThreadHazardPointerThreadClosure add_cl(_table);
    current_list->threads_do(&add_cl);
  }
};

// Closure to gather hazard ptrs (ThreadsList references) into a hash table.
//
// Since this closure gathers hazard ptrs that may be tagged, this hash
// table of hazard ptrs should only be used for value comparison and not
// traversal of the ThreadsList.
//
class ScanHazardPtrGatherThreadsListClosure : public ThreadClosure {
 private:
  ThreadScanHashtable *_table;
 public:
  ScanHazardPtrGatherThreadsListClosure(ThreadScanHashtable *table) : _table(table) {}

  virtual void do_thread(Thread* thread) {
    assert_locked_or_safepoint(Threads_lock);

    if (thread == nullptr) return;
    ThreadsList *hazard_ptr = thread->get_threads_hazard_ptr();
    if (hazard_ptr == nullptr) return;
#ifdef ASSERT
    if (!Thread::is_hazard_ptr_tagged(hazard_ptr)) {
      // We only validate hazard_ptrs that are not tagged since a tagged
      // hazard ptr can be deleted at any time.
      assert(ThreadsList::is_valid(hazard_ptr), "hazard_ptr=" INTPTR_FORMAT
             " for thread=" INTPTR_FORMAT " is not valid!", p2i(hazard_ptr),
             p2i(thread));
    }
#endif
    // In this closure we always ignore the tag that might mark this
    // hazard ptr as not yet verified. If we happen to catch an
    // unverified hazard ptr that is subsequently discarded (not
    // published), then the only side effect is that we might keep a
    // to-be-deleted ThreadsList alive a little longer.
    hazard_ptr = Thread::untag_hazard_ptr(hazard_ptr);
    if (!_table->has_entry((void*)hazard_ptr)) {
      _table->add_entry((void*)hazard_ptr);
    }
  }
};

// Closure to print JavaThreads that have a hazard ptr (ThreadsList
// reference) that contains an indirect reference to a specific JavaThread.
//
class ScanHazardPtrPrintMatchingThreadsClosure : public ThreadClosure {
 private:
  JavaThread *_thread;
 public:
  ScanHazardPtrPrintMatchingThreadsClosure(JavaThread *thread) : _thread(thread) {}

  virtual void do_thread(Thread *thread) {
    assert_locked_or_safepoint(Threads_lock);

    if (thread == nullptr) return;
    ThreadsList *current_list = thread->get_threads_hazard_ptr();
    if (current_list == nullptr) {
      return;
    }
    // If the hazard ptr is unverified, then ignore it.
    if (Thread::is_hazard_ptr_tagged(current_list)) return;

    // The current JavaThread has a hazard ptr (ThreadsList reference)
    // which might be _java_thread_list or it might be an older
    // ThreadsList that has been removed but not freed. In either case,
    // the hazard ptr is protecting all the JavaThreads on that
    // ThreadsList, but we only care about matching a specific JavaThread.
    JavaThreadIterator jti(current_list);
    for (JavaThread *p = jti.first(); p != nullptr; p = jti.next()) {
      if (p == _thread) {
        log_debug(thread, smr)("tid=%zu: ThreadsSMRSupport::smr_delete: thread1=" INTPTR_FORMAT " has a hazard pointer for thread2=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread), p2i(_thread));
        break;
      }
    }
  }
};

#ifdef ASSERT
// Closure to validate hazard ptrs.
//
class ValidateHazardPtrsClosure : public ThreadClosure {
 public:
  ValidateHazardPtrsClosure() {};

  virtual void do_thread(Thread* thread) {
    assert_locked_or_safepoint(Threads_lock);

    if (thread == nullptr) return;
    ThreadsList *hazard_ptr = thread->get_threads_hazard_ptr();
    if (hazard_ptr == nullptr) return;
    // If the hazard ptr is unverified, then ignore it since it could
    // be deleted at any time now.
    if (Thread::is_hazard_ptr_tagged(hazard_ptr)) return;
    assert(ThreadsList::is_valid(hazard_ptr), "hazard_ptr=" INTPTR_FORMAT
           " for thread=" INTPTR_FORMAT " is not valid!", p2i(hazard_ptr),
           p2i(thread));
  }
};
#endif

// Closure to determine if the specified JavaThread is found by
// threads_do().
//
class VerifyHazardPtrThreadClosure : public ThreadClosure {
 private:
  bool _found;
  Thread *_self;

 public:
  VerifyHazardPtrThreadClosure(Thread *self) : _found(false), _self(self) {}

  bool found() const { return _found; }

  virtual void do_thread(Thread *thread) {
    if (thread == _self) {
      _found = true;
    }
  }
};


// Acquire a stable ThreadsList.
//
void SafeThreadsListPtr::acquire_stable_list() {
  assert(_thread != nullptr, "sanity check");
  _needs_release = true;
  _previous = _thread->_threads_list_ptr;
  _thread->_threads_list_ptr = this;

  if (_thread->get_threads_hazard_ptr() == nullptr && _previous == nullptr) {
    // The typical case is first.
    acquire_stable_list_fast_path();
    return;
  }

  // The nested case is rare.
  acquire_stable_list_nested_path();
}

// Fast path way to acquire a stable ThreadsList.
//
void SafeThreadsListPtr::acquire_stable_list_fast_path() {
  assert(_thread != nullptr, "sanity check");
  assert(_thread->get_threads_hazard_ptr() == nullptr, "sanity check");

  ThreadsList* threads;

  // Stable recording of a hazard ptr for SMR. This code does not use
  // locks so its use of the _java_thread_list & _threads_hazard_ptr
  // fields is racy relative to code that uses those fields with locks.
  // OrderAccess and Atomic functions are used to deal with those races.
  //
  while (true) {
    threads = ThreadsSMRSupport::get_java_thread_list();

    // Publish a tagged hazard ptr to denote that the hazard ptr is not
    // yet verified as being stable. Due to the fence after the hazard
    // ptr write, it will be sequentially consistent w.r.t. the
    // sequentially consistent writes of the ThreadsList, even on
    // non-multiple copy atomic machines where stores can be observed
    // in different order from different observer threads.
    ThreadsList* unverified_threads = Thread::tag_hazard_ptr(threads);
    _thread->set_threads_hazard_ptr(unverified_threads);

    // If _java_thread_list has changed, we have lost a race with
    // Threads::add() or Threads::remove() and have to try again.
    if (ThreadsSMRSupport::get_java_thread_list() != threads) {
      continue;
    }

    // We try to remove the tag which will verify the hazard ptr as
    // being stable. This exchange can race with a scanning thread
    // which might invalidate the tagged hazard ptr to keep it from
    // being followed to access JavaThread ptrs. If we lose the race,
    // we simply retry. If we win the race, then the stable hazard
    // ptr is officially published.
    if (_thread->cmpxchg_threads_hazard_ptr(threads, unverified_threads) == unverified_threads) {
      break;
    }
  }

  // A stable hazard ptr has been published letting other threads know
  // that the ThreadsList and the JavaThreads reachable from this list
  // are protected and hence they should not be deleted until everyone
  // agrees it is safe to do so.

  _list = threads;

  verify_hazard_ptr_scanned();
}

// Acquire a nested stable ThreadsList; this is rare so it uses
// reference counting.
//
void SafeThreadsListPtr::acquire_stable_list_nested_path() {
  assert(_thread != nullptr, "sanity check");

  // The thread already has a hazard ptr (ThreadsList ref) so we need
  // to create a nested ThreadsListHandle with the current ThreadsList
  // since it might be different than our current hazard ptr. To remedy
  // the situation, the ThreadsList pointed to by the pre-existing
  // stable hazard ptr is reference counted before the hazard ptr may
  // be released and moved to a new ThreadsList. The old ThreadsList
  // is remembered in the ThreadsListHandle.

  ThreadsList* current_list = _previous->_list;
  if (EnableThreadSMRStatistics) {
    _thread->inc_nested_threads_hazard_ptr_cnt();
  }
  if (!_previous->_has_ref_count) {
    // Promote the thread's current SafeThreadsListPtr to be reference counted.
    current_list->inc_nested_handle_cnt();
    _previous->_has_ref_count = true;
  }
  // Clear the hazard ptr so we can go through the fast path below and
  // acquire a nested stable ThreadsList.
  _thread->set_threads_hazard_ptr(nullptr);

  if (EnableThreadSMRStatistics && _thread->nested_threads_hazard_ptr_cnt() > ThreadsSMRSupport::_nested_thread_list_max) {
    ThreadsSMRSupport::_nested_thread_list_max = _thread->nested_threads_hazard_ptr_cnt();
  }

  acquire_stable_list_fast_path();

  verify_hazard_ptr_scanned();

  log_debug(thread, smr)("tid=%zu: SafeThreadsListPtr::acquire_stable_list: add nested list pointer to ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(_list));
}

// Release a stable ThreadsList.
//
void SafeThreadsListPtr::release_stable_list() {
  assert(_thread != nullptr, "sanity check");
  assert(_thread->_threads_list_ptr == this, "sanity check");
  _thread->_threads_list_ptr = _previous;

  // We're releasing either a leaf or nested ThreadsListHandle. In either
  // case, we set this thread's hazard ptr back to null and we do it before
  // _nested_handle_cnt is decremented below.
  _thread->set_threads_hazard_ptr(nullptr);
  if (_previous != nullptr) {
    // The ThreadsListHandle being released is a nested ThreadsListHandle.
    if (EnableThreadSMRStatistics) {
      _thread->dec_nested_threads_hazard_ptr_cnt();
    }
    // The previous ThreadsList is stable because the _nested_handle_cnt is
    // > 0, but we cannot safely make it this thread's hazard ptr again.
    // The protocol for installing and verifying a ThreadsList as a
    // thread's hazard ptr is handled by acquire_stable_list_fast_path().
    // And that protocol cannot be properly done with a ThreadsList that
    // might not be the current system ThreadsList.
    assert(_previous->_list->_nested_handle_cnt > 0, "must be > zero");
  }
  if (_has_ref_count) {
    // This thread created a nested ThreadsListHandle after the current
    // ThreadsListHandle so we had to protect this ThreadsList with a
    // ref count. We no longer need that protection.
    _list->dec_nested_handle_cnt();

    log_debug(thread, smr)("tid=%zu: SafeThreadsListPtr::release_stable_list: delete nested list pointer to ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(_list));
  }

  // After releasing the hazard ptr, other threads may go ahead and
  // free up some memory temporarily used by a ThreadsList snapshot.

  // We use double-check locking to reduce traffic on the system
  // wide Thread-SMR delete_lock.
  if (ThreadsSMRSupport::delete_notify()) {
    // An exiting thread might be waiting in smr_delete(); we need to
    // check with delete_lock to be sure.
    ThreadsSMRSupport::release_stable_list_wake_up(_has_ref_count);
    assert(_previous == nullptr || ThreadsList::is_valid(_previous->_list),
           "_previous->_list=" INTPTR_FORMAT
           " is not valid after calling release_stable_list_wake_up!",
           p2i(_previous->_list));
  }
}

// Verify that the stable hazard ptr used to safely keep threads
// alive is scanned by threads_do() which is a key piece of honoring
// the Thread-SMR protocol.
void SafeThreadsListPtr::verify_hazard_ptr_scanned() {
#ifdef ASSERT
  assert(_list != nullptr, "_list must not be null");

  if (ThreadsSMRSupport::is_bootstrap_list(_list)) {
    // We are early in VM bootstrapping so nothing to do here.
    return;
  }

  if ( _thread == VM_Exit::shutdown_thread()) {
    // The shutdown thread has removed itself from the Threads
    // list and is safe to have a waiver from this check because
    // VM_Exit::_shutdown_thread is not set until after the VMThread
    // has started the final safepoint which holds the Threads_lock
    // for the remainder of the VM's life.
    return;
  }

  if (VMError::is_error_reported_in_current_thread()) {
    // If there is an error reported by this thread it may use ThreadsList even
    // if it's unsafe.
    return;
  }

  // The closure will attempt to verify that the calling thread can
  // be found by threads_do() on the specified ThreadsList. If it
  // is successful, then the specified ThreadsList was acquired as
  // a stable hazard ptr by the calling thread in a way that honored
  // the Thread-SMR protocol.
  //
  // If the calling thread cannot be found by threads_do() and if
  // it is not the shutdown thread, then the calling thread is not
  // honoring the Thread-SMR ptotocol. This means that the specified
  // ThreadsList is not a stable hazard ptr and can be freed by
  // another thread from the to-be-deleted list at any time.
  //
  VerifyHazardPtrThreadClosure cl(_thread);
  ThreadsSMRSupport::threads_do(&cl, _list);

  // If the calling thread is not honoring the Thread-SMR protocol,
  // then we will either crash in threads_do() above because 'threads'
  // was freed by another thread or we will fail the assert() below.
  // In either case, we won't get past this point with a badly placed
  // ThreadsListHandle.

  assert(cl.found(), "Acquired a ThreadsList snapshot from a thread not recognized by the Thread-SMR protocol.");
#endif
}

// Shared singleton data for all ThreadsList(0) instances.
// Used by _bootstrap_list to avoid static init time heap allocation.
// No real entries, just the final null terminator.
static JavaThread* const empty_threads_list_data[1] = {};

// Result has 'entries + 1' elements, with the last being the null terminator.
static JavaThread* const* make_threads_list_data(int entries) {
  if (entries == 0) {
    return empty_threads_list_data;
  }
  JavaThread** data = NEW_C_HEAP_ARRAY(JavaThread*, entries + 1, mtThread);
  data[entries] = nullptr;         // Make sure the final entry is null.
  return data;
}

#ifdef ASSERT

ThreadsList::Iterator::Iterator() : _thread_ptr(nullptr), _list(nullptr) {}

uint ThreadsList::Iterator::check_index(ThreadsList* list, uint i) {
  assert(i <= list->length(), "invalid index %u", i);
  return i;
}

void ThreadsList::Iterator::assert_not_singular() const {
  assert(_list != nullptr, "singular iterator");
}

void ThreadsList::Iterator::assert_dereferenceable() const {
  assert(_thread_ptr < (_list->threads() + _list->length()), "not dereferenceable");
}

void ThreadsList::Iterator::assert_same_list(Iterator i) const {
  assert(_list == i._list, "iterators from different lists");
}

#endif // ASSERT

ThreadsList::ThreadsList(int entries) :
  _magic(THREADS_LIST_MAGIC),
  _length(entries),
  _next_list(nullptr),
  _threads(make_threads_list_data(entries)),
  _nested_handle_cnt(0)
{}

ThreadsList::~ThreadsList() {
  if (_threads != empty_threads_list_data) {
    FREE_C_HEAP_ARRAY(JavaThread*, _threads);
  }
  _magic = 0xDEADBEEF;
}

// Add a JavaThread to a ThreadsList. The returned ThreadsList is a
// new copy of the specified ThreadsList with the specified JavaThread
// appended to the end.
ThreadsList *ThreadsList::add_thread(ThreadsList *list, JavaThread *java_thread) {
  const uint index = list->_length;
  const uint new_length = index + 1;
  const uint head_length = index;
  ThreadsList *const new_list = new ThreadsList(new_length);

  if (head_length > 0) {
    Copy::disjoint_words((HeapWord*)list->_threads, (HeapWord*)new_list->_threads, head_length);
  }
  *(JavaThread**)(new_list->_threads + index) = java_thread;

  return new_list;
}

void ThreadsList::dec_nested_handle_cnt() {
  Atomic::dec(&_nested_handle_cnt);
}

int ThreadsList::find_index_of_JavaThread(JavaThread *target) {
  if (target == nullptr) {
    return -1;
  }
  for (uint i = 0; i < length(); i++) {
    if (target == thread_at(i)) {
      return (int)i;
    }
  }
  return -1;
}

JavaThread* ThreadsList::find_JavaThread_from_java_tid(jlong java_tid) const {
  ThreadIdTable::lazy_initialize(this);
  JavaThread* thread = ThreadIdTable::find_thread_by_tid(java_tid);
  if (thread == nullptr) {
    // If the thread is not found in the table find it
    // with a linear search and add to the table.
    for (uint i = 0; i < length(); i++) {
      thread = thread_at(i);
      oop tobj = thread->threadObj();
      // Ignore the thread if it hasn't run yet, has exited
      // or is starting to exit.
      if (tobj != nullptr && java_tid == java_lang_Thread::thread_id(tobj)) {
        MutexLocker ml(Threads_lock);
        // Must be inside the lock to ensure that we don't add a thread to the table
        // that has just passed the removal point in Threads::remove().
        if (!thread->is_exiting()) {
          ThreadIdTable::add_thread(java_tid, thread);
          return thread;
        }
      }
    }
  } else if (!thread->is_exiting()) {
    return thread;
  }
  return nullptr;
}

void ThreadsList::inc_nested_handle_cnt() {
  Atomic::inc(&_nested_handle_cnt);
}

bool ThreadsList::includes(const JavaThread * const p) const {
  if (p == nullptr) {
    return false;
  }
  for (uint i = 0; i < length(); i++) {
    if (thread_at(i) == p) {
      return true;
    }
  }
  return false;
}

// Remove a JavaThread from a ThreadsList. The returned ThreadsList is a
// new copy of the specified ThreadsList with the specified JavaThread
// removed.
ThreadsList *ThreadsList::remove_thread(ThreadsList* list, JavaThread* java_thread) {
  assert(list->_length > 0, "sanity");

  uint i = (uint)list->find_index_of_JavaThread(java_thread);
  assert(i < list->_length, "did not find JavaThread on the list");
  const uint index = i;
  const uint new_length = list->_length - 1;
  const uint head_length = index;
  const uint tail_length = (new_length >= index) ? (new_length - index) : 0;
  ThreadsList *const new_list = new ThreadsList(new_length);

  if (head_length > 0) {
    Copy::disjoint_words((HeapWord*)list->_threads, (HeapWord*)new_list->_threads, head_length);
  }
  if (tail_length > 0) {
    Copy::disjoint_words((HeapWord*)list->_threads + index + 1, (HeapWord*)new_list->_threads + index, tail_length);
  }

  return new_list;
}

ThreadsListHandle::ThreadsListHandle(Thread *self) : _list_ptr(self, /* acquire */ true) {
  assert(self == Thread::current(), "sanity check");
  if (EnableThreadSMRStatistics) {
    _timer.start();
  }
}

ThreadsListHandle::~ThreadsListHandle() {
  if (EnableThreadSMRStatistics) {
    _timer.stop();
    uint millis = (uint)_timer.milliseconds();
    ThreadsSMRSupport::update_tlh_stats(millis);
  }
}

// Convert an internal thread reference to a JavaThread found on the
// associated ThreadsList. This ThreadsListHandle "protects" the
// returned JavaThread *.
//
// If thread_oop_p is not null, then the caller wants to use the oop
// after this call so the oop is returned. On success, *jt_pp is set
// to the converted JavaThread * and true is returned. On error,
// returns false.
//
bool ThreadsListHandle::cv_internal_thread_to_JavaThread(jobject jthread,
                                                         JavaThread ** jt_pp,
                                                         oop * thread_oop_p) {
  assert(this->list() != nullptr, "must have a ThreadsList");
  assert(jt_pp != nullptr, "must have a return JavaThread pointer");
  // thread_oop_p is optional so no assert()

  // The JVM_* interfaces don't allow a null thread parameter; JVM/TI
  // allows a null thread parameter to signify "current thread" which
  // allows us to avoid calling cv_external_thread_to_JavaThread().
  // The JVM_* interfaces have no such leeway.

  oop thread_oop = JNIHandles::resolve_non_null(jthread);
  // Looks like an oop at this point.
  if (thread_oop_p != nullptr) {
    // Return the oop to the caller; the caller may still want
    // the oop even if this function returns false.
    *thread_oop_p = thread_oop;
  }

  JavaThread *java_thread = java_lang_Thread::thread_acquire(thread_oop);
  if (java_thread == nullptr) {
    // The java.lang.Thread does not contain a JavaThread* so it has not
    // run enough to be put on a ThreadsList or it has exited enough to
    // make it past ensure_join() where the JavaThread* is cleared.
    return false;
  }
  // Looks like a live JavaThread at this point.

  if (java_thread != JavaThread::current()) {
    // java_thread is not the current JavaThread so we have to verify it
    // against the ThreadsList.
    if (!includes(java_thread)) {
      // Not on this ThreadsList so it is not protected.
      return false;
    }
  }

  // Return a live JavaThread that is "protected" by the
  // ThreadsListHandle in the caller.
  *jt_pp = java_thread;
  return true;
}

FastThreadsListHandle::FastThreadsListHandle(oop thread_oop, JavaThread* java_thread) : _protected_java_thread(nullptr) {
  assert(thread_oop != nullptr, "must be");
  if (java_thread != nullptr) {
    // We captured a non-null JavaThread* before the _tlh was created
    // so that covers the early life stage of the target JavaThread.
    _protected_java_thread = java_lang_Thread::thread(thread_oop);
    assert(_protected_java_thread == nullptr || _tlh.includes(_protected_java_thread), "must be");
    // If we captured a non-null JavaThread* after the _tlh was created
    // then that covers the end life stage of the target JavaThread and we
    // we know that _tlh protects the JavaThread*. The underlying atomic
    // load is sufficient (no acquire necessary here).
  }
}

void ThreadsSMRSupport::add_thread(JavaThread *thread){
  ThreadsList *new_list = ThreadsList::add_thread(get_java_thread_list(), thread);
  if (EnableThreadSMRStatistics) {
    inc_java_thread_list_alloc_cnt();
    update_java_thread_list_max(new_list->length());
  }
  // Initial _java_thread_list will not generate a "Threads::add" mesg.
  log_debug(thread, smr)("tid=%zu: Threads::add: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list));

  ThreadsList *old_list = xchg_java_thread_list(new_list);
  free_list(old_list);
  if (ThreadIdTable::is_initialized()) {
    jlong tid = SharedRuntime::get_java_tid(thread);
    ThreadIdTable::add_thread(tid, thread);
  }
}

// set_delete_notify() and clear_delete_notify() are called
// under the protection of the delete_lock, but we also use an
// Atomic operation to ensure the memory update is seen earlier than
// when the delete_lock is dropped.
//
void ThreadsSMRSupport::clear_delete_notify() {
  Atomic::dec(&_delete_notify);
}

bool ThreadsSMRSupport::delete_notify() {
  // Use load_acquire() in order to see any updates to _delete_notify
  // earlier than when delete_lock is grabbed.
  return (Atomic::load_acquire(&_delete_notify) != 0);
}

// Safely free a ThreadsList after a Threads::add() or Threads::remove().
// The specified ThreadsList may not get deleted during this call if it
// is still in-use (referenced by a hazard ptr). Other ThreadsLists
// in the chain may get deleted by this call if they are no longer in-use.
void ThreadsSMRSupport::free_list(ThreadsList* threads) {
  assert_locked_or_safepoint(Threads_lock);

  if (is_bootstrap_list(threads)) {
    // The bootstrap list cannot be freed and is empty so
    // it does not need to be scanned. Nothing to do here.
    log_debug(thread, smr)("tid=%zu: ThreadsSMRSupport::free_list: bootstrap ThreadsList=" INTPTR_FORMAT " is no longer in use.", os::current_thread_id(), p2i(threads));
    return;
  }

  threads->set_next_list(_to_delete_list);
  _to_delete_list = threads;
  if (EnableThreadSMRStatistics) {
    _to_delete_list_cnt++;
    if (_to_delete_list_cnt > _to_delete_list_max) {
      _to_delete_list_max = _to_delete_list_cnt;
    }
  }

  // Gather a hash table of the current hazard ptrs:
  ThreadScanHashtable *scan_table = new ThreadScanHashtable();
  ScanHazardPtrGatherThreadsListClosure scan_cl(scan_table);
  threads_do(&scan_cl);
  OrderAccess::acquire(); // Must order reads of hazard ptr before reads of
                          // nested reference counters

  // Walk through the linked list of pending freeable ThreadsLists
  // and free the ones that are not referenced from hazard ptrs.
  ThreadsList* current = _to_delete_list;
  ThreadsList* prev = nullptr;
  ThreadsList* next = nullptr;
  bool threads_is_freed = false;
  while (current != nullptr) {
    next = current->next_list();
    if (!scan_table->has_entry((void*)current) && current->_nested_handle_cnt == 0) {
      // This ThreadsList is not referenced by a hazard ptr.
      if (prev != nullptr) {
        prev->set_next_list(next);
      }
      if (_to_delete_list == current) {
        _to_delete_list = next;
      }

      log_debug(thread, smr)("tid=%zu: ThreadsSMRSupport::free_list: threads=" INTPTR_FORMAT " is freed.", os::current_thread_id(), p2i(current));
      if (current == threads) threads_is_freed = true;
      delete current;
      if (EnableThreadSMRStatistics) {
        _java_thread_list_free_cnt++;
        _to_delete_list_cnt--;
      }
    } else {
      prev = current;
    }
    current = next;
  }

  if (!threads_is_freed) {
    // Only report "is not freed" on the original call to
    // free_list() for this ThreadsList.
    log_debug(thread, smr)("tid=%zu: ThreadsSMRSupport::free_list: threads=" INTPTR_FORMAT " is not freed.", os::current_thread_id(), p2i(threads));
  }

#ifdef ASSERT
  ValidateHazardPtrsClosure validate_cl;
  threads_do(&validate_cl);
#endif

  delete scan_table;
}

// Return true if the specified JavaThread is protected by a hazard
// pointer (ThreadsList reference). Otherwise, returns false.
//
bool ThreadsSMRSupport::is_a_protected_JavaThread(JavaThread *thread) {
  assert_locked_or_safepoint(Threads_lock);

  // Gather a hash table of the JavaThreads indirectly referenced by
  // hazard ptrs.
  ThreadScanHashtable *scan_table = new ThreadScanHashtable();
  ScanHazardPtrGatherProtectedThreadsClosure scan_cl(scan_table);
  threads_do(&scan_cl);
  OrderAccess::acquire(); // Must order reads of hazard ptr before reads of
                          // nested reference counters

  // Walk through the linked list of pending freeable ThreadsLists
  // and include the ones that are currently in use by a nested
  // ThreadsListHandle in the search set.
  ThreadsList* current = _to_delete_list;
  while (current != nullptr) {
    if (current->_nested_handle_cnt != 0) {
      // 'current' is in use by a nested ThreadsListHandle so the hazard
      // ptr is protecting all the JavaThreads on that ThreadsList.
      AddThreadHazardPointerThreadClosure add_cl(scan_table);
      current->threads_do(&add_cl);
    }
    current = current->next_list();
  }

  bool thread_is_protected = false;
  if (scan_table->has_entry((void*)thread)) {
    thread_is_protected = true;
  }
  delete scan_table;
  return thread_is_protected;
}

// Wake up portion of the release stable ThreadsList protocol;
// uses the delete_lock().
//
void ThreadsSMRSupport::release_stable_list_wake_up(bool is_nested) {
  const char* log_str = is_nested ? "nested hazard ptr" : "regular hazard ptr";

  // Note: delete_lock is held in smr_delete() for the entire
  // hazard ptr search so that we do not lose this notify() if
  // the exiting thread has to wait. That code path also holds
  // Threads_lock (which was grabbed before delete_lock) so that
  // threads_do() can be called. This means the system can't start a
  // safepoint which means this thread can't take too long to get to
  // a safepoint because of being blocked on delete_lock.
  //
  MonitorLocker ml(ThreadsSMRSupport::delete_lock(), Monitor::_no_safepoint_check_flag);
  if (ThreadsSMRSupport::delete_notify()) {
    // Notify any exiting JavaThreads that are waiting in smr_delete()
    // that we've released a ThreadsList.
    ml.notify_all();
    log_debug(thread, smr)("tid=%zu: ThreadsSMRSupport::release_stable_list notified %s", os::current_thread_id(), log_str);
  }
}

void ThreadsSMRSupport::remove_thread(JavaThread *thread) {
  ThreadsList *new_list = ThreadsList::remove_thread(ThreadsSMRSupport::get_java_thread_list(), thread);
  if (EnableThreadSMRStatistics) {
    ThreadsSMRSupport::inc_java_thread_list_alloc_cnt();
    // This list is smaller so no need to check for a "longest" update.
  }

  // Final _java_thread_list will not generate a "Threads::remove" mesg.
  log_debug(thread, smr)("tid=%zu: Threads::remove: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list));

  ThreadsList *old_list = ThreadsSMRSupport::xchg_java_thread_list(new_list);
  ThreadsSMRSupport::free_list(old_list);
}

// See note for clear_delete_notify().
//
void ThreadsSMRSupport::set_delete_notify() {
  Atomic::inc(&_delete_notify);
}

// Safely delete a JavaThread when it is no longer in use by a
// ThreadsListHandle.
//
void ThreadsSMRSupport::smr_delete(JavaThread *thread) {
  elapsedTimer timer;
  if (EnableThreadSMRStatistics) {
    timer.start();
  }

  wait_until_not_protected(thread);

  delete thread;
  if (EnableThreadSMRStatistics) {
    timer.stop();
    uint millis = (uint)timer.milliseconds();
    ThreadsSMRSupport::inc_deleted_thread_cnt();
    ThreadsSMRSupport::add_deleted_thread_times(millis);
    ThreadsSMRSupport::update_deleted_thread_time_max(millis);
  }

  log_debug(thread, smr)("tid=%zu: ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is deleted.", os::current_thread_id(), p2i(thread));
}

void ThreadsSMRSupport::wait_until_not_protected(JavaThread *thread) {
  assert(!Threads_lock->owned_by_self(), "sanity");

  bool has_logged_once = false;

  while (true) {
    {
      // Will not make a safepoint check because this JavaThread
      // is not on the current ThreadsList.
      MutexLocker ml(Threads_lock);
      // Cannot use a MonitorLocker helper here because we have
      // to drop the Threads_lock first if we wait.
      ThreadsSMRSupport::delete_lock()->lock_without_safepoint_check();
      // Set the delete_notify flag after we grab delete_lock
      // and before we scan hazard ptrs because we're doing
      // double-check locking in release_stable_list().
      ThreadsSMRSupport::set_delete_notify();

      if (!is_a_protected_JavaThread(thread)) {
        // This is the common case.
        ThreadsSMRSupport::clear_delete_notify();
        ThreadsSMRSupport::delete_lock()->unlock();
        break;
      }
      if (!has_logged_once) {
        has_logged_once = true;
        log_debug(thread, smr)("tid=%zu: ThreadsSMRSupport::wait_until_not_protected: thread=" INTPTR_FORMAT " is not deleted.", os::current_thread_id(), p2i(thread));
        if (log_is_enabled(Debug, os, thread)) {
          ScanHazardPtrPrintMatchingThreadsClosure scan_cl(thread);
          threads_do(&scan_cl);
          ThreadsList* current = _to_delete_list;
          while (current != nullptr) {
            if (current->_nested_handle_cnt != 0 && current->includes(thread)) {
              log_debug(thread, smr)("tid=%zu: ThreadsSMRSupport::wait_until_not_protected: found nested hazard pointer to thread=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread));
            }
            current = current->next_list();
          }
        }
      }
    } // We have to drop the Threads_lock to wait or delete the thread

    if (EnableThreadSMRStatistics) {
      _delete_lock_wait_cnt++;
      if (_delete_lock_wait_cnt > _delete_lock_wait_max) {
        _delete_lock_wait_max = _delete_lock_wait_cnt;
      }
    }
    // Wait for a release_stable_list() call before we check again. No
    // safepoint check, no timeout, and not as suspend equivalent flag
    // because this JavaThread is not on the Threads list.
    ThreadsSMRSupport::delete_lock()->wait_without_safepoint_check();
    if (EnableThreadSMRStatistics) {
      _delete_lock_wait_cnt--;
    }

    ThreadsSMRSupport::clear_delete_notify();
    ThreadsSMRSupport::delete_lock()->unlock();
    // Retry the whole scenario.
  }
}

// Apply the closure to all threads in the system, with a snapshot of
// all JavaThreads provided by the list parameter.
void ThreadsSMRSupport::threads_do(ThreadClosure *tc, ThreadsList *list) {
  list->threads_do(tc);
  Threads::non_java_threads_do(tc);
}

// Apply the closure to all threads in the system.
void ThreadsSMRSupport::threads_do(ThreadClosure *tc) {
  threads_do(tc, _java_thread_list);
}


// Debug, logging, and printing stuff at the end:

// Print SMR info for a SafeThreadsListPtr to a given output stream.
void SafeThreadsListPtr::print_on(outputStream* st) {
  if (this == _thread->_threads_list_ptr) {
    // The top level hazard ptr.
    st->print(" _threads_hazard_ptr=" INTPTR_FORMAT, p2i(_list));
  } else {
    // Nested hazard ptrs.
    st->print(", _nested_threads_hazard_ptr=" INTPTR_FORMAT, p2i(_list));
  }
}

// Log Threads class SMR info.
void ThreadsSMRSupport::log_statistics() {
  LogTarget(Info, thread, smr) log;
  if (log.is_enabled()) {
    LogStream out(log);
    print_info_on(&out);
  }
}

// Print SMR info for a thread to a given output stream.
void ThreadsSMRSupport::print_info_on(const Thread* thread, outputStream* st) {
  ThreadsList* hazard_ptr = thread->get_threads_hazard_ptr();
  if (hazard_ptr != nullptr) {
    st->print(" _threads_hazard_ptr=" INTPTR_FORMAT, p2i(hazard_ptr));
  }
  if (EnableThreadSMRStatistics && thread->_threads_list_ptr != nullptr) {
    // The count is only interesting if we have a _threads_list_ptr.
    st->print(", _nested_threads_hazard_ptr_cnt=%u", thread->_nested_threads_hazard_ptr_cnt);
  }
  if ((SafepointSynchronize::is_at_safepoint() && thread->is_Java_thread()) ||
      Thread::current() == thread) {
    // It is only safe to walk the list if we're at a safepoint and processing a JavaThread,
    // or the calling thread is walking its own list.
    SafeThreadsListPtr* current = thread->_threads_list_ptr;
    if (current != nullptr) {
      // Skip the top nesting level as it is always printed above.
      current = current->previous();
    }
    while (current != nullptr) {
      current->print_on(st);
      current = current->previous();
    }
  }
}

// Print Threads class SMR info.
void ThreadsSMRSupport::print_info_on(outputStream* st) {
  bool needs_unlock = false;
  if (Threads_lock->try_lock_without_rank_check()) {
    // We were able to grab the Threads_lock which makes things safe for
    // this call, but if we are error reporting, then a nested error
    // could happen with the Threads_lock held.
    needs_unlock = true;
  }

  ThreadsList* saved_threads_list = nullptr;
  {
    ThreadsListHandle tlh;  // make the current ThreadsList safe for reporting
    saved_threads_list = tlh.list();  // save for later comparison

    st->print_cr("Threads class SMR info:");
    st->print_cr("_java_thread_list=" INTPTR_FORMAT ", length=%u, elements={",
                 p2i(saved_threads_list), saved_threads_list->length());
    print_info_elements_on(st, saved_threads_list);
    st->print_cr("}");
  }

  if (_to_delete_list != nullptr) {
    if (Threads_lock->owned_by_self()) {
      // Only safe if we have the Threads_lock.
      st->print_cr("_to_delete_list=" INTPTR_FORMAT ", length=%u, elements={",
                   p2i(_to_delete_list), _to_delete_list->length());
      print_info_elements_on(st, _to_delete_list);
      st->print_cr("}");
      for (ThreadsList *t_list = _to_delete_list->next_list();
           t_list != nullptr; t_list = t_list->next_list()) {
        st->print("next-> " INTPTR_FORMAT ", length=%u, elements={",
                  p2i(t_list), t_list->length());
        print_info_elements_on(st, t_list);
        st->print_cr("}");
      }
    } else {
      st->print_cr("_to_delete_list=" INTPTR_FORMAT, p2i(_to_delete_list));
      st->print_cr("Skipping _to_delete_list fields and contents for safety.");
    }
  }
  if (EnableThreadSMRStatistics) {
    st->print_cr("_java_thread_list_alloc_cnt=" UINT64_FORMAT ", "
                 "_java_thread_list_free_cnt=" UINT64_FORMAT ", "
                 "_java_thread_list_max=%u, "
                 "_nested_thread_list_max=%u",
                 _java_thread_list_alloc_cnt,
                 _java_thread_list_free_cnt,
                 _java_thread_list_max,
                 _nested_thread_list_max);
    if (_tlh_cnt > 0) {
      st->print_cr("_tlh_cnt=%u"
                   ", _tlh_times=%u"
                   ", avg_tlh_time=%0.2f"
                   ", _tlh_time_max=%u",
                   _tlh_cnt, _tlh_times,
                   ((double) _tlh_times / _tlh_cnt),
                   _tlh_time_max);
    }
    if (_deleted_thread_cnt > 0) {
      st->print_cr("_deleted_thread_cnt=%u"
                   ", _deleted_thread_times=%u"
                   ", avg_deleted_thread_time=%0.2f"
                   ", _deleted_thread_time_max=%u",
                   _deleted_thread_cnt, _deleted_thread_times,
                   ((double) _deleted_thread_times / _deleted_thread_cnt),
                   _deleted_thread_time_max);
    }
    st->print_cr("_delete_lock_wait_cnt=%u, _delete_lock_wait_max=%u",
                 _delete_lock_wait_cnt, _delete_lock_wait_max);
    st->print_cr("_to_delete_list_cnt=%u, _to_delete_list_max=%u",
                 _to_delete_list_cnt, _to_delete_list_max);
  }
  if (needs_unlock) {
    Threads_lock->unlock();
  } else {
    if (_java_thread_list != saved_threads_list) {
      st->print_cr("The _java_thread_list has changed from " INTPTR_FORMAT
                   " to " INTPTR_FORMAT
                   " so some of the above information may be stale.",
                   p2i(saved_threads_list), p2i(_java_thread_list));
    }
  }
}

// Print ThreadsList elements (4 per line).
void ThreadsSMRSupport::print_info_elements_on(outputStream* st, ThreadsList* t_list) {
  uint cnt = 0;
  JavaThreadIterator jti(t_list);
  for (JavaThread *jt = jti.first(); jt != nullptr; jt = jti.next()) {
    st->print(INTPTR_FORMAT, p2i(jt));
    if (cnt < t_list->length() - 1) {
      // Separate with comma or comma-space except for the last one.
      if (((cnt + 1) % 4) == 0) {
        // Four INTPTR_FORMAT fit on an 80 column line so end the
        // current line with just a comma.
        st->print_cr(",");
      } else {
        // Not the last one on the current line so use comma-space:
        st->print(", ");
      }
    } else {
      // Last one so just end the current line.
      st->cr();
    }
    cnt++;
  }
}
