eventq.hh revision 224
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. 272SN/A */ 282SN/A 292439SN/A/* @file 30146SN/A * EventQueue interfaces 31146SN/A */ 32146SN/A 33146SN/A#ifndef __EVENTQ_HH__ 34146SN/A#define __EVENTQ_HH__ 35146SN/A 361717SN/A#include <assert.h> 37146SN/A 381717SN/A#include <algorithm> 392190SN/A#include <map> 40146SN/A#include <string> 41146SN/A#include <vector> 421977SN/A 431717SN/A#include "sim/host.hh" // for Tick 442623SN/A 451717SN/A#include "base/fast_alloc.hh" 46146SN/A#include "sim/serialize.hh" 471917SN/A#include "base/trace.hh" 482592SN/A 492036SN/Aclass EventQueue; // forward declaration 50146SN/A 51146SN/A/* 5256SN/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. 55695SN/A */ 562SN/Aclass Event : public Serializeable, public FastAlloc 571858SN/A{ 5856SN/A friend class EventQueue; 59146SN/A 602171SN/A private: 612170SN/A /// queue to which this event belongs (though it may or may not be 622170SN/A /// scheduled on this queue yet) 63146SN/A EventQueue *queue; 642462SN/A 65146SN/A Event *next; 662SN/A 672SN/A Tick _when; //!< timestamp when event should be processed 682449SN/A int _priority; //!< event priority 691355SN/A char _flags; 702623SN/A 712623SN/A protected: 72224SN/A enum Flags { 731858SN/A None = 0x0, 742518SN/A Squashed = 0x1, 752420SN/A Scheduled = 0x2, 762519SN/A AutoDelete = 0x4 772520SN/A }; 782420SN/A 792SN/A bool getFlags(Flags f) const { return (_flags & f) == f; } 802190SN/A void setFlags(Flags f) { _flags |= f; } 812SN/A void clearFlags(Flags f) { _flags &= ~f; } 822SN/A 83334SN/A protected: 84140SN/A EventQueue *theQueue() const { return queue; } 85334SN/A 862SN/A#if TRACING_ON 872SN/A Tick when_created; //!< Keep track of creation time For debugging 882SN/A Tick when_scheduled; //!< Keep track of creation time For debugging 892190SN/A 902SN/A virtual void trace(const char *action); //!< trace event activity 912SN/A#else 922623SN/A void trace(const char *) {} 932SN/A#endif 942SN/A 952SN/A unsigned annotated_value; 96180SN/A 972623SN/A public: 98393SN/A 99393SN/A static const std::string defaultName; 100393SN/A 101393SN/A /* 102384SN/A * Event constructor 103384SN/A * @param queue that the event gets scheduled on 104393SN/A */ 1052623SN/A Event(EventQueue *q, int p = 0) 106393SN/A : Serializeable(defaultName), queue(q), next(NULL), 107393SN/A _priority(p), _flags(None), 108393SN/A#if TRACING_ON 109393SN/A when_created(curTick), when_scheduled(0), 110384SN/A#endif 111189SN/A annotated_value(0) 112189SN/A { 1132623SN/A } 1142SN/A 115729SN/A /* 116334SN/A * Event constructor 1172SN/A * @param queue that the event gets scheduled on 1182SN/A */ 1192SN/A Event(EventQueue *q, std::string _name, int p = 0) 1202SN/A : Serializeable(_name), queue(q), next(NULL), 1212SN/A _priority(p), _flags(None), 1222SN/A#if TRACING_ON 1232SN/A when_created(curTick), when_scheduled(0), 1242SN/A#endif 1252SN/A annotated_value(0) 1262SN/A { 1272SN/A } 1282SN/A 1291001SN/A ~Event() {} 1301001SN/A 1311001SN/A /// Determine if the current event is scheduled 1321001SN/A bool scheduled() const { return getFlags(Scheduled); } 1331001SN/A 1342SN/A /// Schedule the event with the current priority or default priority 1352SN/A void schedule(Tick t); 1362SN/A 1372SN/A /// Schedule the event with a specific priority 1382SN/A void schedule(Tick t, int priority); 1392SN/A 1402SN/A /// Reschedule the event with the current priority 1412SN/A void reschedule(Tick t); 1422SN/A 1432SN/A /// Reschedule the event with a specific priority 1442SN/A void reschedule(Tick t, int priority); 1452SN/A 1462SN/A /// Remove the event from the current schedule 1472SN/A void deschedule(); 1482SN/A 1492SN/A /// Return a C string describing the event. This string should 1502SN/A /// *not* be dynamically allocated; just a const char array 1512390SN/A /// describing the event class. 1522390SN/A virtual const char *description(); 1532390SN/A 1542390SN/A /// Dump the current event data 1552390SN/A void dump(); 1562390SN/A 1572390SN/A /* 1582390SN/A * This member function is invoked when the event is processed 1592390SN/A * (occurs). There is no default implementation; each subclass 1602390SN/A * must provide its own implementation. The event is not 1612390SN/A * automatically deleted after it is processed (to allow for 1622390SN/A * statically allocated event objects). 163385SN/A * 1642SN/A * If the AutoDestroy flag is set, the object is deleted once it 1652SN/A * is processed. 1662SN/A */ 1672623SN/A virtual void process() = 0; 168334SN/A 169334SN/A void annotate(unsigned value) { annotated_value = value; }; 1702623SN/A unsigned annotation() { return annotated_value; } 171334SN/A 172334SN/A /// Squash the current event 173334SN/A void squash() { setFlags(Squashed); } 1742623SN/A 1752SN/A /// Check whether the event is squashed 176921SN/A bool squashed() { return getFlags(Squashed); } 177224SN/A 178237SN/A /// Get the time that the event is scheduled 1792190SN/A Tick when() const { return _when; } 1802SN/A 1812SN/A /// Get the event priority 1822SN/A int priority() const { return _priority; } 1832623SN/A 1842SN/A struct priority_compare : 185921SN/A public std::binary_function<Event *, Event *, bool> 186224SN/A { 1872190SN/A bool operator()(const Event *l, const Event *r) const { 1882SN/A return l->when() >= r->when() || l->priority() >= r->priority(); 1892SN/A } 1902SN/A }; 1912SN/A 1922SN/A virtual void serialize(std::ostream &os); 1932SN/A virtual void unserialize(const IniFile *db, const std::string §ion); 1942SN/A}; 195595SN/A 1962623SN/Atemplate <class T, void (T::* F)()> 197595SN/Avoid 1982390SN/ADelayFunction(Tick when, T *object) 1991080SN/A{ 2001080SN/A class DelayEvent : public Event 2011080SN/A { 2021080SN/A private: 2031080SN/A T *object; 2041080SN/A 2051080SN/A public: 2061121SN/A DelayEvent(Tick when, T *o) 2072107SN/A : Event(&mainEventQueue), object(o) 2081089SN/A { setFlags(AutoDestroy); schedule(when); } 2091089SN/A void process() { (object->*F)(); } 2101080SN/A const char *description() { return "delay"; } 2111080SN/A }; 2121080SN/A 2131080SN/A new DelayEvent(when, object); 214595SN/A} 2152623SN/A 2162623SN/A/* 217595SN/A * Queue of events sorted in time order 2182090SN/A */ 2192190SN/Aclass EventQueue : public Serializeable 2202190SN/A{ 221595SN/A private: 2222205SN/A Event *head; 2232205SN/A 2242190SN/A void insert(Event *event); 2252190SN/A void remove(Event *event); 226595SN/A 227595SN/A public: 2282390SN/A 2292423SN/A // constructor 2302390SN/A EventQueue(const std::string &n) 231595SN/A : Serializeable(n), head(NULL) 232595SN/A {} 233595SN/A 2342623SN/A // schedule the given event on this queue 235595SN/A void schedule(Event *ev); 2362390SN/A void deschedule(Event *ev); 2371080SN/A void reschedule(Event *ev); 238595SN/A 2391080SN/A Tick nextTick() { return head->when(); } 2401080SN/A void serviceOne(); 241595SN/A 2422190SN/A // process all events up to the given timestamp. we inline a 2431080SN/A // quick test to see if there are any events to process; if so, 2441080SN/A // call the internal out-of-line version to process them all. 2451080SN/A void serviceEvents(Tick when) { 2461121SN/A while (!empty()) { 2472107SN/A if (nextTick() > when) 2481089SN/A break; 2491080SN/A 2501089SN/A assert(head->when() >= when && "event scheduled in the past"); 2511080SN/A serviceOne(); 2521080SN/A } 2531080SN/A } 254595SN/A 2552422SN/A // default: process all events up to 'now' (curTick) 2561080SN/A void serviceEvents() { serviceEvents(curTick); } 2572090SN/A 2581080SN/A // return true if no events are queued 259595SN/A bool empty() { return head == NULL; } 2602190SN/A 2612190SN/A void dump(); 262595SN/A 2632190SN/A Tick nextEventTime() { return empty() ? curTick : head->when(); } 2641098SN/A 2651098SN/A virtual void nameChildren(); 2661098SN/A virtual void serialize(std::ostream &os); 2672190SN/A}; 2681098SN/A 2691098SN/A 2701098SN/A////////////////////// 2712012SN/A// 2721098SN/A// inline functions 2731098SN/A// 274595SN/A// can't put these inside declaration due to circular dependence 2752205SN/A// between Event and EventQueue classes. 2762205SN/A// 2772205SN/A////////////////////// 278595SN/A 2792390SN/A// schedule at specified time (place on event queue specified via 2802420SN/A// constructor) 2812423SN/Ainline void 2822390SN/AEvent::schedule(Tick t) 283595SN/A{ 284595SN/A assert(!scheduled()); 2851858SN/A setFlags(Scheduled); 2862SN/A#if TRACING_ON 2872623SN/A when_scheduled = curTick; 2882SN/A#endif 2892190SN/A _when = t; 2902SN/A queue->schedule(this); 2912SN/A} 2922SN/A 2931858SN/Ainline void 2942SN/AEvent::schedule(Tick t, int p) 2952623SN/A{ 2962SN/A _priority = p; 2972SN/A schedule(t); 2982SN/A} 2992190SN/A 3002SN/Ainline void 3012190SN/AEvent::deschedule() 3022SN/A{ 3032SN/A assert(scheduled()); 3042SN/A 3052SN/A clearFlags(Squashed); 3062SN/A clearFlags(Scheduled); 3072623SN/A queue->deschedule(this); 3082SN/A} 3091858SN/A 3102626SN/Ainline void 3112SN/AEvent::reschedule(Tick t) 3122SN/A{ 3131133SN/A assert(scheduled()); 3142SN/A clearFlags(Squashed); 3152190SN/A 3162107SN/A#if TRACING_ON 3172107SN/A when_scheduled = curTick; 3182190SN/A#endif 3192SN/A _when = t; 3202107SN/A queue->reschedule(this); 3212SN/A} 3222SN/A 3232SN/Ainline void 3242SN/AEvent::reschedule(Tick t, int p) 3252SN/A{ 3262190SN/A _priority = p; 3272107SN/A reschedule(t); 3282107SN/A} 3292SN/A 3302SN/Ainline void 3312SN/AEventQueue::schedule(Event *event) 3322SN/A{ 3332SN/A insert(event); 3342SN/A if (DTRACE(Event)) 3352SN/A event->trace("scheduled"); 3362190SN/A} 3372SN/A 3382SN/Ainline void 3392190SN/AEventQueue::deschedule(Event *event) 3402190SN/A{ 3412190SN/A remove(event); 3422234SN/A if (DTRACE(Event)) 3432234SN/A event->trace("descheduled"); 3442SN/A} 3452SN/A 3462190SN/Ainline void 3472SN/AEventQueue::reschedule(Event *event) 3482SN/A{ 3492SN/A remove(event); 3502623SN/A insert(event); 3512SN/A if (DTRACE(Event)) 3522623SN/A event->trace("rescheduled"); 3532623SN/A} 3542662Sstever@eecs.umich.edu 3552623SN/A 3562623SN/A////////////////////// 3572623SN/A// 3582623SN/A// Main Event Queue 3592623SN/A// 3602662Sstever@eecs.umich.edu// Events on this queue are processed at the *beginning* of each 3612662Sstever@eecs.umich.edu// cycle, before the pipeline simulation is performed. 3622623SN/A// 3632662Sstever@eecs.umich.edu// defined in eventq.cc 3642623SN/A// 3652662Sstever@eecs.umich.edu////////////////////// 3662623SN/Aextern EventQueue mainEventQueue; 3672623SN/A 3682662Sstever@eecs.umich.edu#endif // __EVENTQ_HH__ 3692623SN/A