eventq.hh revision 237
12SN/A/* 21762SN/A * Copyright (c) 2003 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292SN/A/* @file 302SN/A * EventQueue interfaces 312439SN/A */ 322984Sgblack@eecs.umich.edu 33146SN/A#ifndef __EVENTQ_HH__ 34146SN/A#define __EVENTQ_HH__ 35146SN/A 36146SN/A#include <assert.h> 37146SN/A 38146SN/A#include <algorithm> 391717SN/A#include <map> 40146SN/A#include <string> 411717SN/A#include <vector> 42146SN/A 431977SN/A#include "sim/host.hh" // for Tick 442623SN/A 452683Sktlim@umich.edu#include "base/fast_alloc.hh" 461717SN/A#include "sim/serialize.hh" 47146SN/A#include "base/trace.hh" 482683Sktlim@umich.edu 493348Sbinkertn@umich.educlass EventQueue; // forward declaration 502683Sktlim@umich.edu 512036SN/A/* 52146SN/A * An item on an event queue. The action caused by a given 5356SN/A * event is specified by deriving a subclass and overriding the 5456SN/A * process() member function. 5556SN/A */ 56695SN/Aclass Event : public Serializeable, public FastAlloc 572901Ssaidi@eecs.umich.edu{ 582SN/A friend class EventQueue; 591858SN/A 603565Sgblack@eecs.umich.edu private: 613565Sgblack@eecs.umich.edu /// queue to which this event belongs (though it may or may not be 622171SN/A /// scheduled on this queue yet) 632170SN/A EventQueue *queue; 643562Sgblack@eecs.umich.edu 65146SN/A Event *next; 662462SN/A 67146SN/A Tick _when; //!< timestamp when event should be processed 682SN/A int _priority; //!< event priority 692SN/A char _flags; 702449SN/A 711355SN/A protected: 722623SN/A enum Flags { 733402Sktlim@umich.edu None = 0x0, 74224SN/A Squashed = 0x1, 751858SN/A Scheduled = 0x2, 762683Sktlim@umich.edu AutoDelete = 0x4, 772420SN/A AutoSerialize = 0x8 782683Sktlim@umich.edu }; 793402Sktlim@umich.edu 802420SN/A bool getFlags(Flags f) const { return (_flags & f) == f; } 812SN/A void setFlags(Flags f) { _flags |= f; } 822683Sktlim@umich.edu void clearFlags(Flags f) { _flags &= ~f; } 832672Sktlim@umich.edu 842683Sktlim@umich.edu protected: 852SN/A EventQueue *theQueue() const { return queue; } 862SN/A 87334SN/A#if TRACING_ON 88140SN/A Tick when_created; //!< Keep track of creation time For debugging 89334SN/A Tick when_scheduled; //!< Keep track of creation time For debugging 902SN/A 912SN/A virtual void trace(const char *action); //!< trace event activity 922SN/A#else 932680Sktlim@umich.edu void trace(const char *) {} 942SN/A#endif 952SN/A 962623SN/A unsigned annotated_value; 972SN/A 982SN/A public: 992SN/A 100180SN/A static const std::string defaultName; 1012623SN/A 102393SN/A /* 103393SN/A * Event constructor 104393SN/A * @param queue that the event gets scheduled on 105393SN/A */ 106384SN/A Event(EventQueue *q, int p = 0) 107384SN/A : Serializeable(defaultName), queue(q), next(NULL), 108393SN/A _priority(p), _flags(None), 1092623SN/A#if TRACING_ON 110393SN/A when_created(curTick), when_scheduled(0), 111393SN/A#endif 112393SN/A annotated_value(0) 113393SN/A { 114384SN/A } 115189SN/A 116189SN/A /* 1172623SN/A * Event constructor 1182SN/A * @param queue that the event gets scheduled on 119729SN/A */ 120334SN/A Event(EventQueue *q, std::string _name, int p = 0) 1212SN/A : Serializeable(_name), queue(q), next(NULL), 1222SN/A _priority(p), _flags(None), 1232SN/A#if TRACING_ON 1242SN/A when_created(curTick), when_scheduled(0), 1252SN/A#endif 1262SN/A annotated_value(0) 1272SN/A { 1282SN/A } 1292SN/A 1302SN/A ~Event() {} 1312SN/A 1322SN/A /// Determine if the current event is scheduled 1331001SN/A bool scheduled() const { return getFlags(Scheduled); } 1341001SN/A 1351001SN/A /// Schedule the event with the current priority or default priority 1361001SN/A void schedule(Tick t); 1371001SN/A 1382SN/A /// Schedule the event with a specific priority 1392SN/A void schedule(Tick t, int priority); 1402SN/A 1412SN/A /// Reschedule the event with the current priority 1422SN/A void reschedule(Tick t); 1432SN/A 1442SN/A /// Reschedule the event with a specific priority 1452SN/A void reschedule(Tick t, int priority); 1462SN/A 1472SN/A /// Remove the event from the current schedule 1482SN/A void deschedule(); 1492SN/A 1502SN/A /// Return a C string describing the event. This string should 1512SN/A /// *not* be dynamically allocated; just a const char array 1522SN/A /// describing the event class. 1532SN/A virtual const char *description(); 1542SN/A 1552390SN/A /// Dump the current event data 1562390SN/A void dump(); 1572390SN/A 1582390SN/A /* 1592390SN/A * This member function is invoked when the event is processed 1602390SN/A * (occurs). There is no default implementation; each subclass 1612390SN/A * must provide its own implementation. The event is not 1622390SN/A * automatically deleted after it is processed (to allow for 1632390SN/A * statically allocated event objects). 1642390SN/A * 1652390SN/A * If the AutoDestroy flag is set, the object is deleted once it 1662390SN/A * is processed. 167385SN/A */ 1682SN/A virtual void process() = 0; 1692SN/A 1702SN/A void annotate(unsigned value) { annotated_value = value; }; 1712623SN/A unsigned annotation() { return annotated_value; } 172334SN/A 1732361SN/A /// Squash the current event 1742623SN/A void squash() { setFlags(Squashed); } 175334SN/A 176334SN/A /// Check whether the event is squashed 177334SN/A bool squashed() { return getFlags(Squashed); } 1782623SN/A 1792SN/A /// Get the time that the event is scheduled 180921SN/A Tick when() const { return _when; } 1812915Sktlim@umich.edu 1822915Sktlim@umich.edu /// Get the event priority 1832683Sktlim@umich.edu int priority() const { return _priority; } 1842SN/A 1852SN/A struct priority_compare : 1862SN/A public std::binary_function<Event *, Event *, bool> 1872623SN/A { 1882SN/A bool operator()(const Event *l, const Event *r) const { 189921SN/A return l->when() >= r->when() || l->priority() >= r->priority(); 1902915Sktlim@umich.edu } 1912915Sktlim@umich.edu }; 1922SN/A 1932SN/A virtual void serialize(std::ostream &os); 1942SN/A virtual void unserialize(Checkpoint *cp, const std::string §ion); 1952SN/A}; 1962SN/A 1972SN/Atemplate <class T, void (T::* F)()> 1982SN/Avoid 199595SN/ADelayFunction(Tick when, T *object) 2002623SN/A{ 201595SN/A class DelayEvent : public Event 2022390SN/A { 2031080SN/A private: 2041080SN/A T *object; 2051080SN/A 2061080SN/A public: 2071080SN/A DelayEvent(Tick when, T *o) 2081080SN/A : Event(&mainEventQueue), object(o) 2091080SN/A { setFlags(AutoDestroy); schedule(when); } 2101121SN/A void process() { (object->*F)(); } 2112107SN/A const char *description() { return "delay"; } 2121089SN/A }; 2131089SN/A 2141080SN/A new DelayEvent(when, object); 2151080SN/A} 2161080SN/A 2171080SN/A/* 218595SN/A * Queue of events sorted in time order 2192623SN/A */ 2202683Sktlim@umich.educlass EventQueue : public Serializeable 221595SN/A{ 2222090SN/A private: 2232683Sktlim@umich.edu Event *head; 2242683Sktlim@umich.edu 225595SN/A // only used to hold value between nameChildren() and serialize() 2262205SN/A int numAutoSerializeEvents; 2272205SN/A 2282683Sktlim@umich.edu void insert(Event *event); 2292683Sktlim@umich.edu void remove(Event *event); 230595SN/A 231595SN/A public: 2322390SN/A 2332423SN/A // constructor 2342390SN/A EventQueue(const std::string &n) 235595SN/A : Serializeable(n), head(NULL), numAutoSerializeEvents(-1) 236595SN/A {} 237595SN/A 2382623SN/A // schedule the given event on this queue 239595SN/A void schedule(Event *ev); 2402390SN/A void deschedule(Event *ev); 2411080SN/A void reschedule(Event *ev); 242595SN/A 2431080SN/A Tick nextTick() { return head->when(); } 2441080SN/A void serviceOne(); 245595SN/A 2462683Sktlim@umich.edu // process all events up to the given timestamp. we inline a 2471080SN/A // quick test to see if there are any events to process; if so, 2481080SN/A // call the internal out-of-line version to process them all. 2491080SN/A void serviceEvents(Tick when) { 2501121SN/A while (!empty()) { 2512107SN/A if (nextTick() > when) 2521089SN/A break; 2531080SN/A 2541089SN/A assert(head->when() >= when && "event scheduled in the past"); 2551080SN/A serviceOne(); 2561080SN/A } 2571080SN/A } 258595SN/A 2592683Sktlim@umich.edu // default: process all events up to 'now' (curTick) 2601080SN/A void serviceEvents() { serviceEvents(curTick); } 2612090SN/A 2621080SN/A // return true if no events are queued 263595SN/A bool empty() { return head == NULL; } 2642683Sktlim@umich.edu 2652683Sktlim@umich.edu void dump(); 266595SN/A 2672683Sktlim@umich.edu Tick nextEventTime() { return empty() ? curTick : head->when(); } 2681098SN/A 2691098SN/A virtual void nameChildren(); 2701098SN/A virtual void serialize(std::ostream &os); 2712683Sktlim@umich.edu virtual void unserialize(Checkpoint *cp, const std::string §ion); 2721098SN/A}; 2731098SN/A 2741098SN/A 2752012SN/A////////////////////// 2761098SN/A// 2771098SN/A// inline functions 278595SN/A// 2792205SN/A// can't put these inside declaration due to circular dependence 2802205SN/A// between Event and EventQueue classes. 2812205SN/A// 282595SN/A////////////////////// 2832390SN/A 2842420SN/A// schedule at specified time (place on event queue specified via 2852423SN/A// constructor) 2862390SN/Ainline void 287595SN/AEvent::schedule(Tick t) 288595SN/A{ 2891858SN/A assert(!scheduled()); 2902SN/A setFlags(Scheduled); 2912623SN/A#if TRACING_ON 2922SN/A when_scheduled = curTick; 2932680Sktlim@umich.edu#endif 2942SN/A _when = t; 2952SN/A queue->schedule(this); 2962SN/A} 2971858SN/A 2982SN/Ainline void 2992623SN/AEvent::schedule(Tick t, int p) 3002SN/A{ 3012SN/A _priority = p; 3022SN/A schedule(t); 3032683Sktlim@umich.edu} 3042SN/A 3052683Sktlim@umich.eduinline void 3062SN/AEvent::deschedule() 3072SN/A{ 3082SN/A assert(scheduled()); 3092SN/A 3102SN/A clearFlags(Squashed); 3112623SN/A clearFlags(Scheduled); 3122SN/A queue->deschedule(this); 3131858SN/A} 3143521Sgblack@eecs.umich.edu 3153520Sgblack@eecs.umich.eduinline void 3162SN/AEvent::reschedule(Tick t) 3173520Sgblack@eecs.umich.edu{ 3183521Sgblack@eecs.umich.edu assert(scheduled()); 3193520Sgblack@eecs.umich.edu clearFlags(Squashed); 3202SN/A 3212SN/A#if TRACING_ON 3222SN/A when_scheduled = curTick; 3232623SN/A#endif 3242SN/A _when = t; 3252623SN/A queue->reschedule(this); 3262623SN/A} 3272662Sstever@eecs.umich.edu 3282623SN/Ainline void 3292623SN/AEvent::reschedule(Tick t, int p) 3303093Sksewell@umich.edu{ 3313093Sksewell@umich.edu _priority = p; 3323093Sksewell@umich.edu reschedule(t); 3333093Sksewell@umich.edu} 3342741Sksewell@umich.edu 3352741Sksewell@umich.eduinline void 3362741Sksewell@umich.eduEventQueue::schedule(Event *event) 3372623SN/A{ 3382683Sktlim@umich.edu insert(event); 3392683Sktlim@umich.edu if (DTRACE(Event)) 3402683Sktlim@umich.edu event->trace("scheduled"); 3412623SN/A} 3422683Sktlim@umich.edu 3432623SN/Ainline void 3442623SN/AEventQueue::deschedule(Event *event) 3452623SN/A{ 3462623SN/A remove(event); 3472623SN/A if (DTRACE(Event)) 3482623SN/A event->trace("descheduled"); 3492623SN/A} 3502623SN/A 3512SN/Ainline void 3522683Sktlim@umich.eduEventQueue::reschedule(Event *event) 3532427SN/A{ 3542683Sktlim@umich.edu remove(event); 3552427SN/A insert(event); 3562SN/A if (DTRACE(Event)) 3572623SN/A event->trace("rescheduled"); 3582623SN/A} 3592623SN/A 3602SN/A 3612683Sktlim@umich.edu////////////////////// 3622SN/A// 3632623SN/A// Main Event Queue 3642623SN/A// 3652SN/A// Events on this queue are processed at the *beginning* of each 3662623SN/A// cycle, before the pipeline simulation is performed. 3672623SN/A// 3683276Sgblack@eecs.umich.edu// defined in eventq.cc 3693276Sgblack@eecs.umich.edu// 3703484Sktlim@umich.edu////////////////////// 3713484Sktlim@umich.eduextern EventQueue mainEventQueue; 3723484Sktlim@umich.edu 3733276Sgblack@eecs.umich.edu#endif // __EVENTQ_HH__ 3743521Sgblack@eecs.umich.edu