arch-arm: Do not check MustBeOne flag for TLB requests from the prefetcher
[gem5.git] / src / sim / stat_control.cc
index 07e1b2380e1d917294cff4835d9450b3ddb16812..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/hostinfo.hh"
 #include "base/statistics.hh"
 #include "base/time.hh"
-
-#include "config/the_isa.hh"
-#if THE_ISA == NO_ISA
-#include "arch/noisa/cpu_dummy.hh"
-#else
 #include "cpu/base.hh"
-#endif
-
-#include "sim/eventq.hh"
+#include "sim/global_event.hh"
 
 using namespace std;
 
 Stats::Formula simSeconds;
 Stats::Value simTicks;
+Stats::Value finalTick;
 Stats::Value simFreq;
 
 namespace Stats {
@@ -60,27 +71,37 @@ namespace Stats {
 Time statTime(true);
 Tick startTick;
 
+GlobalEvent *dumpEvent;
+
 struct SimTicksReset : public Callback
 {
     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;
@@ -88,11 +109,13 @@ SimTicksReset simTicksReset;
 struct Global
 {
     Stats::Formula hostInstRate;
+    Stats::Formula hostOpRate;
     Stats::Formula hostTickRate;
     Stats::Value hostMemory;
     Stats::Value hostSeconds;
 
     Stats::Value simInsts;
+    Stats::Value simOps;
 
     Global();
 };
@@ -100,13 +123,21 @@ struct 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")
@@ -124,6 +155,13 @@ Global::Global()
         .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)")
@@ -131,6 +169,13 @@ Global::Global()
         .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")
@@ -153,6 +198,7 @@ Global::Global()
 
     simSeconds = simTicks / simFreq;
     hostInstRate = simInsts / hostSeconds;
+    hostOpRate = simOps / hostSeconds;
     hostTickRate = simTicks / hostSeconds;
 
     registerResetCallback(&simTicksReset);
@@ -164,7 +210,10 @@ initSimStats()
     static Global global;
 }
 
-class _StatEvent : public Event
+/**
+ * Event to dump and/or reset the statistics.
+ */
+class StatEvent : public GlobalEvent
 {
   private:
     bool dump;
@@ -172,10 +221,10 @@ class _StatEvent : public Event
     Tick repeat;
 
   public:
-    _StatEvent(bool _dump, bool _reset, Tick _repeat)
-        : Event(Stat_Event_Pri), dump(_dump), reset(_reset), repeat(_repeat)
+    StatEvent(Tick _when, bool _dump, bool _reset, Tick _repeat)
+        : GlobalEvent(_when, Stat_Event_Pri, 0),
+          dump(_dump), reset(_reset), repeat(_repeat)
     {
-        setFlags(AutoDelete);
     }
 
     virtual void
@@ -188,17 +237,67 @@ class _StatEvent : public Event
             Stats::reset();
 
         if (repeat) {
-            Event *event = new _StatEvent(dump, reset, repeat);
-            mainEventQueue.schedule(event, curTick + repeat);
+            Stats::schedStatEvent(dump, reset, curTick() + repeat, repeat);
         }
     }
+
+    const char *description() const { return "GlobalStatEvent"; }
 };
 
 void
-StatEvent(bool dump, bool reset, Tick when, Tick repeat)
+schedStatEvent(bool dump, bool reset, Tick when, Tick repeat)
 {
-    Event *event = new _StatEvent(dump, reset, repeat);
-    mainEventQueue.schedule(event, when);
+    // 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
+periodicStatDump(Tick period)
+{
+    /*
+     * 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();
+    }
+
+    /*
+     * 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
+updateEvents()
+{
+    /*
+     * 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 */ }
+} // namespace Stats