changeset 6fec8f26e56d in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=6fec8f26e56d
description:
        sim: Move the draining interface into a separate base class

        This patch moves the draining interface from SimObject to a separate
        class that can be used by any object needing draining. However,
        objects not visible to the Python code (i.e., objects not deriving
        from SimObject) still depend on their parents informing them when to
        drain. This patch also gets rid of the CountedDrainEvent (which isn't
        really an event) and replaces it with a DrainManager.

diffstat:

 src/arch/arm/table_walker.cc               |   24 +-
 src/arch/arm/table_walker.hh               |    6 +-
 src/cpu/o3/cpu.cc                          |   26 +-
 src/cpu/o3/cpu.hh                          |    8 +-
 src/cpu/simple/atomic.cc                   |   28 ++-
 src/cpu/simple/atomic.hh                   |    4 +-
 src/cpu/simple/timing.cc                   |   59 ++++---
 src/cpu/simple/timing.hh                   |    8 +-
 src/cpu/testers/traffic_gen/traffic_gen.cc |    4 +-
 src/cpu/testers/traffic_gen/traffic_gen.hh |    2 +-
 src/dev/copy_engine.cc                     |   42 ++--
 src/dev/copy_engine.hh                     |   15 +-
 src/dev/dma_device.cc                      |   20 +-
 src/dev/dma_device.hh                      |    7 +-
 src/dev/i8254xGBe.cc                       |   44 ++--
 src/dev/i8254xGBe.hh                       |   11 +-
 src/dev/ide_disk.cc                        |    6 +-
 src/dev/io_device.cc                       |    8 +-
 src/dev/io_device.hh                       |    2 +-
 src/dev/ns_gige.cc                         |   12 +-
 src/dev/ns_gige.hh                         |    2 +-
 src/dev/pcidev.cc                          |    8 +-
 src/dev/pcidev.hh                          |    2 +-
 src/dev/sinic.cc                           |    8 +-
 src/dev/sinic.hh                           |    2 +-
 src/mem/bus.cc                             |   15 +-
 src/mem/bus.hh                             |   10 +-
 src/mem/cache/base.cc                      |   12 +-
 src/mem/cache/base.hh                      |    4 +-
 src/mem/coherent_bus.cc                    |    4 +-
 src/mem/coherent_bus.hh                    |    2 +-
 src/mem/noncoherent_bus.cc                 |    4 +-
 src/mem/noncoherent_bus.hh                 |    2 +-
 src/mem/packet_queue.cc                    |   12 +-
 src/mem/packet_queue.hh                    |   15 +-
 src/mem/qport.hh                           |   16 +-
 src/mem/ruby/system/MemoryControl.hh       |    2 -
 src/mem/ruby/system/RubyMemoryControl.cc   |    2 +-
 src/mem/ruby/system/RubyMemoryControl.hh   |    2 +-
 src/mem/ruby/system/RubyPort.cc            |   36 ++--
 src/mem/ruby/system/RubyPort.hh            |    6 +-
 src/mem/ruby/system/Sequencer.cc           |    5 +-
 src/mem/simple_dram.cc                     |   24 +-
 src/mem/simple_dram.hh                     |    6 +-
 src/mem/simple_mem.cc                      |    8 +-
 src/mem/simple_mem.hh                      |    2 +-
 src/python/SConscript                      |    1 +
 src/python/m5/SimObject.py                 |   31 ++-
 src/python/m5/__init__.py                  |    1 +
 src/python/m5/internal/__init__.py         |    1 +
 src/python/m5/simulate.py                  |   10 +-
 src/python/swig/drain.i                    |   66 ++++++++
 src/python/swig/event.i                    |    5 -
 src/python/swig/pyevent.cc                 |   19 --
 src/python/swig/pyevent.hh                 |    3 -
 src/sim/SConscript                         |    1 +
 src/sim/drain.cc                           |   73 +++++++++
 src/sim/drain.hh                           |  216 +++++++++++++++++++++++++++++
 src/sim/serialize.hh                       |    8 +-
 src/sim/sim_events.cc                      |   11 -
 src/sim/sim_object.cc                      |   10 +-
 src/sim/sim_object.hh                      |  113 +-------------
 src/sim/system.cc                          |   13 +-
 src/sim/system.hh                          |    4 +-
 64 files changed, 690 insertions(+), 443 deletions(-)

diffs (truncated from 2710 to 300 lines):

diff -r a0eff1e9c773 -r 6fec8f26e56d src/arch/arm/table_walker.cc
--- a/src/arch/arm/table_walker.cc      Fri Nov 02 11:32:01 2012 -0500
+++ b/src/arch/arm/table_walker.cc      Fri Nov 02 11:32:01 2012 -0500
@@ -51,7 +51,7 @@
 using namespace ArmISA;
 
 TableWalker::TableWalker(const Params *p)
-    : MemObject(p), port(this, params()->sys), drainEvent(NULL),
+    : MemObject(p), port(this, params()->sys), drainManager(NULL),
       tlb(NULL), currState(NULL), pending(false),
       masterId(p->sys->getMasterId(name())),
       numSquashable(p->num_squash_per_cycle),
@@ -68,30 +68,30 @@
 void
 TableWalker::completeDrain()
 {
-    if (drainEvent && stateQueueL1.empty() && stateQueueL2.empty() &&
+    if (drainManager && stateQueueL1.empty() && stateQueueL2.empty() &&
         pendingQueue.empty()) {
-        changeState(Drained);
+        setDrainState(Drainable::Drained);
         DPRINTF(Drain, "TableWalker done draining, processing drain event\n");
-        drainEvent->process();
-        drainEvent = NULL;
+        drainManager->signalDrainDone();
+        drainManager = NULL;
     }
 }
 
 unsigned int
-TableWalker::drain(Event *de)
+TableWalker::drain(DrainManager *dm)
 {
-    unsigned int count = port.drain(de);
+    unsigned int count = port.drain(dm);
 
     if (stateQueueL1.empty() && stateQueueL2.empty() &&
         pendingQueue.empty()) {
-        changeState(Drained);
+        setDrainState(Drainable::Drained);
         DPRINTF(Drain, "TableWalker free, no need to drain\n");
 
         // table walker is drained, but its ports may still need to be drained
         return count;
     } else {
-        drainEvent = de;
-        changeState(Draining);
+        drainManager = dm;
+        setDrainState(Drainable::Draining);
         DPRINTF(Drain, "TableWalker not drained\n");
 
         // return port drain count plus the table walker itself needs to drain
@@ -101,9 +101,9 @@
 }
 
 void
-TableWalker::resume()
+TableWalker::drainResume()
 {
-    MemObject::resume();
+    Drainable::drainResume();
     if ((params()->sys->getMemoryMode() == Enums::timing) && currState) {
         delete currState;
         currState = NULL;
diff -r a0eff1e9c773 -r 6fec8f26e56d src/arch/arm/table_walker.hh
--- a/src/arch/arm/table_walker.hh      Fri Nov 02 11:32:01 2012 -0500
+++ b/src/arch/arm/table_walker.hh      Fri Nov 02 11:32:01 2012 -0500
@@ -364,7 +364,7 @@
     SnoopingDmaPort port;
 
     /** If we're draining keep the drain event around until we're drained */
-    Event *drainEvent;
+    DrainManager *drainManager;
 
     /** TLB that is initiating these table walks */
     TLB *tlb;
@@ -397,8 +397,8 @@
 
     /** Checks if all state is cleared and if so, completes drain */
     void completeDrain();
-    virtual unsigned int drain(Event *de);
-    virtual void resume();
+    unsigned int drain(DrainManager *dm);
+    void drainResume();
     virtual BaseMasterPort& getMasterPort(const std::string &if_name,
                                           PortID idx = InvalidPortID);
 
diff -r a0eff1e9c773 -r 6fec8f26e56d src/cpu/o3/cpu.cc
--- a/src/cpu/o3/cpu.cc Fri Nov 02 11:32:01 2012 -0500
+++ b/src/cpu/o3/cpu.cc Fri Nov 02 11:32:01 2012 -0500
@@ -619,7 +619,7 @@
 
     if (!tickEvent.scheduled()) {
         if (_status == SwitchedOut ||
-            getState() == SimObject::Drained) {
+            getDrainState() == Drainable::Drained) {
             DPRINTF(O3CPU, "Switched out!\n");
             // increment stat
             lastRunningCycle = curCycle();
@@ -1077,7 +1077,7 @@
 void
 FullO3CPU<Impl>::serialize(std::ostream &os)
 {
-    SimObject::State so_state = SimObject::getState();
+    Drainable::State so_state(getDrainState());
     SERIALIZE_ENUM(so_state);
     BaseCPU::serialize(os);
     nameOut(os, csprintf("%s.tickEvent", name()));
@@ -1100,7 +1100,7 @@
 void
 FullO3CPU<Impl>::unserialize(Checkpoint *cp, const std::string &section)
 {
-    SimObject::State so_state;
+    Drainable::State so_state;
     UNSERIALIZE_ENUM(so_state);
     BaseCPU::unserialize(cp, section);
     tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
@@ -1120,7 +1120,7 @@
 
 template <class Impl>
 unsigned int
-FullO3CPU<Impl>::drain(Event *drain_event)
+FullO3CPU<Impl>::drain(DrainManager *drain_manager)
 {
     DPRINTF(O3CPU, "Switching out\n");
 
@@ -1137,12 +1137,12 @@
 
     // Wake the CPU and record activity so everything can drain out if
     // the CPU was not able to immediately drain.
-    if (getState() != SimObject::Drained) {
-        // A bit of a hack...set the drainEvent after all the drain()
+    if (getDrainState() != Drainable::Drained) {
+        // A bit of a hack...set the drainManager after all the drain()
         // calls have been made, that way if all of the stages drain
         // immediately, the signalDrained() function knows not to call
         // process on the drain event.
-        drainEvent = drain_event;
+        drainManager = drain_manager;
 
         wakeCPU();
         activityRec.activity();
@@ -1157,7 +1157,7 @@
 
 template <class Impl>
 void
-FullO3CPU<Impl>::resume()
+FullO3CPU<Impl>::drainResume()
 {
     fetch.resume();
     decode.resume();
@@ -1165,7 +1165,7 @@
     iew.resume();
     commit.resume();
 
-    changeState(SimObject::Running);
+    setDrainState(Drainable::Running);
 
     if (_status == SwitchedOut)
         return;
@@ -1185,14 +1185,14 @@
         if (tickEvent.scheduled())
             tickEvent.squash();
 
-        changeState(SimObject::Drained);
+        setDrainState(Drainable::Drained);
 
         BaseCPU::switchOut();
 
-        if (drainEvent) {
+        if (drainManager) {
             DPRINTF(Drain, "CPU done draining, processing drain event\n");
-            drainEvent->process();
-            drainEvent = NULL;
+            drainManager->signalDrainDone();
+            drainManager = NULL;
         }
     }
     assert(drainCount <= 5);
diff -r a0eff1e9c773 -r 6fec8f26e56d src/cpu/o3/cpu.hh
--- a/src/cpu/o3/cpu.hh Fri Nov 02 11:32:01 2012 -0500
+++ b/src/cpu/o3/cpu.hh Fri Nov 02 11:32:01 2012 -0500
@@ -431,10 +431,10 @@
 
     /** Starts draining the CPU's pipeline of all instructions in
      * order to stop all memory accesses. */
-    virtual unsigned int drain(Event *drain_event);
+    unsigned int drain(DrainManager *drain_manager);
 
     /** Resumes execution after a drain. */
-    virtual void resume();
+    void drainResume();
 
     /** Signals to this CPU that a stage has completed switching out. */
     void signalDrained();
@@ -730,8 +730,8 @@
     /** Pointer to the system. */
     System *system;
 
-    /** Event to call process() on once draining has completed. */
-    Event *drainEvent;
+    /** DrainManager to notify when draining has completed. */
+    DrainManager *drainManager;
 
     /** Counter of how many stages have completed draining. */
     int drainCount;
diff -r a0eff1e9c773 -r 6fec8f26e56d src/cpu/simple/atomic.cc
--- a/src/cpu/simple/atomic.cc  Fri Nov 02 11:32:01 2012 -0500
+++ b/src/cpu/simple/atomic.cc  Fri Nov 02 11:32:01 2012 -0500
@@ -123,7 +123,7 @@
 void
 AtomicSimpleCPU::serialize(ostream &os)
 {
-    SimObject::State so_state = SimObject::getState();
+    Drainable::State so_state(getDrainState());
     SERIALIZE_ENUM(so_state);
     SERIALIZE_SCALAR(locked);
     BaseSimpleCPU::serialize(os);
@@ -134,15 +134,22 @@
 void
 AtomicSimpleCPU::unserialize(Checkpoint *cp, const string &section)
 {
-    SimObject::State so_state;
+    Drainable::State so_state;
     UNSERIALIZE_ENUM(so_state);
     UNSERIALIZE_SCALAR(locked);
     BaseSimpleCPU::unserialize(cp, section);
     tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
 }
 
+unsigned int
+AtomicSimpleCPU::drain(DrainManager *drain_manager)
+{
+    setDrainState(Drainable::Drained);
+    return 0;
+}
+
 void
-AtomicSimpleCPU::resume()
+AtomicSimpleCPU::drainResume()
 {
     if (_status == Idle || _status == SwitchedOut)
         return;
@@ -150,7 +157,7 @@
     DPRINTF(SimpleCPU, "Resume\n");
     assert(system->getMemoryMode() == Enums::atomic);
 
-    changeState(SimObject::Running);
+    setDrainState(Drainable::Running);
     if (thread->status() == ThreadContext::Active) {
         if (!tickEvent.scheduled())
             schedule(tickEvent, nextCycle());
@@ -161,7 +168,7 @@
 void
 AtomicSimpleCPU::switchOut()
 {
-    assert(_status == Running || _status == Idle);
+    assert(_status == BaseSimpleCPU::Running || _status == Idle);
     _status = SwitchedOut;
 
     tickEvent.squash();
@@ -180,13 +187,14 @@
     ThreadID size = threadContexts.size();
     for (ThreadID i = 0; i < size; ++i) {
         ThreadContext *tc = threadContexts[i];
-        if (tc->status() == ThreadContext::Active && _status != Running) {
-            _status = Running;
+        if (tc->status() == ThreadContext::Active &&
+            _status != BaseSimpleCPU::Running) {
+            _status = BaseSimpleCPU::Running;
             schedule(tickEvent, nextCycle());
             break;
         }
     }
-    if (_status != Running) {
+    if (_status != BaseSimpleCPU::Running) {
         _status = Idle;
     }
     assert(threadContexts.size() == 1);
@@ -212,7 +220,7 @@
 
     //Make sure ticks are still on multiples of cycles
     schedule(tickEvent, clockEdge(delay));
-    _status = Running;
+    _status = BaseSimpleCPU::Running;
 }
 
 
@@ -227,7 +235,7 @@
     if (_status == Idle)
         return;
 
-    assert(_status == Running);
+    assert(_status == BaseSimpleCPU::Running);
 
     // tick event may not be scheduled if this gets called from inside
     // an instruction's execution, e.g. "quiesce"
diff -r a0eff1e9c773 -r 6fec8f26e56d src/cpu/simple/atomic.hh
--- a/src/cpu/simple/atomic.hh  Fri Nov 02 11:32:01 2012 -0500
+++ b/src/cpu/simple/atomic.hh  Fri Nov 02 11:32:01 2012 -0500
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to