/*
 * Copyright (c) 2020 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * Copyright (c) 2011 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "base/hostinfo.hh"
#include "base/logging.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "debug/TimeSync.hh"
#include "sim/core.hh"
#include "sim/cur_tick.hh"
#include "sim/eventq.hh"
#include "sim/full_system.hh"
#include "sim/root.hh"

namespace gem5
{

Root *Root::_root = NULL;
Root::RootStats Root::RootStats::instance;
Root::RootStats &rootStats = Root::RootStats::instance;

Root::RootStats::RootStats()
    : statistics::Group(nullptr),
    ADD_STAT(simSeconds, statistics::units::Second::get(),
             "Number of seconds simulated"),
    ADD_STAT(simTicks, statistics::units::Tick::get(),
             "Number of ticks simulated"),
    ADD_STAT(finalTick, statistics::units::Tick::get(),
             "Number of ticks from beginning of simulation "
             "(restored from checkpoints and never reset)"),
    ADD_STAT(simFreq, statistics::units::Rate<
                statistics::units::Tick, statistics::units::Second>::get(),
             "The number of ticks per simulated second"),
    ADD_STAT(hostSeconds, statistics::units::Second::get(),
             "Real time elapsed on the host"),
    ADD_STAT(hostTickRate, statistics::units::Rate<
                statistics::units::Tick, statistics::units::Second>::get(),
             "The number of ticks simulated per host second (ticks/s)"),
    ADD_STAT(hostMemory, statistics::units::Byte::get(),
             "Number of bytes of host memory used"),

    statTime(true),
    startTick(0)
{
    simFreq.scalar(sim_clock::Frequency);
    simTicks.functor([this]() { return curTick() - startTick; });
    finalTick.functor(curTick);

    hostMemory
        .functor(memUsage)
        .prereq(hostMemory)
        ;

    hostSeconds
        .functor([this]() {
                Time now;
                now.setTimer();
                return now - statTime;
            })
        .precision(2)
        ;

    hostTickRate.precision(0);

    simSeconds = simTicks / simFreq;
    hostTickRate = simTicks / hostSeconds;
}

void
Root::RootStats::resetStats()
{
    statTime.setTimer();
    startTick = curTick();

    statistics::Group::resetStats();
}

/*
 * This function is called periodically by an event in M5 and ensures that
 * at least as much real time has passed between invocations as simulated time.
 * If not, the function either sleeps, or if the difference is small enough
 * spin waits.
 */
void
Root::timeSync()
{
    Time cur_time, diff, period = timeSyncPeriod();

    do {
        cur_time.setTimer();
        diff = cur_time - lastTime;
        Time remainder = period - diff;
        if (diff < period && remainder > _spinThreshold) {
            DPRINTF(TimeSync, "Sleeping to sync with real time.\n");
            // Sleep until the end of the period, or until a signal.
            sleep(remainder);
            // Refresh the current time.
            cur_time.setTimer();
        }
    } while (diff < period);
    lastTime = cur_time;
    schedule(&syncEvent, curTick() + _periodTick);
}

void
Root::timeSyncEnable(bool en)
{
    if (en == _enabled)
        return;
    _enabled = en;
    if (_enabled) {
        // Get event going.
        Tick periods = ((curTick() + _periodTick - 1) / _periodTick);
        Tick nextPeriod = periods * _periodTick;
        schedule(&syncEvent, nextPeriod);
    } else {
        // Stop event.
        deschedule(&syncEvent);
    }
}

/// Configure the period for time sync events.
void
Root::timeSyncPeriod(Time newPeriod)
{
    bool en = timeSyncEnabled();
    _period = newPeriod;
    _periodTick = _period.getTick();
    timeSyncEnable(en);
}

/// Set the threshold for time remaining to spin wait.
void
Root::timeSyncSpinThreshold(Time newThreshold)
{
    bool en = timeSyncEnabled();
    _spinThreshold = newThreshold;
    timeSyncEnable(en);
}

Root::Root(const RootParams &p, int)
    : SimObject(p), _enabled(false), _periodTick(p.time_sync_period),
      syncEvent([this]{ timeSync(); }, name())
{
    _period.setTick(p.time_sync_period);
    _spinThreshold.setTick(p.time_sync_spin_threshold);

    assert(_root == NULL);
    _root = this;
    lastTime.setTimer();

    simQuantum = p.sim_quantum;

    // Some of the statistics are global and need to be accessed by
    // stat formulas. The most convenient way to implement that is by
    // having a single global stat group for global stats. Merge that
    // group into the root object here.
    mergeStatGroup(&Root::RootStats::instance);
}

void
Root::startup()
{
    timeSyncEnable(params().time_sync_enable);
}

void
Root::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(FullSystem);
    std::string isa = THE_ISA_STR;
    SERIALIZE_SCALAR(isa);

    globals.serializeSection(cp, "globals");
}

void
Root::unserialize(CheckpointIn &cp)
{
    globals.unserializeSection(cp, "globals");
    for (uint32_t i = 0; i < numMainEventQueues; ++i)
        mainEventQueue[i]->setCurTick(globals.unserializedCurTick);
}

bool FullSystem;
unsigned int FullSystemInt;

Root *
RootParams::create() const
{
    static bool created = false;
    if (created)
        panic("only one root object allowed!");

    created = true;

    FullSystem = full_system;
    FullSystemInt = full_system ? 1 : 0;

    return new Root(*this, 0);
}

} // namespace gem5
