eventq.hh revision 5738
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" 472361SN/A#include "base/misc.hh" 481354SN/A#include "base/trace.hh" 4956SN/A#include "sim/serialize.hh" 505501Snate@binkert.org#include "sim/host.hh" 512SN/A 525543Ssaidi@eecs.umich.educlass EventQueue; // forward declaration 532SN/A 541354SN/Aextern EventQueue mainEventQueue; 551354SN/A 562SN/A/* 572SN/A * An item on an event queue. The action caused by a given 582SN/A * event is specified by deriving a subclass and overriding the 592SN/A * process() member function. 605501Snate@binkert.org * 615501Snate@binkert.org * Caution, the order of members is chosen to maximize data packing. 622SN/A */ 63395SN/Aclass Event : public Serializable, public FastAlloc 642SN/A{ 652SN/A friend class EventQueue; 662SN/A 672SN/A private: 685502Snate@binkert.org // The event queue is now a linked list of linked lists. The 695502Snate@binkert.org // 'nextBin' pointer is to find the bin, where a bin is defined as 705502Snate@binkert.org // when+priority. All events in the same bin will be stored in a 715503Snate@binkert.org // second linked list (a stack) maintained by the 'nextInBin' 725503Snate@binkert.org // pointer. The list will be accessed in LIFO order. The end 735502Snate@binkert.org // result is that the insert/removal in 'nextBin' is 745502Snate@binkert.org // linear/constant, and the lookup/removal in 'nextInBin' is 755502Snate@binkert.org // constant/constant. Hopefully this is a significant improvement 765502Snate@binkert.org // over the current fully linear insertion. 775502Snate@binkert.org Event *nextBin; 785502Snate@binkert.org Event *nextInBin; 795502Snate@binkert.org 805602Snate@binkert.org static Event *insertBefore(Event *event, Event *curr); 815602Snate@binkert.org static Event *removeItem(Event *event, Event *last); 825501Snate@binkert.org 835543Ssaidi@eecs.umich.edu Tick _when; //!< timestamp when event should be processed 845543Ssaidi@eecs.umich.edu short _priority; //!< event priority 855501Snate@binkert.org short _flags; 864016Sstever@eecs.umich.edu 874016Sstever@eecs.umich.edu#ifndef NDEBUG 884016Sstever@eecs.umich.edu /// Global counter to generate unique IDs for Event instances 894016Sstever@eecs.umich.edu static Counter instanceCounter; 904016Sstever@eecs.umich.edu 914016Sstever@eecs.umich.edu /// This event's unique ID. We can also use pointer values for 924016Sstever@eecs.umich.edu /// this but they're not consistent across runs making debugging 934016Sstever@eecs.umich.edu /// more difficult. Thus we use a global counter value when 944016Sstever@eecs.umich.edu /// debugging. 955501Snate@binkert.org Counter instance; 965605Snate@binkert.org 975605Snate@binkert.org /// queue to which this event belongs (though it may or may not be 985605Snate@binkert.org /// scheduled on this queue yet) 995605Snate@binkert.org EventQueue *queue; 1005501Snate@binkert.org#endif 1014016Sstever@eecs.umich.edu 1025577SSteve.Reinhardt@amd.com#ifdef EVENTQ_DEBUG 1035501Snate@binkert.org Tick whenCreated; //!< time created 1045501Snate@binkert.org Tick whenScheduled; //!< time scheduled 1055501Snate@binkert.org#endif 1065502Snate@binkert.org 1075502Snate@binkert.org void 1085605Snate@binkert.org setWhen(Tick when, EventQueue *q) 1095502Snate@binkert.org { 1105502Snate@binkert.org _when = when; 1115605Snate@binkert.org#ifndef NDEBUG 1125605Snate@binkert.org queue = q; 1135605Snate@binkert.org#endif 1145577SSteve.Reinhardt@amd.com#ifdef EVENTQ_DEBUG 1155502Snate@binkert.org whenScheduled = curTick; 1165502Snate@binkert.org#endif 1175502Snate@binkert.org } 1185502Snate@binkert.org 1192SN/A protected: 1202SN/A enum Flags { 1212SN/A None = 0x0, 1222SN/A Squashed = 0x1, 1232SN/A Scheduled = 0x2, 124237SN/A AutoDelete = 0x4, 1252667Sstever@eecs.umich.edu AutoSerialize = 0x8, 1265605Snate@binkert.org IsExitEvent = 0x10, 1275605Snate@binkert.org IsMainQueue = 0x20 1282SN/A }; 1292SN/A 1302SN/A bool getFlags(Flags f) const { return (_flags & f) == f; } 1312SN/A void setFlags(Flags f) { _flags |= f; } 1322SN/A void clearFlags(Flags f) { _flags &= ~f; } 1332SN/A 1342SN/A protected: 1355501Snate@binkert.org // This function isn't really useful if TRACING_ON is not defined 1365543Ssaidi@eecs.umich.edu virtual void trace(const char *action); //!< trace event activity 1372SN/A 1382SN/A public: 139396SN/A /// Event priorities, to provide tie-breakers for events scheduled 140396SN/A /// at the same cycle. Most events are scheduled at the default 141396SN/A /// priority; these values are used to control events that need to 142396SN/A /// be ordered within a cycle. 143396SN/A enum Priority { 1445501Snate@binkert.org /// Minimum priority 1455543Ssaidi@eecs.umich.edu Minimum_Pri = SHRT_MIN, 1465501Snate@binkert.org 1473329Sstever@eecs.umich.edu /// If we enable tracing on a particular cycle, do that as the 1483329Sstever@eecs.umich.edu /// very first thing so we don't miss any of the events on 1493329Sstever@eecs.umich.edu /// that cycle (even if we enter the debugger). 1503329Sstever@eecs.umich.edu Trace_Enable_Pri = -101, 1513329Sstever@eecs.umich.edu 1523329Sstever@eecs.umich.edu /// Breakpoints should happen before anything else (except 1533329Sstever@eecs.umich.edu /// enabling trace output), so we don't miss any action when 1543329Sstever@eecs.umich.edu /// debugging. 1555543Ssaidi@eecs.umich.edu Debug_Break_Pri = -100, 156396SN/A 1573329Sstever@eecs.umich.edu /// CPU switches schedule the new CPU's tick event for the 1583329Sstever@eecs.umich.edu /// same cycle (after unscheduling the old CPU's tick event). 1593329Sstever@eecs.umich.edu /// The switch needs to come before any tick events to make 1603329Sstever@eecs.umich.edu /// sure we don't tick both CPUs in the same cycle. 1615543Ssaidi@eecs.umich.edu CPU_Switch_Pri = -31, 1623329Sstever@eecs.umich.edu 163396SN/A /// For some reason "delayed" inter-cluster writebacks are 164396SN/A /// scheduled before regular writebacks (which have default 165396SN/A /// priority). Steve? 1665543Ssaidi@eecs.umich.edu Delayed_Writeback_Pri = -1, 167396SN/A 168396SN/A /// Default is zero for historical reasons. 1695543Ssaidi@eecs.umich.edu Default_Pri = 0, 170396SN/A 171396SN/A /// Serailization needs to occur before tick events also, so 172396SN/A /// that a serialize/unserialize is identical to an on-line 173396SN/A /// CPU switch. 1745543Ssaidi@eecs.umich.edu Serialize_Pri = 32, 175396SN/A 176396SN/A /// CPU ticks must come after other associated CPU events 177396SN/A /// (such as writebacks). 1785543Ssaidi@eecs.umich.edu CPU_Tick_Pri = 50, 179396SN/A 180396SN/A /// Statistics events (dump, reset, etc.) come after 181396SN/A /// everything else, but before exit. 1825543Ssaidi@eecs.umich.edu Stat_Event_Pri = 90, 183396SN/A 1844075Sbinkertn@umich.edu /// Progress events come at the end. 1854075Sbinkertn@umich.edu Progress_Event_Pri = 95, 1864075Sbinkertn@umich.edu 187396SN/A /// If we want to exit on this cycle, it's the very last thing 188396SN/A /// we do. 1895543Ssaidi@eecs.umich.edu Sim_Exit_Pri = 100, 1905501Snate@binkert.org 1915501Snate@binkert.org /// Maximum priority 1925543Ssaidi@eecs.umich.edu Maximum_Pri = SHRT_MAX 193396SN/A }; 194396SN/A 1952SN/A /* 1962SN/A * Event constructor 1972SN/A * @param queue that the event gets scheduled on 1982SN/A */ 1995605Snate@binkert.org Event(Priority p = Default_Pri) 2005605Snate@binkert.org : nextBin(NULL), nextInBin(NULL), _priority(p), _flags(None) 201224SN/A { 2024016Sstever@eecs.umich.edu#ifndef NDEBUG 2035501Snate@binkert.org instance = ++instanceCounter; 2045605Snate@binkert.org queue = NULL; 2055501Snate@binkert.org#endif 2065501Snate@binkert.org#ifdef EVENTQ_DEBUG 2075501Snate@binkert.org whenCreated = curTick; 2085501Snate@binkert.org whenScheduled = 0; 2094016Sstever@eecs.umich.edu#endif 210224SN/A } 211224SN/A 2125501Snate@binkert.org virtual 2135501Snate@binkert.org ~Event() 2145501Snate@binkert.org { 2155501Snate@binkert.org } 2162SN/A 2175501Snate@binkert.org virtual const std::string 2185501Snate@binkert.org name() const 2195501Snate@binkert.org { 2204016Sstever@eecs.umich.edu#ifndef NDEBUG 2215501Snate@binkert.org return csprintf("Event_%d", instance); 2224016Sstever@eecs.umich.edu#else 223270SN/A return csprintf("Event_%x", (uintptr_t)this); 2244016Sstever@eecs.umich.edu#endif 225265SN/A } 226265SN/A 2275501Snate@binkert.org /// Return a C string describing the event. This string should 2285501Snate@binkert.org /// *not* be dynamically allocated; just a const char array 2295501Snate@binkert.org /// describing the event class. 2305501Snate@binkert.org virtual const char *description() const; 2315501Snate@binkert.org 2325501Snate@binkert.org /// Dump the current event data 2335501Snate@binkert.org void dump() const; 2345501Snate@binkert.org 2355501Snate@binkert.org public: 2365501Snate@binkert.org /* 2375501Snate@binkert.org * This member function is invoked when the event is processed 2385501Snate@binkert.org * (occurs). There is no default implementation; each subclass 2395501Snate@binkert.org * must provide its own implementation. The event is not 2405501Snate@binkert.org * automatically deleted after it is processed (to allow for 2415501Snate@binkert.org * statically allocated event objects). 2425501Snate@binkert.org * 2435501Snate@binkert.org * If the AutoDestroy flag is set, the object is deleted once it 2445501Snate@binkert.org * is processed. 2455501Snate@binkert.org */ 2465501Snate@binkert.org virtual void process() = 0; 2475501Snate@binkert.org 2482SN/A /// Determine if the current event is scheduled 2492SN/A bool scheduled() const { return getFlags(Scheduled); } 2502SN/A 2512SN/A /// Squash the current event 2522SN/A void squash() { setFlags(Squashed); } 2532SN/A 2542SN/A /// Check whether the event is squashed 2555501Snate@binkert.org bool squashed() const { return getFlags(Squashed); } 2562SN/A 2572667Sstever@eecs.umich.edu /// See if this is a SimExitEvent (without resorting to RTTI) 2585501Snate@binkert.org bool isExitEvent() const { return getFlags(IsExitEvent); } 2592667Sstever@eecs.umich.edu 2602SN/A /// Get the time that the event is scheduled 2612SN/A Tick when() const { return _when; } 2622SN/A 2632SN/A /// Get the event priority 2642SN/A int priority() const { return _priority; } 2652SN/A 2665605Snate@binkert.org#ifndef SWIG 2675501Snate@binkert.org struct priority_compare 2685501Snate@binkert.org : public std::binary_function<Event *, Event *, bool> 2692SN/A { 2705501Snate@binkert.org bool 2715501Snate@binkert.org operator()(const Event *l, const Event *r) const 2725501Snate@binkert.org { 2732SN/A return l->when() >= r->when() || l->priority() >= r->priority(); 2742SN/A } 2752SN/A }; 276224SN/A 277224SN/A virtual void serialize(std::ostream &os); 278237SN/A virtual void unserialize(Checkpoint *cp, const std::string §ion); 2795605Snate@binkert.org#endif 280571SN/A}; 281571SN/A 2822SN/A/* 2832SN/A * Queue of events sorted in time order 2842SN/A */ 285395SN/Aclass EventQueue : public Serializable 2862SN/A{ 2875605Snate@binkert.org private: 288265SN/A std::string objName; 2892SN/A Event *head; 2902SN/A 2912SN/A void insert(Event *event); 2922SN/A void remove(Event *event); 2932SN/A 2942SN/A public: 2952SN/A EventQueue(const std::string &n) 296265SN/A : objName(n), head(NULL) 2972SN/A {} 2982SN/A 299512SN/A virtual const std::string name() const { return objName; } 300265SN/A 3012SN/A // schedule the given event on this queue 3025738Snate@binkert.org void schedule(Event *event, Tick when); 3035738Snate@binkert.org void deschedule(Event *event); 3045738Snate@binkert.org void reschedule(Event *event, Tick when, bool always = false); 3052SN/A 3065501Snate@binkert.org Tick nextTick() const { return head->when(); } 3072667Sstever@eecs.umich.edu Event *serviceOne(); 3082SN/A 3092SN/A // process all events up to the given timestamp. we inline a 3102SN/A // quick test to see if there are any events to process; if so, 3112SN/A // call the internal out-of-line version to process them all. 3125501Snate@binkert.org void 3135501Snate@binkert.org serviceEvents(Tick when) 3145501Snate@binkert.org { 3152SN/A while (!empty()) { 3162SN/A if (nextTick() > when) 3172SN/A break; 3182SN/A 3191634SN/A /** 3201634SN/A * @todo this assert is a good bug catcher. I need to 3211634SN/A * make it true again. 3221634SN/A */ 3231634SN/A //assert(head->when() >= when && "event scheduled in the past"); 3242SN/A serviceOne(); 3252SN/A } 3262SN/A } 3272SN/A 3282SN/A // default: process all events up to 'now' (curTick) 3292SN/A void serviceEvents() { serviceEvents(curTick); } 3302SN/A 3312SN/A // return true if no events are queued 3325501Snate@binkert.org bool empty() const { return head == NULL; } 3332SN/A 3345501Snate@binkert.org void dump() const; 3352SN/A 3362SN/A Tick nextEventTime() { return empty() ? curTick : head->when(); } 3372SN/A 3385502Snate@binkert.org bool debugVerify() const; 3395502Snate@binkert.org 3405605Snate@binkert.org#ifndef SWIG 341217SN/A virtual void serialize(std::ostream &os); 342237SN/A virtual void unserialize(Checkpoint *cp, const std::string §ion); 3435605Snate@binkert.org#endif 3442SN/A}; 3452SN/A 3465605Snate@binkert.org#ifndef SWIG 3475605Snate@binkert.orgclass EventManager 3485605Snate@binkert.org{ 3495605Snate@binkert.org protected: 3505605Snate@binkert.org /** A pointer to this object's event queue */ 3515605Snate@binkert.org EventQueue *eventq; 3522SN/A 3535605Snate@binkert.org public: 3545605Snate@binkert.org EventManager(EventManager &em) : eventq(em.queue()) {} 3555605Snate@binkert.org EventManager(EventManager *em) : eventq(em ? em->queue() : NULL) {} 3565605Snate@binkert.org EventManager(EventQueue *eq) : eventq(eq) {} 3572SN/A 3585605Snate@binkert.org EventQueue * 3595605Snate@binkert.org queue() const 3605605Snate@binkert.org { 3615605Snate@binkert.org return eventq; 3625605Snate@binkert.org } 3635605Snate@binkert.org 3645605Snate@binkert.org void 3655605Snate@binkert.org schedule(Event &event, Tick when) 3665605Snate@binkert.org { 3675605Snate@binkert.org eventq->schedule(&event, when); 3685605Snate@binkert.org } 3695605Snate@binkert.org 3705605Snate@binkert.org void 3715605Snate@binkert.org deschedule(Event &event) 3725605Snate@binkert.org { 3735605Snate@binkert.org eventq->deschedule(&event); 3745605Snate@binkert.org } 3755605Snate@binkert.org 3765605Snate@binkert.org void 3775605Snate@binkert.org reschedule(Event &event, Tick when, bool always = false) 3785605Snate@binkert.org { 3795605Snate@binkert.org eventq->reschedule(&event, when, always); 3805605Snate@binkert.org } 3815605Snate@binkert.org 3825605Snate@binkert.org void 3835605Snate@binkert.org schedule(Event *event, Tick when) 3845605Snate@binkert.org { 3855605Snate@binkert.org eventq->schedule(event, when); 3865605Snate@binkert.org } 3875605Snate@binkert.org 3885605Snate@binkert.org void 3895605Snate@binkert.org deschedule(Event *event) 3905605Snate@binkert.org { 3915605Snate@binkert.org eventq->deschedule(event); 3925605Snate@binkert.org } 3935605Snate@binkert.org 3945605Snate@binkert.org void 3955605Snate@binkert.org reschedule(Event *event, Tick when, bool always = false) 3965605Snate@binkert.org { 3975605Snate@binkert.org eventq->reschedule(event, when, always); 3985605Snate@binkert.org } 3995605Snate@binkert.org}; 4005605Snate@binkert.org 4015605Snate@binkert.orgtemplate <class T, void (T::* F)()> 4025605Snate@binkert.orgvoid 4035605Snate@binkert.orgDelayFunction(EventQueue *eventq, Tick when, T *object) 4045605Snate@binkert.org{ 4055605Snate@binkert.org class DelayEvent : public Event 4065605Snate@binkert.org { 4075605Snate@binkert.org private: 4085605Snate@binkert.org T *object; 4095605Snate@binkert.org 4105605Snate@binkert.org public: 4115605Snate@binkert.org DelayEvent(T *o) 4125605Snate@binkert.org : object(o) 4135605Snate@binkert.org { setFlags(this->AutoDestroy); } 4145605Snate@binkert.org void process() { (object->*F)(); } 4155605Snate@binkert.org const char *description() const { return "delay"; } 4165605Snate@binkert.org }; 4175605Snate@binkert.org 4185605Snate@binkert.org eventq->schedule(new DelayEvent(object), when); 4195605Snate@binkert.org} 4205605Snate@binkert.org 4215605Snate@binkert.orgtemplate <class T, void (T::* F)()> 4225605Snate@binkert.orgclass EventWrapper : public Event 4235605Snate@binkert.org{ 4245605Snate@binkert.org private: 4255605Snate@binkert.org T *object; 4265605Snate@binkert.org 4275605Snate@binkert.org public: 4285605Snate@binkert.org EventWrapper(T *obj, bool del = false, Priority p = Default_Pri) 4295605Snate@binkert.org : Event(p), object(obj) 4305605Snate@binkert.org { 4315605Snate@binkert.org if (del) 4325605Snate@binkert.org setFlags(AutoDelete); 4335605Snate@binkert.org } 4345605Snate@binkert.org 4355605Snate@binkert.org void process() { (object->*F)(); } 4365605Snate@binkert.org}; 4375605Snate@binkert.org 4382SN/Ainline void 4395605Snate@binkert.orgEventQueue::schedule(Event *event, Tick when) 4402SN/A{ 4415605Snate@binkert.org assert(when >= curTick); 4425605Snate@binkert.org assert(!event->scheduled()); 4435605Snate@binkert.org 4445605Snate@binkert.org event->setWhen(when, this); 4455605Snate@binkert.org insert(event); 4465605Snate@binkert.org event->setFlags(Event::Scheduled); 4475605Snate@binkert.org if (this == &mainEventQueue) 4485605Snate@binkert.org event->setFlags(Event::IsMainQueue); 4495605Snate@binkert.org else 4505605Snate@binkert.org event->clearFlags(Event::IsMainQueue); 4515605Snate@binkert.org 4525605Snate@binkert.org if (DTRACE(Event)) 4535605Snate@binkert.org event->trace("scheduled"); 4542SN/A} 4552SN/A 4562SN/Ainline void 4575605Snate@binkert.orgEventQueue::deschedule(Event *event) 4582SN/A{ 4595605Snate@binkert.org assert(event->scheduled()); 4605605Snate@binkert.org 4615605Snate@binkert.org remove(event); 4625605Snate@binkert.org 4635605Snate@binkert.org event->clearFlags(Event::Squashed); 4645605Snate@binkert.org event->clearFlags(Event::Scheduled); 4655605Snate@binkert.org 4665605Snate@binkert.org if (event->getFlags(Event::AutoDelete)) 4675605Snate@binkert.org delete event; 4685605Snate@binkert.org 4695605Snate@binkert.org if (DTRACE(Event)) 4705605Snate@binkert.org event->trace("descheduled"); 4712SN/A} 4722SN/A 4732SN/Ainline void 4745605Snate@binkert.orgEventQueue::reschedule(Event *event, Tick when, bool always) 4752SN/A{ 4765605Snate@binkert.org assert(when >= curTick); 4775605Snate@binkert.org assert(always || event->scheduled()); 4785605Snate@binkert.org 4795605Snate@binkert.org if (event->scheduled()) 4805605Snate@binkert.org remove(event); 4815605Snate@binkert.org 4825605Snate@binkert.org event->setWhen(when, this); 4835605Snate@binkert.org insert(event); 4845605Snate@binkert.org event->clearFlags(Event::Squashed); 4855605Snate@binkert.org event->setFlags(Event::Scheduled); 4865605Snate@binkert.org if (this == &mainEventQueue) 4875605Snate@binkert.org event->setFlags(Event::IsMainQueue); 4885605Snate@binkert.org else 4895605Snate@binkert.org event->clearFlags(Event::IsMainQueue); 4905605Snate@binkert.org 4915605Snate@binkert.org if (DTRACE(Event)) 4925605Snate@binkert.org event->trace("rescheduled"); 4932SN/A} 4942SN/A 4955502Snate@binkert.orginline bool 4965502Snate@binkert.orgoperator<(const Event &l, const Event &r) 4975502Snate@binkert.org{ 4985502Snate@binkert.org return l.when() < r.when() || 4995502Snate@binkert.org (l.when() == r.when() && l.priority() < r.priority()); 5005502Snate@binkert.org} 5015502Snate@binkert.org 5025502Snate@binkert.orginline bool 5035502Snate@binkert.orgoperator>(const Event &l, const Event &r) 5045502Snate@binkert.org{ 5055502Snate@binkert.org return l.when() > r.when() || 5065502Snate@binkert.org (l.when() == r.when() && l.priority() > r.priority()); 5075502Snate@binkert.org} 5085502Snate@binkert.org 5095502Snate@binkert.orginline bool 5105502Snate@binkert.orgoperator<=(const Event &l, const Event &r) 5115502Snate@binkert.org{ 5125502Snate@binkert.org return l.when() < r.when() || 5135502Snate@binkert.org (l.when() == r.when() && l.priority() <= r.priority()); 5145502Snate@binkert.org} 5155502Snate@binkert.orginline bool 5165502Snate@binkert.orgoperator>=(const Event &l, const Event &r) 5175502Snate@binkert.org{ 5185502Snate@binkert.org return l.when() > r.when() || 5195502Snate@binkert.org (l.when() == r.when() && l.priority() >= r.priority()); 5205502Snate@binkert.org} 5215502Snate@binkert.org 5225502Snate@binkert.orginline bool 5235502Snate@binkert.orgoperator==(const Event &l, const Event &r) 5245502Snate@binkert.org{ 5255502Snate@binkert.org return l.when() == r.when() && l.priority() == r.priority(); 5265502Snate@binkert.org} 5275502Snate@binkert.org 5285502Snate@binkert.orginline bool 5295502Snate@binkert.orgoperator!=(const Event &l, const Event &r) 5305502Snate@binkert.org{ 5315502Snate@binkert.org return l.when() != r.when() || l.priority() != r.priority(); 5325502Snate@binkert.org} 5335605Snate@binkert.org#endif 5342SN/A 5351354SN/A#endif // __SIM_EVENTQ_HH__ 536