arch-arm: Do not check MustBeOne flag for TLB requests from the prefetcher
[gem5.git] / src / sim / stat_control.cc
index 041830ab7e726888c12f0e5fcbce52ffae5f4120..6324b36ef9e56f54326c063cc538abd731523240 100644 (file)
@@ -1,5 +1,19 @@
 /*
+ * Copyright (c) 2012 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) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
+ * Copyright (c) 2013 Mark D. Hill and David A. Wood
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Authors: Nathan Binkert
+ *          Sascha Bischoff
  */
 
 // This file will contain default statistics for the simulator that
 // don't really belong to a specific simulator object
 
+#include "sim/stat_control.hh"
+
 #include <fstream>
 #include <iostream>
 #include <list>
 #include "base/callback.hh"
 #include "base/hostinfo.hh"
 #include "base/statistics.hh"
-#include "base/str.hh"
 #include "base/time.hh"
-#include "base/stats/output.hh"
 #include "cpu/base.hh"
-#include "sim/eventq.hh"
-#include "sim/sim_object.hh"
-#include "sim/stat_control.hh"
-#include "sim/root.hh"
+#include "sim/global_event.hh"
 
 using namespace std;
 
-Stats::Formula hostInstRate;
-Stats::Formula hostTickRate;
-Stats::Value hostMemory;
-Stats::Value hostSeconds;
-
+Stats::Formula simSeconds;
 Stats::Value simTicks;
-Stats::Value simInsts;
+Stats::Value finalTick;
 Stats::Value simFreq;
-Stats::Formula simSeconds;
 
 namespace Stats {
 
 Time statTime(true);
 Tick startTick;
-Tick lastDump(0);
 
-class SimTicksReset : public Callback
+GlobalEvent *dumpEvent;
+
+struct SimTicksReset : public Callback
 {
-  public:
     void process()
     {
-        statTime.set();
-        startTick = curTick;
+        statTime.setTimer();
+        startTick = curTick();
     }
 };
 
 double
 statElapsedTime()
 {
-    Time now(true);
+    Time now;
+    now.setTimer();
+
     Time elapsed = now - statTime;
-    return elapsed();
+    return elapsed;
 }
 
 Tick
 statElapsedTicks()
 {
-    return curTick - startTick;
+    return curTick() - startTick;
+}
+
+Tick
+statFinalTick()
+{
+    return curTick();
 }
 
 SimTicksReset simTicksReset;
 
-void
-InitSimStats()
+struct Global
+{
+    Stats::Formula hostInstRate;
+    Stats::Formula hostOpRate;
+    Stats::Formula hostTickRate;
+    Stats::Value hostMemory;
+    Stats::Value hostSeconds;
+
+    Stats::Value simInsts;
+    Stats::Value simOps;
+
+    Global();
+};
+
+Global::Global()
 {
     simInsts
-        .functor(BaseCPU::numSimulatedInstructions)
+        .functor(BaseCPU::numSimulatedInsts)
         .name("sim_insts")
         .desc("Number of instructions simulated")
         .precision(0)
         .prereq(simInsts)
         ;
 
+    simOps
+        .functor(BaseCPU::numSimulatedOps)
+        .name("sim_ops")
+        .desc("Number of ops (including micro ops) simulated")
+        .precision(0)
+        .prereq(simOps)
+        ;
+
     simSeconds
         .name("sim_seconds")
         .desc("Number of seconds simulated")
         ;
 
     simFreq
-        .scalar(Clock::Frequency)
+        .scalar(SimClock::Frequency)
         .name("sim_freq")
         .desc("Frequency of simulated ticks")
         ;
@@ -119,6 +155,13 @@ InitSimStats()
         .desc("Number of ticks simulated")
         ;
 
+    finalTick
+        .functor(statFinalTick)
+        .name("final_tick")
+        .desc("Number of ticks from beginning of simulation "
+              "(restored from checkpoints and never reset)")
+        ;
+
     hostInstRate
         .name("host_inst_rate")
         .desc("Simulator instruction rate (inst/s)")
@@ -126,6 +169,13 @@ InitSimStats()
         .prereq(simInsts)
         ;
 
+    hostOpRate
+        .name("host_op_rate")
+        .desc("Simulator op (including micro ops) rate (op/s)")
+        .precision(0)
+        .prereq(simOps)
+        ;
+
     hostMemory
         .functor(memUsage)
         .name("host_mem_usage")
@@ -148,81 +198,106 @@ InitSimStats()
 
     simSeconds = simTicks / simFreq;
     hostInstRate = simInsts / hostSeconds;
+    hostOpRate = simOps / hostSeconds;
     hostTickRate = simTicks / hostSeconds;
 
     registerResetCallback(&simTicksReset);
 }
 
-class StatEvent : public Event
-{
-  protected:
-    int flags;
-    Tick repeat;
-
-  public:
-    StatEvent(int _flags, Tick _when, Tick _repeat);
-    virtual void process();
-    virtual const char *description();
-};
-
-StatEvent::StatEvent(int _flags, Tick _when, Tick _repeat)
-    : Event(&mainEventQueue, Stat_Event_Pri),
-      flags(_flags), repeat(_repeat)
+void
+initSimStats()
 {
-    setFlags(AutoDelete);
-    schedule(_when);
+    static Global global;
 }
 
-const char *
-StatEvent::description()
+/**
+ * Event to dump and/or reset the statistics.
+ */
+class StatEvent : public GlobalEvent
 {
-    return "Statistics dump and/or reset";
-}
+  private:
+    bool dump;
+    bool reset;
+    Tick repeat;
 
-void
-StatEvent::process()
-{
-    if (flags & Stats::Dump)
-        DumpNow();
+  public:
+    StatEvent(Tick _when, bool _dump, bool _reset, Tick _repeat)
+        : GlobalEvent(_when, Stat_Event_Pri, 0),
+          dump(_dump), reset(_reset), repeat(_repeat)
+    {
+    }
 
-    if (flags & Stats::Reset)
-        reset();
+    virtual void
+    process()
+    {
+        if (dump)
+            Stats::dump();
 
-    if (repeat)
-        schedule(curTick + repeat);
-}
+        if (reset)
+            Stats::reset();
 
-list<Output *> OutputList;
+        if (repeat) {
+            Stats::schedStatEvent(dump, reset, curTick() + repeat, repeat);
+        }
+    }
+
+    const char *description() const { return "GlobalStatEvent"; }
+};
 
 void
-DumpNow()
+schedStatEvent(bool dump, bool reset, Tick when, Tick repeat)
 {
-    assert(lastDump <= curTick);
-    if (lastDump == curTick)
-        return;
-    lastDump = curTick;
-
-    list<Output *>::iterator i = OutputList.begin();
-    list<Output *>::iterator end = OutputList.end();
-    for (; i != end; ++i) {
-        Output *output = *i;
-        if (!output->valid())
-            continue;
-
-        output->output();
-    }
+    // simQuantum is being added to the time when the stats would be
+    // dumped so as to ensure that this event happens only after the next
+    // sync amongst the event queues.  Asingle event queue simulation
+    // should remain unaffected.
+    dumpEvent = new StatEvent(when + simQuantum, dump, reset, repeat);
 }
 
 void
-SetupEvent(int flags, Tick when, Tick repeat)
+periodicStatDump(Tick period)
 {
-    new StatEvent(flags, when, repeat);
-}
+    /*
+     * If the period is set to 0, then we do not want to dump periodically,
+     * thus we deschedule the event. Else, if the period is not 0, but the event
+     * has already been scheduled, we need to get rid of the old event before we
+     * create a new one, as the old event will no longer be moved forward in the
+     * event that we resume from a checkpoint.
+     */
+    if (dumpEvent != NULL && (period == 0 || dumpEvent->scheduled())) {
+        // Event should AutoDelete, so we do not need to free it.
+        dumpEvent->deschedule();
+    }
 
-/* namespace Stats */ }
+    /*
+     * If the period is not 0, we schedule the event. If this is called with a
+     * period that is less than the current tick, then we shift the first dump
+     * by curTick. This ensures that we do not schedule the event is the past.
+     */
+    if (period != 0) {
+        // Schedule the event
+        if (period >= curTick()) {
+            schedStatEvent(true, true, (Tick)period, (Tick)period);
+        } else {
+            schedStatEvent(true, true, (Tick)period + curTick(), (Tick)period);
+        }
+    }
+}
 
-void debugDumpStats()
+void
+updateEvents()
 {
-    Stats::DumpNow();
+    /*
+     * If the dumpEvent has been scheduled, but is scheduled in the past, then
+     * we need to shift the event to be at a valid point in time. Therefore, we
+     * shift the event by curTick.
+     */
+    if (dumpEvent != NULL &&
+        (dumpEvent->scheduled() && dumpEvent->when() < curTick())) {
+        // shift by curTick() and reschedule
+        Tick _when = dumpEvent->when();
+        dumpEvent->reschedule(_when + curTick());
+    }
 }
 
+} // namespace Stats