From ba11a02cf2e6259d091017f7d44ca1551736ccd3 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Thu, 30 May 2013 12:54:03 -0400 Subject: [PATCH] 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. --- 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(-) diff --git a/src/cpu/testers/traffic_gen/traffic_gen.cc b/src/cpu/testers/traffic_gen/traffic_gen.cc index 0aef7e061..3e2dc6eb2 100644 --- a/src/cpu/testers/traffic_gen/traffic_gen.cc +++ b/src/cpu/testers/traffic_gen/traffic_gen.cc @@ -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 @@ TrafficGen::TrafficGen(const TrafficGenParams* p) : 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 @@ TrafficGen::init() 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 @@ TrafficGen::initState() { // 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 @@ TrafficGen::serialize(ostream &os) 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 @@ void 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 @@ TrafficGen::StateGraph::parseConfig(const string& file_name, 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 @@ TrafficGen::StateGraph::parseConfig(const string& file_name, } 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 @@ TrafficGen::StateGraph::transition() } void -TrafficGen::StateGraph::enterState(uint32_t newState) +TrafficGen::enterState(uint32_t newState) { DPRINTF(TrafficGen, "Transition to state %d\n", newState); diff --git a/src/cpu/testers/traffic_gen/traffic_gen.hh b/src/cpu/testers/traffic_gen/traffic_gen.hh index 6793e24b6..a2fcd3bc0 100644 --- a/src/cpu/testers/traffic_gen/traffic_gen.hh +++ b/src/cpu/testers/traffic_gen/traffic_gen.hh @@ -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,18 +49,65 @@ /** * 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 { 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 @@ class TrafficGen : public MemObject */ 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 > 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 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. - * - * @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 state graph event - */ - Tick nextEventTick() - { - return std::min(states[currState]->nextExecuteTick(), - nextTransitionTick); - - } - - /** Time of next transition */ - Tick nextTransitionTick; - - private: - - /** - * 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); - - /** Struct to represent a probabilistic transition during parsing. */ - struct Transition { - uint32_t from; - uint32_t to; - double p; - }; - - /** Pointer to owner of request handler */ - TrafficGen& owner; - - /** Pointer to request handler */ - QueuedMasterPort& port; - - /** State transition matrix */ - std::vector > transitionMatrix; - - public: - - /** Index of the current state */ - uint32_t currState; - - /** Map of states */ - m5::hash_map states; - }; - - - /** Queued handler */ + /** Queued master port */ class TrafficGenPort : public QueuedMasterPort { public: @@ -197,20 +150,11 @@ class TrafficGen : public MemObject }; + /** The instance of master port used by the traffic generator. */ TrafficGenPort port; - /** Request generator state graph */ - StateGraph stateGraph; - - /** - * Schedules event for next update and executes an update on the - * state graph. - */ - void updateStateGraph(); - - /** Event for updating the state graph */ - EventWrapper updateStateGraphEvent; + /** Event for scheduling updates */ + EventWrapper updateEvent; public: