kvm, arm: Switch to the device EQ when accessing ISA devices
[gem5.git] / src / sim / sim_events.cc
index 2ccc9dad20047236ffb795a694cbefc6fbde0d0d..23da8fd8de945d37b78e376c6602224bb86b5da5 100644 (file)
@@ -1,5 +1,19 @@
 /*
+ * Copyright (c) 2013 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) 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
  * Authors: Nathan Binkert
  */
 
+#include "sim/sim_events.hh"
+
 #include <string>
 
 #include "base/callback.hh"
 #include "base/hostinfo.hh"
-#include "sim/eventq.hh"
-#include "sim/param.hh"
-#include "sim/sim_events.hh"
+#include "sim/eventq_impl.hh"
 #include "sim/sim_exit.hh"
-#include "sim/startup.hh"
 #include "sim/stats.hh"
 
 using namespace std;
 
-//
-// handle termination event
-//
-void
-SimLoopExitEvent::process()
+GlobalSimLoopExitEvent::GlobalSimLoopExitEvent(Tick when,
+                                               const std::string &_cause,
+                                               int c, Tick r)
+    : GlobalEvent(when, Sim_Exit_Pri, IsExitEvent),
+      cause(_cause), code(c), repeat(r)
 {
-    // if this got scheduled on a different queue (e.g. the committed
-    // instruction queue) then make a corresponding event on the main
-    // queue.
-    if (theQueue() != &mainEventQueue) {
-        exitSimLoop(cause, code);
-        delete this;
-    }
-
-    // otherwise do nothing... the IsExitEvent flag takes care of
-    // exiting the simulation loop and returning this object to Python
-
-    // but if you are doing this on intervals, don't forget to make another
-    if (repeat) {
-        schedule(curTick + repeat);
-    }
 }
 
-
 const char *
-SimLoopExitEvent::description()
+GlobalSimLoopExitEvent::description() const
 {
-    return "simulation loop exit";
-}
-
-SimLoopExitEvent *
-schedExitSimLoop(const std::string &message, Tick when, Tick repeat,
-                 EventQueue *q, int exit_code)
-{
-    if (q == NULL)
-        q = &mainEventQueue;
-
-    return new SimLoopExitEvent(q, when, repeat, message, exit_code);
+    return "global simulation loop exit";
 }
 
+//
+// handle termination event
+//
 void
-exitSimLoop(const std::string &message, int exit_code)
+GlobalSimLoopExitEvent::process()
 {
-    schedExitSimLoop(message, curTick, 0, NULL, exit_code);
+    if (repeat) {
+        schedule(curTick() + repeat);
+    }
 }
 
 void
-CountedDrainEvent::process()
+exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat,
+            bool serialize)
 {
-    if (--count == 0) {
-        exitSimLoop("Finished drain");
-    }
+    warn_if(serialize && (when != curTick() || repeat),
+            "exitSimLoop called with a delay and auto serialization. This is "
+            "currently unsupported.");
+
+    new GlobalSimLoopExitEvent(when + simQuantum, message, exit_code, repeat);
 }
 
-//
-// constructor: automatically schedules at specified time
-//
-CountedExitEvent::CountedExitEvent(EventQueue *q, const std::string &_cause,
-                                   Tick _when, int &_downCounter)
-    : Event(q, Sim_Exit_Pri),
-      cause(_cause),
-      downCounter(_downCounter)
+LocalSimLoopExitEvent::LocalSimLoopExitEvent(const std::string &_cause, int c,
+                                   Tick r)
+    : Event(Sim_Exit_Pri, IsExitEvent),
+      cause(_cause), code(c), repeat(r)
 {
-    // catch stupid mistakes
-    assert(downCounter > 0);
-
-    schedule(_when);
 }
 
-
 //
 // handle termination event
 //
 void
-CountedExitEvent::process()
+LocalSimLoopExitEvent::process()
 {
-    if (--downCounter == 0) {
-        exitSimLoop(cause, 0);
-    }
+    exitSimLoop(cause, 0);
 }
 
 
 const char *
-CountedExitEvent::description()
+LocalSimLoopExitEvent::description() const
 {
-    return "counted exit";
+    return "simulation loop exit";
 }
 
-#ifdef CHECK_SWAP_CYCLES
-new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES);
-#endif
-
 void
-CheckSwapEvent::process()
+LocalSimLoopExitEvent::serialize(CheckpointOut &cp) const
 {
-    /*  Check the amount of free swap space  */
-    long swap;
-
-    /*  returns free swap in KBytes  */
-    swap = procInfo("/proc/meminfo", "SwapFree:");
+    Event::serialize(cp);
 
-    if (swap < 1000)
-        ccprintf(cerr, "\a\a\aWarning! Swap space is low (%d)\n", swap);
+    SERIALIZE_SCALAR(cause);
+    SERIALIZE_SCALAR(code);
+    SERIALIZE_SCALAR(repeat);
+}
 
-    if (swap < 100) {
-        cerr << "\a\aAborting Simulation! Inadequate swap space!\n\n";
-        exitSimLoop("Lack of swap space");
-    }
+void
+LocalSimLoopExitEvent::unserialize(CheckpointIn &cp)
+{
+    Event::unserialize(cp);
 
-    schedule(curTick + interval);
+    UNSERIALIZE_SCALAR(cause);
+    UNSERIALIZE_SCALAR(code);
+    UNSERIALIZE_SCALAR(repeat);
 }
 
-const char *
-CheckSwapEvent::description()
+//
+// constructor: automatically schedules at specified time
+//
+CountedExitEvent::CountedExitEvent(const std::string &_cause, int &counter)
+    : Event(Sim_Exit_Pri), cause(_cause), downCounter(counter)
 {
-    return "check swap";
+    // catch stupid mistakes
+    assert(downCounter > 0);
 }
 
+
 //
-// handle progress event: print message and reschedule
+// handle termination event
 //
 void
-ProgressEvent::process()
+CountedExitEvent::process()
 {
-    DPRINTFN("ProgressEvent\n");
-    // reschedule for next interval
-    schedule(curTick + interval);
+    if (--downCounter == 0) {
+        exitSimLoop(cause, 0);
+    }
 }
 
 
 const char *
-ProgressEvent::description()
+CountedExitEvent::description() const
 {
-    return "progress message";
+    return "counted exit";
 }