eventq.hh revision 6982
12SN/A/* 21762SN/A * Copyright (c) 2000-2005 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 * Authors: Steve Reinhardt 292665Ssaidi@eecs.umich.edu * Nathan Binkert 302SN/A */ 312SN/A 322SN/A/* @file 332SN/A * EventQueue interfaces 342SN/A */ 352SN/A 361354SN/A#ifndef __SIM_EVENTQ_HH__ 371354SN/A#define __SIM_EVENTQ_HH__ 382SN/A 392SN/A#include <algorithm> 405501Snate@binkert.org#include <cassert> 415546Snate@binkert.org#include <climits> 422SN/A#include <map> 432SN/A#include <string> 442SN/A#include <vector> 452SN/A 4656SN/A#include "base/fast_alloc.hh" 475769Snate@binkert.org#include "base/flags.hh" 482361SN/A#include "base/misc.hh" 491354SN/A#include "base/trace.hh" 506216Snate@binkert.org#include "base/types.hh" 5156SN/A#include "sim/serialize.hh" 522SN/A 535543Ssaidi@eecs.umich.educlass EventQueue; // forward declaration 542SN/A 551354SN/Aextern EventQueue mainEventQueue; 561354SN/A 572SN/A/* 582SN/A * An item on an event queue. The action caused by a given 592SN/A * event is specified by deriving a subclass and overriding the 602SN/A * process() member function. 615501Snate@binkert.org * 625501Snate@binkert.org * Caution, the order of members is chosen to maximize data packing. 632SN/A */ 64395SN/Aclass Event : public Serializable, public FastAlloc 652SN/A{ 662SN/A friend class EventQueue; 672SN/A 685769Snate@binkert.org protected: 695769Snate@binkert.org typedef short FlagsType; 705769Snate@binkert.org typedef ::Flags<FlagsType> Flags; 715769Snate@binkert.org 725769Snate@binkert.org static const FlagsType PublicRead = 0x003f; 735769Snate@binkert.org static const FlagsType PublicWrite = 0x001d; 745769Snate@binkert.org static const FlagsType Squashed = 0x0001; 755769Snate@binkert.org static const FlagsType Scheduled = 0x0002; 765769Snate@binkert.org static const FlagsType AutoDelete = 0x0004; 775769Snate@binkert.org static const FlagsType AutoSerialize = 0x0008; 785769Snate@binkert.org static const FlagsType IsExitEvent = 0x0010; 795769Snate@binkert.org static const FlagsType IsMainQueue = 0x0020; 805774Snate@binkert.org#ifdef EVENTQ_DEBUG 815774Snate@binkert.org static const FlagsType Initialized = 0xf000; 825774Snate@binkert.org#endif 835769Snate@binkert.org 842SN/A private: 855502Snate@binkert.org // The event queue is now a linked list of linked lists. The 865502Snate@binkert.org // 'nextBin' pointer is to find the bin, where a bin is defined as 875502Snate@binkert.org // when+priority. All events in the same bin will be stored in a 885503Snate@binkert.org // second linked list (a stack) maintained by the 'nextInBin' 895503Snate@binkert.org // pointer. The list will be accessed in LIFO order. The end 905502Snate@binkert.org // result is that the insert/removal in 'nextBin' is 915502Snate@binkert.org // linear/constant, and the lookup/removal in 'nextInBin' is 925502Snate@binkert.org // constant/constant. Hopefully this is a significant improvement 935502Snate@binkert.org // over the current fully linear insertion. 945502Snate@binkert.org Event *nextBin; 955502Snate@binkert.org Event *nextInBin; 965502Snate@binkert.org 975602Snate@binkert.org static Event *insertBefore(Event *event, Event *curr); 985602Snate@binkert.org static Event *removeItem(Event *event, Event *last); 995501Snate@binkert.org 1005543Ssaidi@eecs.umich.edu Tick _when; //!< timestamp when event should be processed 1015543Ssaidi@eecs.umich.edu short _priority; //!< event priority 1025769Snate@binkert.org Flags flags; 1034016Sstever@eecs.umich.edu 1044016Sstever@eecs.umich.edu#ifndef NDEBUG 1054016Sstever@eecs.umich.edu /// Global counter to generate unique IDs for Event instances 1064016Sstever@eecs.umich.edu static Counter instanceCounter; 1074016Sstever@eecs.umich.edu 1084016Sstever@eecs.umich.edu /// This event's unique ID. We can also use pointer values for 1094016Sstever@eecs.umich.edu /// this but they're not consistent across runs making debugging 1104016Sstever@eecs.umich.edu /// more difficult. Thus we use a global counter value when 1114016Sstever@eecs.umich.edu /// debugging. 1125501Snate@binkert.org Counter instance; 1135605Snate@binkert.org 1145605Snate@binkert.org /// queue to which this event belongs (though it may or may not be 1155605Snate@binkert.org /// scheduled on this queue yet) 1165605Snate@binkert.org EventQueue *queue; 1175501Snate@binkert.org#endif 1184016Sstever@eecs.umich.edu 1195577SSteve.Reinhardt@amd.com#ifdef EVENTQ_DEBUG 1205501Snate@binkert.org Tick whenCreated; //!< time created 1215501Snate@binkert.org Tick whenScheduled; //!< time scheduled 1225501Snate@binkert.org#endif 1235502Snate@binkert.org 1245502Snate@binkert.org void 1255605Snate@binkert.org setWhen(Tick when, EventQueue *q) 1265502Snate@binkert.org { 1275502Snate@binkert.org _when = when; 1285605Snate@binkert.org#ifndef NDEBUG 1295605Snate@binkert.org queue = q; 1305605Snate@binkert.org#endif 1315577SSteve.Reinhardt@amd.com#ifdef EVENTQ_DEBUG 1325502Snate@binkert.org whenScheduled = curTick; 1335502Snate@binkert.org#endif 1345502Snate@binkert.org } 1355502Snate@binkert.org 1362SN/A protected: 1375769Snate@binkert.org /// Accessor for flags. 1385769Snate@binkert.org Flags 1395769Snate@binkert.org getFlags() const 1405769Snate@binkert.org { 1415769Snate@binkert.org return flags & PublicRead; 1425769Snate@binkert.org } 1432SN/A 1445769Snate@binkert.org Flags 1455769Snate@binkert.org getFlags(Flags _flags) const 1465769Snate@binkert.org { 1475769Snate@binkert.org assert(flags.noneSet(~PublicRead)); 1485769Snate@binkert.org return flags.isSet(_flags); 1495769Snate@binkert.org } 1502SN/A 1515769Snate@binkert.org Flags 1525769Snate@binkert.org allFlags(Flags _flags) const 1535769Snate@binkert.org { 1545769Snate@binkert.org assert(_flags.noneSet(~PublicRead)); 1555769Snate@binkert.org return flags.allSet(_flags); 1565769Snate@binkert.org } 1575769Snate@binkert.org 1585769Snate@binkert.org /// Accessor for flags. 1595769Snate@binkert.org void 1605769Snate@binkert.org setFlags(Flags _flags) 1615769Snate@binkert.org { 1625769Snate@binkert.org assert(_flags.noneSet(~PublicWrite)); 1635769Snate@binkert.org flags.set(_flags); 1645769Snate@binkert.org } 1655769Snate@binkert.org 1665769Snate@binkert.org void 1675769Snate@binkert.org clearFlags(Flags _flags) 1685769Snate@binkert.org { 1695769Snate@binkert.org assert(_flags.noneSet(~PublicWrite)); 1705769Snate@binkert.org flags.clear(_flags); 1715769Snate@binkert.org } 1725769Snate@binkert.org 1735769Snate@binkert.org void 1745769Snate@binkert.org clearFlags() 1755769Snate@binkert.org { 1765769Snate@binkert.org flags.clear(PublicWrite); 1775769Snate@binkert.org } 1785769Snate@binkert.org 1795501Snate@binkert.org // This function isn't really useful if TRACING_ON is not defined 1805543Ssaidi@eecs.umich.edu virtual void trace(const char *action); //!< trace event activity 1812SN/A 1822SN/A public: 183396SN/A /// Event priorities, to provide tie-breakers for events scheduled 184396SN/A /// at the same cycle. Most events are scheduled at the default 185396SN/A /// priority; these values are used to control events that need to 186396SN/A /// be ordered within a cycle. 187396SN/A enum Priority { 1885501Snate@binkert.org /// Minimum priority 1895543Ssaidi@eecs.umich.edu Minimum_Pri = SHRT_MIN, 1905501Snate@binkert.org 1913329Sstever@eecs.umich.edu /// If we enable tracing on a particular cycle, do that as the 1923329Sstever@eecs.umich.edu /// very first thing so we don't miss any of the events on 1933329Sstever@eecs.umich.edu /// that cycle (even if we enter the debugger). 1943329Sstever@eecs.umich.edu Trace_Enable_Pri = -101, 1953329Sstever@eecs.umich.edu 1963329Sstever@eecs.umich.edu /// Breakpoints should happen before anything else (except 1973329Sstever@eecs.umich.edu /// enabling trace output), so we don't miss any action when 1983329Sstever@eecs.umich.edu /// debugging. 1995543Ssaidi@eecs.umich.edu Debug_Break_Pri = -100, 200396SN/A 2013329Sstever@eecs.umich.edu /// CPU switches schedule the new CPU's tick event for the 2023329Sstever@eecs.umich.edu /// same cycle (after unscheduling the old CPU's tick event). 2033329Sstever@eecs.umich.edu /// The switch needs to come before any tick events to make 2043329Sstever@eecs.umich.edu /// sure we don't tick both CPUs in the same cycle. 2055543Ssaidi@eecs.umich.edu CPU_Switch_Pri = -31, 2063329Sstever@eecs.umich.edu 207396SN/A /// For some reason "delayed" inter-cluster writebacks are 208396SN/A /// scheduled before regular writebacks (which have default 209396SN/A /// priority). Steve? 2105543Ssaidi@eecs.umich.edu Delayed_Writeback_Pri = -1, 211396SN/A 212396SN/A /// Default is zero for historical reasons. 2135543Ssaidi@eecs.umich.edu Default_Pri = 0, 214396SN/A 215396SN/A /// Serailization needs to occur before tick events also, so 216396SN/A /// that a serialize/unserialize is identical to an on-line 217396SN/A /// CPU switch. 2185543Ssaidi@eecs.umich.edu Serialize_Pri = 32, 219396SN/A 220396SN/A /// CPU ticks must come after other associated CPU events 221396SN/A /// (such as writebacks). 2225543Ssaidi@eecs.umich.edu CPU_Tick_Pri = 50, 223396SN/A 224396SN/A /// Statistics events (dump, reset, etc.) come after 225396SN/A /// everything else, but before exit. 2265543Ssaidi@eecs.umich.edu Stat_Event_Pri = 90, 227396SN/A 2284075Sbinkertn@umich.edu /// Progress events come at the end. 2294075Sbinkertn@umich.edu Progress_Event_Pri = 95, 2304075Sbinkertn@umich.edu 231396SN/A /// If we want to exit on this cycle, it's the very last thing 232396SN/A /// we do. 2335543Ssaidi@eecs.umich.edu Sim_Exit_Pri = 100, 2345501Snate@binkert.org 2355501Snate@binkert.org /// Maximum priority 2365543Ssaidi@eecs.umich.edu Maximum_Pri = SHRT_MAX 237396SN/A }; 238396SN/A 2392SN/A /* 2402SN/A * Event constructor 2412SN/A * @param queue that the event gets scheduled on 2422SN/A */ 2435605Snate@binkert.org Event(Priority p = Default_Pri) 2445769Snate@binkert.org : nextBin(NULL), nextInBin(NULL), _priority(p) 245224SN/A { 2464016Sstever@eecs.umich.edu#ifndef NDEBUG 2475501Snate@binkert.org instance = ++instanceCounter; 2485605Snate@binkert.org queue = NULL; 2495501Snate@binkert.org#endif 2505501Snate@binkert.org#ifdef EVENTQ_DEBUG 2515774Snate@binkert.org flags.set(Initialized); 2525501Snate@binkert.org whenCreated = curTick; 2535501Snate@binkert.org whenScheduled = 0; 2544016Sstever@eecs.umich.edu#endif 255224SN/A } 256224SN/A 2575768Snate@binkert.org virtual ~Event(); 2585768Snate@binkert.org virtual const std::string name() const; 259265SN/A 2605501Snate@binkert.org /// Return a C string describing the event. This string should 2615501Snate@binkert.org /// *not* be dynamically allocated; just a const char array 2625501Snate@binkert.org /// describing the event class. 2635501Snate@binkert.org virtual const char *description() const; 2645501Snate@binkert.org 2655501Snate@binkert.org /// Dump the current event data 2665501Snate@binkert.org void dump() const; 2675501Snate@binkert.org 2685501Snate@binkert.org public: 2695501Snate@binkert.org /* 2705501Snate@binkert.org * This member function is invoked when the event is processed 2715501Snate@binkert.org * (occurs). There is no default implementation; each subclass 2725501Snate@binkert.org * must provide its own implementation. The event is not 2735501Snate@binkert.org * automatically deleted after it is processed (to allow for 2745501Snate@binkert.org * statically allocated event objects). 2755501Snate@binkert.org * 2765501Snate@binkert.org * If the AutoDestroy flag is set, the object is deleted once it 2775501Snate@binkert.org * is processed. 2785501Snate@binkert.org */ 2795501Snate@binkert.org virtual void process() = 0; 2805501Snate@binkert.org 2812SN/A /// Determine if the current event is scheduled 2825769Snate@binkert.org bool scheduled() const { return flags.isSet(Scheduled); } 2832SN/A 2842SN/A /// Squash the current event 2855769Snate@binkert.org void squash() { flags.set(Squashed); } 2862SN/A 2872SN/A /// Check whether the event is squashed 2885769Snate@binkert.org bool squashed() const { return flags.isSet(Squashed); } 2892SN/A 2902667Sstever@eecs.umich.edu /// See if this is a SimExitEvent (without resorting to RTTI) 2915769Snate@binkert.org bool isExitEvent() const { return flags.isSet(IsExitEvent); } 2922667Sstever@eecs.umich.edu 2932SN/A /// Get the time that the event is scheduled 2942SN/A Tick when() const { return _when; } 2952SN/A 2962SN/A /// Get the event priority 2972SN/A int priority() const { return _priority; } 2982SN/A 2995605Snate@binkert.org#ifndef SWIG 3005501Snate@binkert.org struct priority_compare 3015501Snate@binkert.org : public std::binary_function<Event *, Event *, bool> 3022SN/A { 3035501Snate@binkert.org bool 3045501Snate@binkert.org operator()(const Event *l, const Event *r) const 3055501Snate@binkert.org { 3062SN/A return l->when() >= r->when() || l->priority() >= r->priority(); 3072SN/A } 3082SN/A }; 309224SN/A 310224SN/A virtual void serialize(std::ostream &os); 311237SN/A virtual void unserialize(Checkpoint *cp, const std::string §ion); 3125605Snate@binkert.org#endif 313571SN/A}; 314571SN/A 3152SN/A/* 3162SN/A * Queue of events sorted in time order 3172SN/A */ 318395SN/Aclass EventQueue : public Serializable 3192SN/A{ 3205605Snate@binkert.org private: 321265SN/A std::string objName; 3222SN/A Event *head; 3232SN/A 3242SN/A void insert(Event *event); 3252SN/A void remove(Event *event); 3262SN/A 3272SN/A public: 3282SN/A EventQueue(const std::string &n) 329265SN/A : objName(n), head(NULL) 3302SN/A {} 3312SN/A 332512SN/A virtual const std::string name() const { return objName; } 333265SN/A 3342SN/A // schedule the given event on this queue 3355738Snate@binkert.org void schedule(Event *event, Tick when); 3365738Snate@binkert.org void deschedule(Event *event); 3375738Snate@binkert.org void reschedule(Event *event, Tick when, bool always = false); 3382SN/A 3395501Snate@binkert.org Tick nextTick() const { return head->when(); } 3402667Sstever@eecs.umich.edu Event *serviceOne(); 3412SN/A 3422SN/A // process all events up to the given timestamp. we inline a 3432SN/A // quick test to see if there are any events to process; if so, 3442SN/A // call the internal out-of-line version to process them all. 3455501Snate@binkert.org void 3465501Snate@binkert.org serviceEvents(Tick when) 3475501Snate@binkert.org { 3482SN/A while (!empty()) { 3492SN/A if (nextTick() > when) 3502SN/A break; 3512SN/A 3521634SN/A /** 3531634SN/A * @todo this assert is a good bug catcher. I need to 3541634SN/A * make it true again. 3551634SN/A */ 3561634SN/A //assert(head->when() >= when && "event scheduled in the past"); 3572SN/A serviceOne(); 3582SN/A } 3592SN/A } 3602SN/A 3612SN/A // default: process all events up to 'now' (curTick) 3622SN/A void serviceEvents() { serviceEvents(curTick); } 3632SN/A 3642SN/A // return true if no events are queued 3655501Snate@binkert.org bool empty() const { return head == NULL; } 3662SN/A 3675501Snate@binkert.org void dump() const; 3682SN/A 3692SN/A Tick nextEventTime() { return empty() ? curTick : head->when(); } 3702SN/A 3715502Snate@binkert.org bool debugVerify() const; 3725502Snate@binkert.org 3735605Snate@binkert.org#ifndef SWIG 374217SN/A virtual void serialize(std::ostream &os); 375237SN/A virtual void unserialize(Checkpoint *cp, const std::string §ion); 3765605Snate@binkert.org#endif 3772SN/A}; 3782SN/A 3795605Snate@binkert.org#ifndef SWIG 3805605Snate@binkert.orgclass EventManager 3815605Snate@binkert.org{ 3825605Snate@binkert.org protected: 3835605Snate@binkert.org /** A pointer to this object's event queue */ 3845605Snate@binkert.org EventQueue *eventq; 3852SN/A 3865605Snate@binkert.org public: 3875605Snate@binkert.org EventManager(EventManager &em) : eventq(em.queue()) {} 3885605Snate@binkert.org EventManager(EventManager *em) : eventq(em ? em->queue() : NULL) {} 3895605Snate@binkert.org EventManager(EventQueue *eq) : eventq(eq) {} 3902SN/A 3915605Snate@binkert.org EventQueue * 3925605Snate@binkert.org queue() const 3935605Snate@binkert.org { 3945605Snate@binkert.org return eventq; 3955605Snate@binkert.org } 3965605Snate@binkert.org 3975605Snate@binkert.org void 3985605Snate@binkert.org schedule(Event &event, Tick when) 3995605Snate@binkert.org { 4005605Snate@binkert.org eventq->schedule(&event, when); 4015605Snate@binkert.org } 4025605Snate@binkert.org 4035605Snate@binkert.org void 4045605Snate@binkert.org deschedule(Event &event) 4055605Snate@binkert.org { 4065605Snate@binkert.org eventq->deschedule(&event); 4075605Snate@binkert.org } 4085605Snate@binkert.org 4095605Snate@binkert.org void 4105605Snate@binkert.org reschedule(Event &event, Tick when, bool always = false) 4115605Snate@binkert.org { 4125605Snate@binkert.org eventq->reschedule(&event, when, always); 4135605Snate@binkert.org } 4145605Snate@binkert.org 4155605Snate@binkert.org void 4165605Snate@binkert.org schedule(Event *event, Tick when) 4175605Snate@binkert.org { 4185605Snate@binkert.org eventq->schedule(event, when); 4195605Snate@binkert.org } 4205605Snate@binkert.org 4215605Snate@binkert.org void 4225605Snate@binkert.org deschedule(Event *event) 4235605Snate@binkert.org { 4245605Snate@binkert.org eventq->deschedule(event); 4255605Snate@binkert.org } 4265605Snate@binkert.org 4275605Snate@binkert.org void 4285605Snate@binkert.org reschedule(Event *event, Tick when, bool always = false) 4295605Snate@binkert.org { 4305605Snate@binkert.org eventq->reschedule(event, when, always); 4315605Snate@binkert.org } 4325605Snate@binkert.org}; 4335605Snate@binkert.org 4345605Snate@binkert.orgtemplate <class T, void (T::* F)()> 4355605Snate@binkert.orgvoid 4365605Snate@binkert.orgDelayFunction(EventQueue *eventq, Tick when, T *object) 4375605Snate@binkert.org{ 4385605Snate@binkert.org class DelayEvent : public Event 4395605Snate@binkert.org { 4405605Snate@binkert.org private: 4415605Snate@binkert.org T *object; 4425605Snate@binkert.org 4435605Snate@binkert.org public: 4445605Snate@binkert.org DelayEvent(T *o) 4455605Snate@binkert.org : object(o) 4465769Snate@binkert.org { this->setFlags(AutoDelete); } 4475605Snate@binkert.org void process() { (object->*F)(); } 4485605Snate@binkert.org const char *description() const { return "delay"; } 4495605Snate@binkert.org }; 4505605Snate@binkert.org 4515605Snate@binkert.org eventq->schedule(new DelayEvent(object), when); 4525605Snate@binkert.org} 4535605Snate@binkert.org 4545605Snate@binkert.orgtemplate <class T, void (T::* F)()> 4555605Snate@binkert.orgclass EventWrapper : public Event 4565605Snate@binkert.org{ 4575605Snate@binkert.org private: 4585605Snate@binkert.org T *object; 4595605Snate@binkert.org 4605605Snate@binkert.org public: 4615605Snate@binkert.org EventWrapper(T *obj, bool del = false, Priority p = Default_Pri) 4625605Snate@binkert.org : Event(p), object(obj) 4635605Snate@binkert.org { 4645605Snate@binkert.org if (del) 4655605Snate@binkert.org setFlags(AutoDelete); 4665605Snate@binkert.org } 4675605Snate@binkert.org 4685605Snate@binkert.org void process() { (object->*F)(); } 4696982Snate@binkert.org 4706982Snate@binkert.org const std::string 4716982Snate@binkert.org name() const 4726982Snate@binkert.org { 4736982Snate@binkert.org return object->name() + ".wrapped_event"; 4746982Snate@binkert.org } 4756982Snate@binkert.org 4766982Snate@binkert.org const char *description() const { return "EventWrapped"; } 4775605Snate@binkert.org}; 4785605Snate@binkert.org 4792SN/Ainline void 4805605Snate@binkert.orgEventQueue::schedule(Event *event, Tick when) 4812SN/A{ 4826712Snate@binkert.org assert((UTick)when >= (UTick)curTick); 4835605Snate@binkert.org assert(!event->scheduled()); 4845774Snate@binkert.org#ifdef EVENTQ_DEBUG 4855774Snate@binkert.org assert((event->flags & Event::Initialized) == Event::Initialized); 4865774Snate@binkert.org#endif 4875605Snate@binkert.org 4885605Snate@binkert.org event->setWhen(when, this); 4895605Snate@binkert.org insert(event); 4905769Snate@binkert.org event->flags.set(Event::Scheduled); 4915605Snate@binkert.org if (this == &mainEventQueue) 4925769Snate@binkert.org event->flags.set(Event::IsMainQueue); 4935605Snate@binkert.org else 4945769Snate@binkert.org event->flags.clear(Event::IsMainQueue); 4955605Snate@binkert.org 4965605Snate@binkert.org if (DTRACE(Event)) 4975605Snate@binkert.org event->trace("scheduled"); 4982SN/A} 4992SN/A 5002SN/Ainline void 5015605Snate@binkert.orgEventQueue::deschedule(Event *event) 5022SN/A{ 5035605Snate@binkert.org assert(event->scheduled()); 5045774Snate@binkert.org#ifdef EVENTQ_DEBUG 5055774Snate@binkert.org assert((event->flags & Event::Initialized) == Event::Initialized); 5065774Snate@binkert.org#endif 5075605Snate@binkert.org 5085605Snate@binkert.org remove(event); 5095605Snate@binkert.org 5105769Snate@binkert.org event->flags.clear(Event::Squashed); 5115769Snate@binkert.org event->flags.clear(Event::Scheduled); 5125605Snate@binkert.org 5135769Snate@binkert.org if (event->flags.isSet(Event::AutoDelete)) 5145605Snate@binkert.org delete event; 5155605Snate@binkert.org 5165605Snate@binkert.org if (DTRACE(Event)) 5175605Snate@binkert.org event->trace("descheduled"); 5182SN/A} 5192SN/A 5202SN/Ainline void 5215605Snate@binkert.orgEventQueue::reschedule(Event *event, Tick when, bool always) 5222SN/A{ 5235605Snate@binkert.org assert(when >= curTick); 5245605Snate@binkert.org assert(always || event->scheduled()); 5255774Snate@binkert.org#ifdef EVENTQ_DEBUG 5265774Snate@binkert.org assert((event->flags & Event::Initialized) == Event::Initialized); 5275774Snate@binkert.org#endif 5285605Snate@binkert.org 5295605Snate@binkert.org if (event->scheduled()) 5305605Snate@binkert.org remove(event); 5315605Snate@binkert.org 5325605Snate@binkert.org event->setWhen(when, this); 5335605Snate@binkert.org insert(event); 5345769Snate@binkert.org event->flags.clear(Event::Squashed); 5355769Snate@binkert.org event->flags.set(Event::Scheduled); 5365605Snate@binkert.org if (this == &mainEventQueue) 5375769Snate@binkert.org event->flags.set(Event::IsMainQueue); 5385605Snate@binkert.org else 5395769Snate@binkert.org event->flags.clear(Event::IsMainQueue); 5405605Snate@binkert.org 5415605Snate@binkert.org if (DTRACE(Event)) 5425605Snate@binkert.org event->trace("rescheduled"); 5432SN/A} 5442SN/A 5455502Snate@binkert.orginline bool 5465502Snate@binkert.orgoperator<(const Event &l, const Event &r) 5475502Snate@binkert.org{ 5485502Snate@binkert.org return l.when() < r.when() || 5495502Snate@binkert.org (l.when() == r.when() && l.priority() < r.priority()); 5505502Snate@binkert.org} 5515502Snate@binkert.org 5525502Snate@binkert.orginline bool 5535502Snate@binkert.orgoperator>(const Event &l, const Event &r) 5545502Snate@binkert.org{ 5555502Snate@binkert.org return l.when() > r.when() || 5565502Snate@binkert.org (l.when() == r.when() && l.priority() > r.priority()); 5575502Snate@binkert.org} 5585502Snate@binkert.org 5595502Snate@binkert.orginline bool 5605502Snate@binkert.orgoperator<=(const Event &l, const Event &r) 5615502Snate@binkert.org{ 5625502Snate@binkert.org return l.when() < r.when() || 5635502Snate@binkert.org (l.when() == r.when() && l.priority() <= r.priority()); 5645502Snate@binkert.org} 5655502Snate@binkert.orginline bool 5665502Snate@binkert.orgoperator>=(const Event &l, const Event &r) 5675502Snate@binkert.org{ 5685502Snate@binkert.org return l.when() > r.when() || 5695502Snate@binkert.org (l.when() == r.when() && l.priority() >= r.priority()); 5705502Snate@binkert.org} 5715502Snate@binkert.org 5725502Snate@binkert.orginline bool 5735502Snate@binkert.orgoperator==(const Event &l, const Event &r) 5745502Snate@binkert.org{ 5755502Snate@binkert.org return l.when() == r.when() && l.priority() == r.priority(); 5765502Snate@binkert.org} 5775502Snate@binkert.org 5785502Snate@binkert.orginline bool 5795502Snate@binkert.orgoperator!=(const Event &l, const Event &r) 5805502Snate@binkert.org{ 5815502Snate@binkert.org return l.when() != r.when() || l.priority() != r.priority(); 5825502Snate@binkert.org} 5835605Snate@binkert.org#endif 5842SN/A 5851354SN/A#endif // __SIM_EVENTQ_HH__ 586