changeset dd2e46b239c1 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=dd2e46b239c1
description:
        cpu: Fold together the StateGraph and the TrafficGen

        This patch simplifies the object hierarchy of the traffic generator by
        getting rid of the StateGraph class and folding this functionality
        into the traffic generator itself.

        The main goal of this patch is to facilitate upcoming changes by
        reducing the number of affected layers.

diffstat:

 src/cpu/testers/traffic_gen/traffic_gen.cc |   73 ++++------
 src/cpu/testers/traffic_gen/traffic_gen.hh |  188 ++++++++++------------------
 2 files changed, 98 insertions(+), 163 deletions(-)

diffs (truncated from 387 to 300 lines):

diff -r 131cd1e24b70 -r dd2e46b239c1 src/cpu/testers/traffic_gen/traffic_gen.cc
--- a/src/cpu/testers/traffic_gen/traffic_gen.cc        Thu May 30 12:54:02 
2013 -0400
+++ b/src/cpu/testers/traffic_gen/traffic_gen.cc        Thu May 30 12:54:03 
2013 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012-2013 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -54,10 +54,11 @@
     : MemObject(p),
       system(p->system),
       masterID(system->getMasterId(name())),
+      nextTransitionTick(0),
       port(name() + ".port", *this),
-      stateGraph(*this, port, p->config_file, masterID),
-      updateStateGraphEvent(this)
+      updateEvent(this)
 {
+    parseConfig(p->config_file, masterID);
 }
 
 TrafficGen*
@@ -87,7 +88,7 @@
         DPRINTF(TrafficGen, "Timing mode, activating request generator\n");
 
         // enter initial state
-        stateGraph.enterState(stateGraph.currState);
+        enterState(currState);
     } else {
         DPRINTF(TrafficGen,
                 "Traffic generator is only active in timing mode\n");
@@ -99,8 +100,7 @@
 {
     // when not restoring from a checkpoint, make sure we kick things off
     if (system->isTimingMode()) {
-        Tick nextStateGraphEvent = stateGraph.nextEventTick();
-        schedule(updateStateGraphEvent, nextStateGraphEvent);
+        schedule(updateEvent, nextEventTick());
     } else {
         DPRINTF(TrafficGen,
                 "Traffic generator is only active in timing mode\n");
@@ -121,15 +121,14 @@
     DPRINTF(Checkpoint, "Serializing TrafficGen\n");
 
     // save ticks of the graph event if it is scheduled
-    Tick nextStateGraphEvent = updateStateGraphEvent.scheduled() ?
-        updateStateGraphEvent.when() : 0;
+    Tick nextEvent = updateEvent.scheduled() ?
+        updateEvent.when() : 0;
 
-    DPRINTF(TrafficGen, "Saving nextStateGraphEvent=%llu\n",
-            nextStateGraphEvent);
+    DPRINTF(TrafficGen, "Saving nextEvent=%llu\n",
+            nextEvent);
 
-    SERIALIZE_SCALAR(nextStateGraphEvent);
+    SERIALIZE_SCALAR(nextEvent);
 
-    Tick nextTransitionTick = stateGraph.nextTransitionTick;
     SERIALIZE_SCALAR(nextTransitionTick);
 
     // @todo: also serialise the current state, figure out the best
@@ -140,34 +139,39 @@
 TrafficGen::unserialize(Checkpoint* cp, const string& section)
 {
     // restore scheduled events
-    Tick nextStateGraphEvent;
-    UNSERIALIZE_SCALAR(nextStateGraphEvent);
-    if (nextStateGraphEvent != 0) {
-        schedule(updateStateGraphEvent, nextStateGraphEvent);
+    Tick nextEvent;
+    UNSERIALIZE_SCALAR(nextEvent);
+    if (nextEvent != 0) {
+        schedule(updateEvent, nextEvent);
     }
 
-    Tick nextTransitionTick;
     UNSERIALIZE_SCALAR(nextTransitionTick);
-    stateGraph.nextTransitionTick = nextTransitionTick;
 }
 
 void
-TrafficGen::updateStateGraph()
+TrafficGen::update()
 {
     // schedule next update event based on either the next execute
     // tick or the next transition, which ever comes first
-    Tick nextStateGraphEvent = stateGraph.nextEventTick();
+    Tick nextEvent = nextEventTick();
     DPRINTF(TrafficGen, "Updating state graph, next event at %lld\n",
-            nextStateGraphEvent);
-    schedule(updateStateGraphEvent, nextStateGraphEvent);
+            nextEvent);
+    schedule(updateEvent, nextEvent);
 
     // perform the update associated with the current update event
-    stateGraph.update();
+
+    // if we have reached the time for the next state transition, then
+    // perform the transition
+    if (curTick() >= nextTransitionTick) {
+        transition();
+    } else {
+        // we are still in the current state and should execute it
+        states[currState]->execute();
+    }
 }
 
 void
-TrafficGen::StateGraph::parseConfig(const string& file_name,
-                                    MasterID master_id)
+TrafficGen::parseConfig(const string& file_name, MasterID master_id)
 {
     // keep track of the transitions parsed to create the matrix when
     // done
@@ -178,7 +182,7 @@
     infile.open(file_name.c_str(), ifstream::in);
     if (!infile.is_open()) {
         fatal("Traffic generator %s config file not found at %s\n",
-              owner.name(), file_name);
+              name(), file_name);
     }
 
     // read line by line and determine the action based on the first
@@ -302,20 +306,7 @@
 }
 
 void
-TrafficGen::StateGraph::update()
-{
-    // if we have reached the time for the next state transition, then
-    // perform the transition
-    if (curTick() >= nextTransitionTick) {
-        transition();
-    } else {
-        // we are still in the current state and should execute it
-        states[currState]->execute();
-    }
-}
-
-void
-TrafficGen::StateGraph::transition()
+TrafficGen::transition()
 {
     // exit the current state
     states[currState]->exit();
@@ -334,7 +325,7 @@
 }
 
 void
-TrafficGen::StateGraph::enterState(uint32_t newState)
+TrafficGen::enterState(uint32_t newState)
 {
     DPRINTF(TrafficGen, "Transition to state %d\n", newState);
 
diff -r 131cd1e24b70 -r dd2e46b239c1 src/cpu/testers/traffic_gen/traffic_gen.hh
--- a/src/cpu/testers/traffic_gen/traffic_gen.hh        Thu May 30 12:54:02 
2013 -0400
+++ b/src/cpu/testers/traffic_gen/traffic_gen.hh        Thu May 30 12:54:03 
2013 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012-2013 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -49,12 +49,12 @@
 
 /**
  * The traffic generator is a master module that generates stimuli for
- * the memory system, based on a collection of simple behaviours that
- * are either probabilistic or based on traces. It can be used stand
- * alone for creating test cases for interconnect and memory
- * controllers, or function as a black box replacement for system
- * components that are not yet modelled in detail, e.g. a video engine
- * or baseband subsystem.
+ * the memory system, based on a collection of simple generator
+ * behaviours that are either probabilistic or based on traces. It can
+ * be used stand alone for creating test cases for interconnect and
+ * memory controllers, or function as a black box replacement for
+ * system components that are not yet modelled in detail, e.g. a video
+ * engine or baseband subsystem.
  */
 class TrafficGen : public MemObject
 {
@@ -62,6 +62,53 @@
   private:
 
     /**
+     * Determine next state and perform the transition.
+     */
+    void transition();
+
+    /**
+     * Enter a new state.
+     *
+     * @param newState identifier of state to enter
+     */
+    void enterState(uint32_t newState);
+
+    /**
+     * Get the tick of the next event, either an execution or a
+     * transition.
+     *
+     * @return tick of the next update event
+     */
+    Tick nextEventTick()
+    {
+        return std::min(states[currState]->nextExecuteTick(),
+                        nextTransitionTick);
+    }
+
+    /**
+     * Parse the config file and build the state map and
+     * transition matrix.
+     *
+     * @param file_name Config file name to parse
+     * @param master_id MasterID to use for generated requests
+     */
+    void parseConfig(const std::string& file_name, MasterID master_id);
+
+    /**
+     * Schedules event for next update and executes an update on the
+     * state graph, either performing a state transition or executing
+     * the current state, depending on the current time.
+     */
+    void update();
+
+    /** Struct to represent a probabilistic transition during parsing. */
+    struct Transition {
+        uint32_t from;
+        uint32_t to;
+        double p;
+    };
+
+    /**
      * The system used to determine which mode we are currently operating
      * in.
      */
@@ -72,113 +119,19 @@
      */
     MasterID masterID;
 
-  protected:
+    /** Time of next transition */
+    Tick nextTransitionTick;
 
-    /**
-     * The state graph is responsible for instantiating and keeping
-     * track of the various generator states and also perform the
-     * transitions and call the appropriate functions when entering,
-     * executing and exiting a state.
-     */
-    class StateGraph
-    {
+    /** State transition matrix */
+    std::vector<std::vector<double> > transitionMatrix;
 
-      public:
+    /** Index of the current state */
+    uint32_t currState;
 
-        /**
-         * Create a state graph from an input file.
-         *
-         * @param _owner used solely for the name
-         * @param _port port used to send requests
-         * @param file_name configuration description to read in
-         * @param master_id the unique id used for all requests
-         */
-        StateGraph(TrafficGen& _owner, QueuedMasterPort& _port,
-                   const std::string& file_name, MasterID master_id)
-            : nextTransitionTick(0), owner(_owner), port(_port)
-        {
-            parseConfig(file_name, master_id);
-        }
+    /** Map of generator states */
+    m5::hash_map<uint32_t, BaseGen*> states;
 
-        /**
-         * Get the name, used for DPRINTFs.
-         *
-         * @return the owner's name
-         */
-        std::string name() const { return owner.name(); }
-
-        /**
-         * Either perform a state transition or execute the current
-         * state, depending on the current time.
-         */
-        void update();
-
-        /**
-         * Determine next state and perform the transition.
-         */
-        void transition();
-
-        /**
-         * Enter a new state.
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to