eventq.hh revision 56
16019SN/A/* 26019SN/A * Copyright (c) 2003 The Regents of The University of Michigan 310037SARM gem5 Developers * All rights reserved. 47134Sgblack@eecs.umich.edu * 57134Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67134Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77134Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87134Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97134Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107134Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117134Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127134Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137134Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147134Sgblack@eecs.umich.edu * this software without specific prior written permission. 156019SN/A * 166019SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176019SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186019SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196019SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206019SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216019SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226019SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236019SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246019SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256019SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266019SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276019SN/A */ 286019SN/A 296019SN/A/* @file 306019SN/A * EventQueue interfaces 316019SN/A */ 326019SN/A 336019SN/A#ifndef __EVENTQ_HH__ 346019SN/A#define __EVENTQ_HH__ 356019SN/A 366019SN/A#include <assert.h> 376019SN/A 386019SN/A#include <algorithm> 396019SN/A#include <map> 406019SN/A#include <string> 416019SN/A#include <vector> 426308SN/A 436308SN/A#include "sim/host.hh" // for Tick 446309SN/A 456309SN/A#include "base/fast_alloc.hh" 466309SN/A#include "sim/serialize.hh" 476309SN/A#include "base/trace.hh" 486309SN/A 497134Sgblack@eecs.umich.educlass EventQueue; // forward declaration 508588Sgblack@eecs.umich.edu 516309SN/A/* 526309SN/A * An item on an event queue. The action caused by a given 537296Sgblack@eecs.umich.edu * event is specified by deriving a subclass and overriding the 548139SMatt.Horsnell@arm.com * process() member function. 556309SN/A */ 566309SN/Aclass Event : public Serializeable, public FastAlloc 576309SN/A{ 588588Sgblack@eecs.umich.edu friend class EventQueue; 597174Sgblack@eecs.umich.edu 607639Sgblack@eecs.umich.edu private: 617639Sgblack@eecs.umich.edu /// queue to which this event belongs (though it may or may not be 627644Sali.saidi@arm.com /// scheduled on this queue yet) 638139SMatt.Horsnell@arm.com EventQueue *queue; 647639Sgblack@eecs.umich.edu 657639Sgblack@eecs.umich.edu Event *next; 667639Sgblack@eecs.umich.edu 678588Sgblack@eecs.umich.edu Tick _when; //!< timestamp when event should be processed 687639Sgblack@eecs.umich.edu int _priority; //!< event priority 697639Sgblack@eecs.umich.edu char _flags; 707639Sgblack@eecs.umich.edu 717644Sali.saidi@arm.com protected: 728139SMatt.Horsnell@arm.com enum Flags { 737639Sgblack@eecs.umich.edu None = 0x0, 747639Sgblack@eecs.umich.edu Squashed = 0x1, 757639Sgblack@eecs.umich.edu Scheduled = 0x2, 767639Sgblack@eecs.umich.edu AutoDelete = 0x4 777639Sgblack@eecs.umich.edu }; 788588Sgblack@eecs.umich.edu 797639Sgblack@eecs.umich.edu bool getFlags(Flags f) const { return (_flags & f) == f; } 807639Sgblack@eecs.umich.edu void setFlags(Flags f) { _flags |= f; } 817639Sgblack@eecs.umich.edu void clearFlags(Flags f) { _flags &= ~f; } 827644Sali.saidi@arm.com 838139SMatt.Horsnell@arm.com protected: 847639Sgblack@eecs.umich.edu EventQueue *theQueue() const { return queue; } 857639Sgblack@eecs.umich.edu 867639Sgblack@eecs.umich.edu#if TRACING_ON 877639Sgblack@eecs.umich.edu Tick when_created; //!< Keep track of creation time For debugging 887174Sgblack@eecs.umich.edu Tick when_scheduled; //!< Keep track of creation time For debugging 898148SAli.Saidi@ARM.com 908303SAli.Saidi@ARM.com virtual void trace(const char *action); //!< trace event activity 917400SAli.Saidi@ARM.com#else 928303SAli.Saidi@ARM.com void trace(const char *) {} 938303SAli.Saidi@ARM.com#endif 9410037SARM gem5 Developers 9510037SARM gem5 Developers unsigned annotated_value; 968303SAli.Saidi@ARM.com 978303SAli.Saidi@ARM.com public: 988303SAli.Saidi@ARM.com 998303SAli.Saidi@ARM.com static const std::string defaultName; 1008303SAli.Saidi@ARM.com 1018303SAli.Saidi@ARM.com /* 1028205SAli.Saidi@ARM.com * Event constructor 1037858SMatt.Horsnell@arm.com * @param queue that the event gets scheduled on 1048285SPrakash.Ramrakhyani@arm.com */ 1056754SN/A Event(EventQueue *q, int p = 0) 1068148SAli.Saidi@ARM.com : Serializeable(defaultName), queue(q), next(NULL), 1076754SN/A _priority(p), _flags(None), 1086754SN/A#if TRACING_ON 1098148SAli.Saidi@ARM.com when_created(curTick), when_scheduled(0), 1108588Sgblack@eecs.umich.edu#endif 1116754SN/A annotated_value(0) 1128139SMatt.Horsnell@arm.com { 1137422Sgblack@eecs.umich.edu } 1148148SAli.Saidi@ARM.com 1158148SAli.Saidi@ARM.com ~Event() {} 1166754SN/A 1178588Sgblack@eecs.umich.edu /// Determine if the current event is scheduled 1186309SN/A bool scheduled() const { return getFlags(Scheduled); } 1196309SN/A 1207296Sgblack@eecs.umich.edu /// Schedule the event with the current priority or default priority 1217303Sgblack@eecs.umich.edu void schedule(Tick t); 1228139SMatt.Horsnell@arm.com 1236309SN/A /// Schedule the event with a specific priority 1246309SN/A void schedule(Tick t, int priority); 1256309SN/A 1268588Sgblack@eecs.umich.edu /// Reschedule the event with the current priority 1277174Sgblack@eecs.umich.edu void reschedule(Tick t); 1287174Sgblack@eecs.umich.edu 1297296Sgblack@eecs.umich.edu /// Reschedule the event with a specific priority 1307303Sgblack@eecs.umich.edu void reschedule(Tick t, int priority); 1317644Sali.saidi@arm.com 1328139SMatt.Horsnell@arm.com /// Remove the event from the current schedule 1337174Sgblack@eecs.umich.edu void deschedule(); 1347174Sgblack@eecs.umich.edu 1357174Sgblack@eecs.umich.edu /// Return a C string describing the event. This string should 1368588Sgblack@eecs.umich.edu /// *not* be dynamically allocated; just a const char array 1377639Sgblack@eecs.umich.edu /// describing the event class. 1387639Sgblack@eecs.umich.edu virtual const char *description(); 1397639Sgblack@eecs.umich.edu 1407639Sgblack@eecs.umich.edu /// Dump the current event data 1417644Sali.saidi@arm.com void dump(); 1428139SMatt.Horsnell@arm.com 1437639Sgblack@eecs.umich.edu /* 1447639Sgblack@eecs.umich.edu * This member function is invoked when the event is processed 1457639Sgblack@eecs.umich.edu * (occurs). There is no default implementation; each subclass 1467639Sgblack@eecs.umich.edu * must provide its own implementation. The event is not 1477639Sgblack@eecs.umich.edu * automatically deleted after it is processed (to allow for 1488588Sgblack@eecs.umich.edu * statically allocated event objects). 1497639Sgblack@eecs.umich.edu * 1507639Sgblack@eecs.umich.edu * If the AutoDestroy flag is set, the object is deleted once it 1517639Sgblack@eecs.umich.edu * is processed. 1527639Sgblack@eecs.umich.edu */ 1537644Sali.saidi@arm.com virtual void process() = 0; 1548139SMatt.Horsnell@arm.com 1557639Sgblack@eecs.umich.edu void annotate(unsigned value) { annotated_value = value; }; 1567639Sgblack@eecs.umich.edu unsigned annotation() { return annotated_value; } 1577639Sgblack@eecs.umich.edu 1587639Sgblack@eecs.umich.edu /// Squash the current event 1597639Sgblack@eecs.umich.edu void squash() { setFlags(Squashed); } 1607174Sgblack@eecs.umich.edu 1617174Sgblack@eecs.umich.edu /// Check whether the event is squashed 16210037SARM gem5 Developers bool squashed() { return getFlags(Squashed); } 16310037SARM gem5 Developers 1647639Sgblack@eecs.umich.edu /// Get the time that the event is scheduled 1657639Sgblack@eecs.umich.edu Tick when() const { return _when; } 1667174Sgblack@eecs.umich.edu 1677174Sgblack@eecs.umich.edu /// Get the event priority 1687174Sgblack@eecs.umich.edu int priority() const { return _priority; } 1697174Sgblack@eecs.umich.edu 1707174Sgblack@eecs.umich.edu struct priority_compare : 1717174Sgblack@eecs.umich.edu public std::binary_function<Event *, Event *, bool> 1727174Sgblack@eecs.umich.edu { 1737174Sgblack@eecs.umich.edu bool operator()(const Event *l, const Event *r) const { 1747174Sgblack@eecs.umich.edu return l->when() >= r->when() || l->priority() >= r->priority(); 1757174Sgblack@eecs.umich.edu } 1767174Sgblack@eecs.umich.edu }; 1776309SN/A}; 1786308SN/A 1797639Sgblack@eecs.umich.edutemplate <class T, void (T::* F)()> 1807639Sgblack@eecs.umich.eduvoid 1817639Sgblack@eecs.umich.eduDelayFunction(Tick when, T *object) 18210037SARM gem5 Developers{ 1837639Sgblack@eecs.umich.edu class DelayEvent : public Event 1847639Sgblack@eecs.umich.edu { 1857639Sgblack@eecs.umich.edu private: 1867639Sgblack@eecs.umich.edu T *object; 1877639Sgblack@eecs.umich.edu 1887639Sgblack@eecs.umich.edu public: 1897639Sgblack@eecs.umich.edu DelayEvent(Tick when, T *o) 1907639Sgblack@eecs.umich.edu : Event(&mainEventQueue), object(o) 1917639Sgblack@eecs.umich.edu { setFlags(AutoDestroy); schedule(when); } 1927639Sgblack@eecs.umich.edu void process() { (object->*F)(); } 1937639Sgblack@eecs.umich.edu const char *description() { return "delay"; } 1947639Sgblack@eecs.umich.edu }; 1957639Sgblack@eecs.umich.edu 1967639Sgblack@eecs.umich.edu new DelayEvent(when, object); 1977639Sgblack@eecs.umich.edu} 1987639Sgblack@eecs.umich.edu 1997639Sgblack@eecs.umich.edu/* 2007639Sgblack@eecs.umich.edu * Queue of events sorted in time order 2017639Sgblack@eecs.umich.edu */ 2027639Sgblack@eecs.umich.educlass EventQueue : public Serializeable 2037639Sgblack@eecs.umich.edu{ 2047639Sgblack@eecs.umich.edu private: 2057639Sgblack@eecs.umich.edu Event *head; 2067639Sgblack@eecs.umich.edu 2077639Sgblack@eecs.umich.edu void insert(Event *event); 2087639Sgblack@eecs.umich.edu void remove(Event *event); 2097639Sgblack@eecs.umich.edu 2107639Sgblack@eecs.umich.edu public: 2117639Sgblack@eecs.umich.edu 2127639Sgblack@eecs.umich.edu // constructor 2137639Sgblack@eecs.umich.edu EventQueue(const std::string &n) 2147639Sgblack@eecs.umich.edu : Serializeable(n), head(NULL) 2157639Sgblack@eecs.umich.edu {} 2167639Sgblack@eecs.umich.edu 2177639Sgblack@eecs.umich.edu // schedule the given event on this queue 2188588Sgblack@eecs.umich.edu void schedule(Event *ev); 2197639Sgblack@eecs.umich.edu void deschedule(Event *ev); 2207639Sgblack@eecs.umich.edu void reschedule(Event *ev); 2217639Sgblack@eecs.umich.edu 2227639Sgblack@eecs.umich.edu Tick nextTick() { return head->when(); } 2237639Sgblack@eecs.umich.edu void serviceOne(); 2247639Sgblack@eecs.umich.edu 2258588Sgblack@eecs.umich.edu // process all events up to the given timestamp. we inline a 2267639Sgblack@eecs.umich.edu // quick test to see if there are any events to process; if so, 2277639Sgblack@eecs.umich.edu // call the internal out-of-line version to process them all. 2287639Sgblack@eecs.umich.edu void serviceEvents(Tick when) { 2297639Sgblack@eecs.umich.edu while (!empty()) { 2307639Sgblack@eecs.umich.edu if (nextTick() > when) 2317639Sgblack@eecs.umich.edu break; 2327639Sgblack@eecs.umich.edu 2337639Sgblack@eecs.umich.edu assert(head->when() >= when && "event scheduled in the past"); 2347639Sgblack@eecs.umich.edu serviceOne(); 2357639Sgblack@eecs.umich.edu } 2367639Sgblack@eecs.umich.edu } 2377644Sali.saidi@arm.com 2387639Sgblack@eecs.umich.edu // default: process all events up to 'now' (curTick) 2397639Sgblack@eecs.umich.edu void serviceEvents() { serviceEvents(curTick); } 2407639Sgblack@eecs.umich.edu 2417639Sgblack@eecs.umich.edu // return true if no events are queued 2427639Sgblack@eecs.umich.edu bool empty() { return head == NULL; } 2437639Sgblack@eecs.umich.edu 2447639Sgblack@eecs.umich.edu void dump(); 2457639Sgblack@eecs.umich.edu 2467644Sali.saidi@arm.com Tick nextEventTime() { return empty() ? curTick : head->when(); } 2477639Sgblack@eecs.umich.edu 2487639Sgblack@eecs.umich.edu virtual void nameChildren(); 2497639Sgblack@eecs.umich.edu virtual void serialize(); 2507639Sgblack@eecs.umich.edu}; 2517639Sgblack@eecs.umich.edu 2527639Sgblack@eecs.umich.edu 2537639Sgblack@eecs.umich.edu////////////////////// 2547639Sgblack@eecs.umich.edu// 2557639Sgblack@eecs.umich.edu// inline functions 2567639Sgblack@eecs.umich.edu// 2577639Sgblack@eecs.umich.edu// can't put these inside declaration due to circular dependence 2587639Sgblack@eecs.umich.edu// between Event and EventQueue classes. 2597639Sgblack@eecs.umich.edu// 2607639Sgblack@eecs.umich.edu////////////////////// 2617639Sgblack@eecs.umich.edu 2627639Sgblack@eecs.umich.edu// schedule at specified time (place on event queue specified via 2637639Sgblack@eecs.umich.edu// constructor) 2647639Sgblack@eecs.umich.eduinline void 2657639Sgblack@eecs.umich.eduEvent::schedule(Tick t) 2667639Sgblack@eecs.umich.edu{ 2677639Sgblack@eecs.umich.edu assert(!scheduled()); 2687639Sgblack@eecs.umich.edu setFlags(Scheduled); 2697639Sgblack@eecs.umich.edu#if TRACING_ON 2707639Sgblack@eecs.umich.edu when_scheduled = curTick; 2717639Sgblack@eecs.umich.edu#endif 2727639Sgblack@eecs.umich.edu _when = t; 2737639Sgblack@eecs.umich.edu queue->schedule(this); 2747639Sgblack@eecs.umich.edu} 2757639Sgblack@eecs.umich.edu 2767639Sgblack@eecs.umich.eduinline void 2777639Sgblack@eecs.umich.eduEvent::schedule(Tick t, int p) 2787639Sgblack@eecs.umich.edu{ 2797639Sgblack@eecs.umich.edu _priority = p; 2807639Sgblack@eecs.umich.edu schedule(t); 2817639Sgblack@eecs.umich.edu} 2827639Sgblack@eecs.umich.edu 2837639Sgblack@eecs.umich.eduinline void 2847639Sgblack@eecs.umich.eduEvent::deschedule() 2857639Sgblack@eecs.umich.edu{ 2867639Sgblack@eecs.umich.edu assert(scheduled()); 2877639Sgblack@eecs.umich.edu 2887639Sgblack@eecs.umich.edu clearFlags(Squashed); 2897639Sgblack@eecs.umich.edu clearFlags(Scheduled); 2907639Sgblack@eecs.umich.edu queue->deschedule(this); 2917639Sgblack@eecs.umich.edu} 2927639Sgblack@eecs.umich.edu 2937639Sgblack@eecs.umich.eduinline void 2947639Sgblack@eecs.umich.eduEvent::reschedule(Tick t) 2957639Sgblack@eecs.umich.edu{ 2967639Sgblack@eecs.umich.edu assert(scheduled()); 2978588Sgblack@eecs.umich.edu clearFlags(Squashed); 2988588Sgblack@eecs.umich.edu 2997639Sgblack@eecs.umich.edu#if TRACING_ON 3007639Sgblack@eecs.umich.edu when_scheduled = curTick; 3018588Sgblack@eecs.umich.edu#endif 3028588Sgblack@eecs.umich.edu _when = t; 3037639Sgblack@eecs.umich.edu queue->reschedule(this); 3047639Sgblack@eecs.umich.edu} 3057639Sgblack@eecs.umich.edu 3067639Sgblack@eecs.umich.eduinline void 3077639Sgblack@eecs.umich.eduEvent::reschedule(Tick t, int p) 3087639Sgblack@eecs.umich.edu{ 3097639Sgblack@eecs.umich.edu _priority = p; 3107639Sgblack@eecs.umich.edu reschedule(t); 3117639Sgblack@eecs.umich.edu} 3127639Sgblack@eecs.umich.edu 3137639Sgblack@eecs.umich.eduinline void 3147639Sgblack@eecs.umich.eduEventQueue::schedule(Event *event) 3157639Sgblack@eecs.umich.edu{ 3167639Sgblack@eecs.umich.edu insert(event); 3177639Sgblack@eecs.umich.edu if (DTRACE(Event)) 3187639Sgblack@eecs.umich.edu event->trace("scheduled"); 3197639Sgblack@eecs.umich.edu} 3207639Sgblack@eecs.umich.edu 3217639Sgblack@eecs.umich.eduinline void 3227639Sgblack@eecs.umich.eduEventQueue::deschedule(Event *event) 3237639Sgblack@eecs.umich.edu{ 3247639Sgblack@eecs.umich.edu remove(event); 3257639Sgblack@eecs.umich.edu if (DTRACE(Event)) 3267639Sgblack@eecs.umich.edu event->trace("descheduled"); 3277639Sgblack@eecs.umich.edu} 3287639Sgblack@eecs.umich.edu 3297639Sgblack@eecs.umich.eduinline void 3307639Sgblack@eecs.umich.eduEventQueue::reschedule(Event *event) 3317639Sgblack@eecs.umich.edu{ 3327639Sgblack@eecs.umich.edu remove(event); 3337639Sgblack@eecs.umich.edu insert(event); 3347639Sgblack@eecs.umich.edu if (DTRACE(Event)) 3357639Sgblack@eecs.umich.edu event->trace("rescheduled"); 3367639Sgblack@eecs.umich.edu} 3377639Sgblack@eecs.umich.edu 3387639Sgblack@eecs.umich.edu 3397639Sgblack@eecs.umich.edu////////////////////// 3407639Sgblack@eecs.umich.edu// 3417639Sgblack@eecs.umich.edu// Main Event Queue 3427639Sgblack@eecs.umich.edu// 3438588Sgblack@eecs.umich.edu// Events on this queue are processed at the *beginning* of each 3448588Sgblack@eecs.umich.edu// cycle, before the pipeline simulation is performed. 3457639Sgblack@eecs.umich.edu// 3467639Sgblack@eecs.umich.edu// defined in eventq.cc 3478588Sgblack@eecs.umich.edu// 3488588Sgblack@eecs.umich.edu////////////////////// 3497639Sgblack@eecs.umich.eduextern EventQueue mainEventQueue; 3507639Sgblack@eecs.umich.edu 3517639Sgblack@eecs.umich.edu#endif // __EVENTQ_HH__ 3527639Sgblack@eecs.umich.edu