/*
 * Copyright (c) 2001, 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 "gc/g1/g1BarrierSet.hpp"
#include "gc/g1/g1ConcurrentRefine.hpp"
#include "gc/g1/g1ConcurrentRefineStats.hpp"
#include "gc/g1/g1ConcurrentRefineThread.hpp"
#include "gc/g1/g1DirtyCardQueue.hpp"
#include "gc/shared/suspendibleThreadSet.hpp"
#include "logging/log.hpp"
#include "runtime/cpuTimeCounters.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "runtime/thread.hpp"
#include "utilities/debug.hpp"
#include "utilities/formatBuffer.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/ticks.hpp"

G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr, uint worker_id) :
  ConcurrentGCThread(),
  _vtime_start(0.0),
  _vtime_accum(0.0),
  _notifier(Mutex::nosafepoint, FormatBuffer<>("G1 Refine#%d", worker_id), true),
  _requested_active(false),
  _refinement_stats(),
  _worker_id(worker_id),
  _cr(cr)
{
  // set name
  set_name("G1 Refine#%d", worker_id);
}

void G1ConcurrentRefineThread::run_service() {
  _vtime_start = os::elapsedVTime();

  while (wait_for_completed_buffers()) {
    SuspendibleThreadSetJoiner sts_join;
    G1ConcurrentRefineStats active_stats_start = _refinement_stats;
    report_active("Activated");
    while (!should_terminate()) {
      if (sts_join.should_yield()) {
        report_inactive("Paused", _refinement_stats - active_stats_start);
        sts_join.yield();
        // Reset after yield rather than accumulating across yields, else a
        // very long running thread could overflow.
        active_stats_start = _refinement_stats;
        report_active("Resumed");
      } else if (maybe_deactivate()) {
        break;
      } else {
        do_refinement_step();
      }
    }
    report_inactive("Deactivated", _refinement_stats - active_stats_start);
    track_usage();
  }

  log_debug(gc, refine)("Stopping %d", _worker_id);
}

void G1ConcurrentRefineThread::report_active(const char* reason) const {
  log_trace(gc, refine)("%s worker %u, current: %zu",
                        reason,
                        _worker_id,
                        G1BarrierSet::dirty_card_queue_set().num_cards());
}

void G1ConcurrentRefineThread::report_inactive(const char* reason,
                                               const G1ConcurrentRefineStats& stats) const {
  log_trace(gc, refine)
           ("%s worker %u, cards: %zu, refined %zu, rate %1.2fc/ms",
            reason,
            _worker_id,
            G1BarrierSet::dirty_card_queue_set().num_cards(),
            stats.refined_cards(),
            stats.refinement_rate_ms());
}

void G1ConcurrentRefineThread::activate() {
  assert(this != Thread::current(), "precondition");
  MonitorLocker ml(&_notifier, Mutex::_no_safepoint_check_flag);
  if (!_requested_active || should_terminate()) {
    _requested_active = true;
    ml.notify();
  }
}

bool G1ConcurrentRefineThread::maybe_deactivate() {
  assert(this == Thread::current(), "precondition");
  if (cr()->is_thread_wanted(_worker_id)) {
    return false;
  } else {
    MutexLocker ml(&_notifier, Mutex::_no_safepoint_check_flag);
    bool requested = _requested_active;
    _requested_active = false;
    return !requested;  // Deactivate only if not recently requested active.
  }
}

bool G1ConcurrentRefineThread::try_refinement_step(size_t stop_at) {
  assert(this == Thread::current(), "precondition");
  return _cr->try_refinement_step(_worker_id, stop_at, &_refinement_stats);
}

void G1ConcurrentRefineThread::stop_service() {
  activate();
}

// The (single) primary thread drives the controller for the refinement threads.
class G1PrimaryConcurrentRefineThread final : public G1ConcurrentRefineThread {
  bool wait_for_completed_buffers() override;
  bool maybe_deactivate() override;
  void do_refinement_step() override;
  void track_usage() override;

public:
  G1PrimaryConcurrentRefineThread(G1ConcurrentRefine* cr) :
    G1ConcurrentRefineThread(cr, 0)
  {}
};

// When inactive, the primary thread periodically wakes up and requests
// adjustment of the number of active refinement threads.
bool G1PrimaryConcurrentRefineThread::wait_for_completed_buffers() {
  assert(this == Thread::current(), "precondition");
  MonitorLocker ml(notifier(), Mutex::_no_safepoint_check_flag);
  if (!requested_active() && !should_terminate()) {
    // Rather than trying to be smart about spurious wakeups, we just treat
    // them as timeouts.
    ml.wait(cr()->adjust_threads_wait_ms());
  }
  // Record adjustment needed whenever reactivating.
  cr()->record_thread_adjustment_needed();
  return !should_terminate();
}

bool G1PrimaryConcurrentRefineThread::maybe_deactivate() {
  // Don't deactivate while needing to adjust the number of active threads.
  return !cr()->is_thread_adjustment_needed() &&
         G1ConcurrentRefineThread::maybe_deactivate();
}

void G1PrimaryConcurrentRefineThread::do_refinement_step() {
  // Try adjustment first.  If it succeeds then don't do any refinement this
  // round.  This thread may have just woken up but no threads are currently
  // needed, which is common.  In this case we want to just go back to
  // waiting, with a minimum of fuss; in particular, don't do any "premature"
  // refinement.  However, adjustment may be pending but temporarily
  // blocked. In that case we *do* try refinement, rather than possibly
  // uselessly spinning while waiting for adjustment to succeed.
  if (!cr()->adjust_threads_periodically()) {
    // No adjustment, so try refinement, with the target as a cuttoff.
    if (!try_refinement_step(cr()->pending_cards_target())) {
      // Refinement was cut off, so proceed with fewer threads.
      cr()->reduce_threads_wanted();
    }
  }
}

void G1PrimaryConcurrentRefineThread::track_usage() {
  G1ConcurrentRefineThread::track_usage();
  // The primary thread is responsible for updating the CPU time for all workers.
  if (UsePerfData && os::is_thread_cpu_time_supported()) {
    ThreadTotalCPUTimeClosure tttc(CPUTimeGroups::CPUTimeType::gc_conc_refine);
    cr()->threads_do(&tttc);
  }
}

class G1SecondaryConcurrentRefineThread final : public G1ConcurrentRefineThread {
  bool wait_for_completed_buffers() override;
  void do_refinement_step() override;

public:
  G1SecondaryConcurrentRefineThread(G1ConcurrentRefine* cr, uint worker_id) :
    G1ConcurrentRefineThread(cr, worker_id)
  {
    assert(worker_id > 0, "precondition");
  }
};

bool G1SecondaryConcurrentRefineThread::wait_for_completed_buffers() {
  assert(this == Thread::current(), "precondition");
  MonitorLocker ml(notifier(), Mutex::_no_safepoint_check_flag);
  while (!requested_active() && !should_terminate()) {
    ml.wait();
  }
  return !should_terminate();
}

void G1SecondaryConcurrentRefineThread::do_refinement_step() {
  assert(this == Thread::current(), "precondition");
  // Secondary threads ignore the target and just drive the number of pending
  // dirty cards down.  The primary thread is responsible for noticing the
  // target has been reached and reducing the number of wanted threads.  This
  // makes the control of wanted threads all under the primary, while avoiding
  // useless spinning by secondary threads until the primary thread notices.
  // (Useless spinning is still possible if there are no pending cards, but
  // that should rarely happen.)
  try_refinement_step(0);
}

G1ConcurrentRefineThread*
G1ConcurrentRefineThread::create(G1ConcurrentRefine* cr, uint worker_id) {
  G1ConcurrentRefineThread* crt;
  if (worker_id == 0) {
    crt = new (std::nothrow) G1PrimaryConcurrentRefineThread(cr);
  } else {
    crt = new (std::nothrow) G1SecondaryConcurrentRefineThread(cr, worker_id);
  }
  if (crt != nullptr) {
    crt->create_and_start();
  }
  return crt;
}
