| /* | |
| * Copyright (c) 2013-2014 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. | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions are | |
| * met: redistributions of source code must retain the above copyright | |
| * notice, this list of conditions and the following disclaimer; | |
| * redistributions in binary form must reproduce the above copyright | |
| * notice, this list of conditions and the following disclaimer in the | |
| * documentation and/or other materials provided with the distribution; | |
| * neither the name of the copyright holders nor the names of its | |
| * contributors may be used to endorse or promote products derived from | |
| * this software without specific prior written permission. | |
| * | |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| * | |
| * Authors: Andrew Bardsley | |
| */ | |
| /** | |
| * @file | |
| * | |
| * Base classes for ClockedObjects which have evaluate functions to | |
| * look like clock ticking operations. TickedObject attaches gem5's event | |
| * queue to Ticked to apply actual scheduling. | |
| */ | |
| #ifndef __SIM_TICKED_OBJECT_HH__ | |
| #define __SIM_TICKED_OBJECT_HH__ | |
| #include "params/TickedObject.hh" | |
| #include "sim/clocked_object.hh" | |
| /** Ticked attaches gem5's event queue/scheduler to evaluate | |
| * calls and provides a start/stop interface to ticking. | |
| * | |
| * Ticked is not a ClockedObject but can be attached to one by | |
| * inheritance and by calling regStats, serialize/unserialize */ | |
| class Ticked | |
| { | |
| protected: | |
| /** An event to call process periodically */ | |
| class ClockEvent : public Event | |
| { | |
| public: | |
| Ticked &owner; | |
| ClockEvent(Ticked &owner_, Priority priority) : | |
| Event(priority), | |
| owner(owner_) | |
| { } | |
| /** Evaluate and reschedule */ | |
| void | |
| process() | |
| { | |
| ++owner.tickCycles; | |
| ++owner.numCycles; | |
| owner.countCycles(Cycles(1)); | |
| owner.evaluate(); | |
| if (owner.running) { | |
| owner.object.schedule(this, | |
| owner.object.clockEdge(Cycles(1))); | |
| } | |
| } | |
| }; | |
| friend class ClockEvent; | |
| /** ClockedObject who is responsible for this Ticked's actions/stats */ | |
| ClockedObject &object; | |
| /** The single instance of ClockEvent used */ | |
| ClockEvent event; | |
| /** Have I been started? and am not stopped */ | |
| bool running; | |
| /** Time of last stop event to calculate run time */ | |
| Cycles lastStopped; | |
| private: | |
| /** Locally allocated stats */ | |
| Stats::Scalar *numCyclesLocal; | |
| protected: | |
| /** Total number of cycles either ticked or spend stopped */ | |
| Stats::Scalar &numCycles; | |
| /** Number of cycles ticked */ | |
| Stats::Scalar tickCycles; | |
| /** Number of cycles stopped */ | |
| Stats::Formula idleCycles; | |
| public: | |
| Ticked(ClockedObject &object_, | |
| Stats::Scalar *imported_num_cycles = NULL, | |
| Event::Priority priority = Event::CPU_Tick_Pri); | |
| virtual ~Ticked() { } | |
| /** Register {num,ticks}Cycles if necessary. If numCycles is | |
| * imported, be sure to register it *before* calling this regStats */ | |
| void regStats(); | |
| /** Start ticking */ | |
| void | |
| start() | |
| { | |
| if (!running) { | |
| if (!event.scheduled()) | |
| object.schedule(event, object.clockEdge(Cycles(1))); | |
| running = true; | |
| numCycles += cyclesSinceLastStopped(); | |
| countCycles(cyclesSinceLastStopped()); | |
| } | |
| } | |
| /** How long have we been stopped for? */ | |
| Cycles | |
| cyclesSinceLastStopped() const | |
| { | |
| return object.curCycle() - lastStopped; | |
| } | |
| /** Reset stopped time to current time */ | |
| void | |
| resetLastStopped() | |
| { | |
| lastStopped = object.curCycle(); | |
| } | |
| /** Cancel the next tick event and issue no more */ | |
| void | |
| stop() | |
| { | |
| if (running) { | |
| if (event.scheduled()) | |
| object.deschedule(event); | |
| running = false; | |
| resetLastStopped(); | |
| } | |
| } | |
| /** Checkpoint lastStopped */ | |
| void serialize(std::ostream &os); | |
| void unserialize(Checkpoint *cp, const std::string §ion); | |
| /** Action to call on the clock tick */ | |
| virtual void evaluate() = 0; | |
| /** | |
| * Callback to handle cycle statistics and probes. | |
| * | |
| * This callback is called at the beginning of a new cycle active | |
| * cycle and when restarting the ticked object. The delta | |
| * parameter indicates the number of cycles elapsed since the | |
| * previous call is normally '1' unless the object has been | |
| * stopped and restarted. | |
| * | |
| * @param delta Number of cycles since the previous call. | |
| */ | |
| virtual void countCycles(Cycles delta) {} | |
| }; | |
| /** TickedObject attaches Ticked to ClockedObject and can be used as | |
| * a base class where ticked operation */ | |
| class TickedObject : public ClockedObject, public Ticked | |
| { | |
| public: | |
| TickedObject(TickedObjectParams *params, | |
| Event::Priority priority = Event::CPU_Tick_Pri); | |
| /** Disambiguate to make these functions overload correctly */ | |
| using ClockedObject::regStats; | |
| using ClockedObject::serialize; | |
| using ClockedObject::unserialize; | |
| /** Pass on regStats, serialize etc. onto Ticked */ | |
| void regStats(); | |
| void serialize(std::ostream &os); | |
| void unserialize(Checkpoint *cp, const std::string §ion); | |
| }; | |
| #endif /* __SIM_TICKED_OBJECT_HH__ */ |