eventq.hh revision 5577
11689SN/A/*
28707Sandreas.hansson@arm.com * Copyright (c) 2000-2005 The Regents of The University of Michigan
38707Sandreas.hansson@arm.com * All rights reserved.
48707Sandreas.hansson@arm.com *
58707Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68707Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78707Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98707Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118707Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128707Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
138707Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
141689SN/A * this software without specific prior written permission.
157897Shestness@cs.utexas.edu *
161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271689SN/A *
281689SN/A * Authors: Steve Reinhardt
291689SN/A *          Nathan Binkert
301689SN/A */
311689SN/A
321689SN/A/* @file
331689SN/A * EventQueue interfaces
341689SN/A */
351689SN/A
361689SN/A#ifndef __SIM_EVENTQ_HH__
371689SN/A#define __SIM_EVENTQ_HH__
381689SN/A
391689SN/A#include <algorithm>
402665Ssaidi@eecs.umich.edu#include <cassert>
412665Ssaidi@eecs.umich.edu#include <climits>
422756Sksewell@umich.edu#include <map>
437897Shestness@cs.utexas.edu#include <string>
441689SN/A#include <vector>
451689SN/A
462325SN/A#include "base/fast_alloc.hh"
472325SN/A#include "base/misc.hh"
481060SN/A#include "base/trace.hh"
491060SN/A#include "sim/serialize.hh"
501060SN/A#include "sim/host.hh"
512292SN/A
522292SN/Aclass EventQueue;       // forward declaration
531681SN/A
541060SN/A//////////////////////
552980Sgblack@eecs.umich.edu//
561060SN/A// Main Event Queue
576658Snate@binkert.org//
581717SN/A// Events on this queue are processed at the *beginning* of each
591717SN/A// cycle, before the pipeline simulation is performed.
602292SN/A//
612292SN/A// defined in eventq.cc
628229Snate@binkert.org//
638229Snate@binkert.org//////////////////////
648229Snate@binkert.orgextern EventQueue mainEventQueue;
658229Snate@binkert.org
662817Sksewell@umich.edu/*
678229Snate@binkert.org * An item on an event queue.  The action caused by a given
681060SN/A * event is specified by deriving a subclass and overriding the
691060SN/A * process() member function.
702316SN/A *
712316SN/A * Caution, the order of members is chosen to maximize data packing.
722680Sktlim@umich.edu */
732817Sksewell@umich.educlass Event : public Serializable, public FastAlloc
742817Sksewell@umich.edu{
752843Sktlim@umich.edu    friend class EventQueue;
762843Sktlim@umich.edu
772669Sktlim@umich.edu  private:
781060SN/A    // The event queue is now a linked list of linked lists.  The
791060SN/A    // 'nextBin' pointer is to find the bin, where a bin is defined as
808737Skoansin.tan@gmail.com    // when+priority.  All events in the same bin will be stored in a
815529Snate@binkert.org    // second linked list (a stack) maintained by the 'nextInBin'
822733Sktlim@umich.edu    // pointer.  The list will be accessed in LIFO order.  The end
831060SN/A    // result is that the insert/removal in 'nextBin' is
841060SN/A    // linear/constant, and the lookup/removal in 'nextInBin' is
851060SN/A    // constant/constant.  Hopefully this is a significant improvement
865529Snate@binkert.org    // over the current fully linear insertion.
872292SN/A    Event *nextBin;
882292SN/A    Event *nextInBin;
891060SN/A
901060SN/A    friend Event *insertBefore(Event *event, Event *curr);
912348SN/A    friend Event *removeItem(Event *event, Event *last);
922348SN/A
932348SN/A    /// queue to which this event belongs (though it may or may not be
942348SN/A    /// scheduled on this queue yet)
952348SN/A    EventQueue *_queue;
961060SN/A
972733Sktlim@umich.edu    Tick _when;         //!< timestamp when event should be processed
981060SN/A    short _priority;    //!< event priority
991060SN/A    short _flags;
1002325SN/A
1011060SN/A#ifndef NDEBUG
1021061SN/A    /// Global counter to generate unique IDs for Event instances
1034329Sktlim@umich.edu    static Counter instanceCounter;
1041060SN/A
1055595Sgblack@eecs.umich.edu    /// This event's unique ID.  We can also use pointer values for
1062292SN/A    /// this but they're not consistent across runs making debugging
1072292SN/A    /// more difficult.  Thus we use a global counter value when
1082292SN/A    /// debugging.
1092292SN/A    Counter instance;
1102817Sksewell@umich.edu#endif
1112829Sksewell@umich.edu
1121060SN/A#ifdef EVENTQ_DEBUG
1131060SN/A    Tick whenCreated;   //!< time created
1141060SN/A    Tick whenScheduled; //!< time scheduled
1151060SN/A#endif
1161060SN/A
1172307SN/A  protected:
1182307SN/A    void
1191060SN/A    setWhen(Tick when)
1201060SN/A    {
1216022Sgblack@eecs.umich.edu        _when = when;
1226022Sgblack@eecs.umich.edu#ifdef EVENTQ_DEBUG
1233781Sgblack@eecs.umich.edu        whenScheduled = curTick;
1242292SN/A#endif
1251060SN/A    }
1261060SN/A
1272829Sksewell@umich.edu  protected:
1282829Sksewell@umich.edu    enum Flags {
1292829Sksewell@umich.edu        None = 0x0,
1301060SN/A        Squashed = 0x1,
1318707Sandreas.hansson@arm.com        Scheduled = 0x2,
1328707Sandreas.hansson@arm.com        AutoDelete = 0x4,
1338707Sandreas.hansson@arm.com        AutoSerialize = 0x8,
1348707Sandreas.hansson@arm.com        IsExitEvent = 0x10
1358707Sandreas.hansson@arm.com    };
1368707Sandreas.hansson@arm.com
1378707Sandreas.hansson@arm.com    bool getFlags(Flags f) const { return (_flags & f) == f; }
1388707Sandreas.hansson@arm.com    void setFlags(Flags f) { _flags |= f; }
1398707Sandreas.hansson@arm.com    void clearFlags(Flags f) { _flags &= ~f; }
1408707Sandreas.hansson@arm.com
1418707Sandreas.hansson@arm.com  protected:
1428707Sandreas.hansson@arm.com    EventQueue *queue() const { return _queue; }
1438707Sandreas.hansson@arm.com
1449095Sandreas.hansson@arm.com    // This function isn't really useful if TRACING_ON is not defined
1458707Sandreas.hansson@arm.com    virtual void trace(const char *action);     //!< trace event activity
1468707Sandreas.hansson@arm.com
1478707Sandreas.hansson@arm.com  public:
1488707Sandreas.hansson@arm.com    /// Event priorities, to provide tie-breakers for events scheduled
1498707Sandreas.hansson@arm.com    /// at the same cycle.  Most events are scheduled at the default
1508707Sandreas.hansson@arm.com    /// priority; these values are used to control events that need to
1518975Sandreas.hansson@arm.com    /// be ordered within a cycle.
1528975Sandreas.hansson@arm.com    enum Priority {
1538707Sandreas.hansson@arm.com        /// Minimum priority
1548707Sandreas.hansson@arm.com        Minimum_Pri             = SHRT_MIN,
1558707Sandreas.hansson@arm.com
1568707Sandreas.hansson@arm.com        /// If we enable tracing on a particular cycle, do that as the
1578707Sandreas.hansson@arm.com        /// very first thing so we don't miss any of the events on
1588707Sandreas.hansson@arm.com        /// that cycle (even if we enter the debugger).
1598707Sandreas.hansson@arm.com        Trace_Enable_Pri        = -101,
1608707Sandreas.hansson@arm.com
1618707Sandreas.hansson@arm.com        /// Breakpoints should happen before anything else (except
1628707Sandreas.hansson@arm.com        /// enabling trace output), so we don't miss any action when
1638707Sandreas.hansson@arm.com        /// debugging.
1648707Sandreas.hansson@arm.com        Debug_Break_Pri         = -100,
1658707Sandreas.hansson@arm.com
1668707Sandreas.hansson@arm.com        /// CPU switches schedule the new CPU's tick event for the
1678707Sandreas.hansson@arm.com        /// same cycle (after unscheduling the old CPU's tick event).
1688707Sandreas.hansson@arm.com        /// The switch needs to come before any tick events to make
1698707Sandreas.hansson@arm.com        /// sure we don't tick both CPUs in the same cycle.
1708707Sandreas.hansson@arm.com        CPU_Switch_Pri          =   -31,
1719095Sandreas.hansson@arm.com
1728707Sandreas.hansson@arm.com        /// For some reason "delayed" inter-cluster writebacks are
1738707Sandreas.hansson@arm.com        /// scheduled before regular writebacks (which have default
1748707Sandreas.hansson@arm.com        /// priority).  Steve?
1758707Sandreas.hansson@arm.com        Delayed_Writeback_Pri   =   -1,
1768707Sandreas.hansson@arm.com
1778707Sandreas.hansson@arm.com        /// Default is zero for historical reasons.
1788707Sandreas.hansson@arm.com        Default_Pri             =    0,
1798975Sandreas.hansson@arm.com
1808975Sandreas.hansson@arm.com        /// Serailization needs to occur before tick events also, so
1818707Sandreas.hansson@arm.com        /// that a serialize/unserialize is identical to an on-line
1828707Sandreas.hansson@arm.com        /// CPU switch.
1838707Sandreas.hansson@arm.com        Serialize_Pri           =   32,
1848707Sandreas.hansson@arm.com
1858707Sandreas.hansson@arm.com        /// CPU ticks must come after other associated CPU events
1868707Sandreas.hansson@arm.com        /// (such as writebacks).
1878707Sandreas.hansson@arm.com        CPU_Tick_Pri            =   50,
1888707Sandreas.hansson@arm.com
1898711Sandreas.hansson@arm.com        /// Statistics events (dump, reset, etc.) come after
1908707Sandreas.hansson@arm.com        /// everything else, but before exit.
1918922Swilliam.wang@arm.com        Stat_Event_Pri          =   90,
1928707Sandreas.hansson@arm.com
1938707Sandreas.hansson@arm.com        /// Progress events come at the end.
1941060SN/A        Progress_Event_Pri      =   95,
1951060SN/A
1961060SN/A        /// If we want to exit on this cycle, it's the very last thing
1972292SN/A        /// we do.
1981755SN/A        Sim_Exit_Pri            =  100,
1991060SN/A
2001060SN/A        /// Maximum priority
2012292SN/A        Maximum_Pri             = SHRT_MAX
2021755SN/A    };
2032292SN/A
2042292SN/A    /*
2051060SN/A     * Event constructor
2062292SN/A     * @param queue that the event gets scheduled on
2075336Shines@cs.fsu.edu     */
2081060SN/A    Event(EventQueue *q, Priority p = Default_Pri)
2091060SN/A        : nextBin(NULL), nextInBin(NULL), _queue(q), _priority(p), _flags(None)
2102292SN/A    {
2111060SN/A#ifndef NDEBUG
2121060SN/A        instance = ++instanceCounter;
2132292SN/A#endif
2149180Sandreas.hansson@arm.com#ifdef EVENTQ_DEBUG
2151060SN/A        whenCreated = curTick;
2161060SN/A        whenScheduled = 0;
2179179Sandreas.hansson@arm.com#endif
2181060SN/A    }
2199179Sandreas.hansson@arm.com
2201060SN/A    virtual
2211060SN/A    ~Event()
2222292SN/A    {
2231060SN/A    }
2241060SN/A
2251060SN/A    virtual const std::string
2261060SN/A    name() const
2271060SN/A    {
2281060SN/A#ifndef NDEBUG
2292829Sksewell@umich.edu        return csprintf("Event_%d", instance);
2302829Sksewell@umich.edu#else
2312829Sksewell@umich.edu        return csprintf("Event_%x", (uintptr_t)this);
2322829Sksewell@umich.edu#endif
2336221Snate@binkert.org    }
2342829Sksewell@umich.edu
2352829Sksewell@umich.edu    /// Return a C string describing the event.  This string should
2362829Sksewell@umich.edu    /// *not* be dynamically allocated; just a const char array
2372829Sksewell@umich.edu    /// describing the event class.
2382829Sksewell@umich.edu    virtual const char *description() const;
2392829Sksewell@umich.edu
2402829Sksewell@umich.edu    /// Dump the current event data
2412829Sksewell@umich.edu    void dump() const;
2422829Sksewell@umich.edu
2432829Sksewell@umich.edu  public:
2442829Sksewell@umich.edu    /*
2452829Sksewell@umich.edu     * This member function is invoked when the event is processed
2462829Sksewell@umich.edu     * (occurs).  There is no default implementation; each subclass
2472829Sksewell@umich.edu     * must provide its own implementation.  The event is not
2482829Sksewell@umich.edu     * automatically deleted after it is processed (to allow for
2495336Shines@cs.fsu.edu     * statically allocated event objects).
2502829Sksewell@umich.edu     *
2512829Sksewell@umich.edu     * If the AutoDestroy flag is set, the object is deleted once it
2522829Sksewell@umich.edu     * is processed.
2536221Snate@binkert.org     */
2549180Sandreas.hansson@arm.com    virtual void process() = 0;
2552829Sksewell@umich.edu
2562829Sksewell@umich.edu    /// Determine if the current event is scheduled
2572829Sksewell@umich.edu    bool scheduled() const { return getFlags(Scheduled); }
2585606Snate@binkert.org
2599179Sandreas.hansson@arm.com    /// Schedule the event with the current priority or default priority
2608518Sgeoffrey.blake@arm.com    void schedule(Tick t);
2619179Sandreas.hansson@arm.com
2628518Sgeoffrey.blake@arm.com    /// Reschedule the event with the current priority
2638518Sgeoffrey.blake@arm.com    // always parameter means to schedule if not already scheduled
2648518Sgeoffrey.blake@arm.com    void reschedule(Tick t, bool always = false);
2658518Sgeoffrey.blake@arm.com
2668518Sgeoffrey.blake@arm.com    /// Remove the event from the current schedule
2678518Sgeoffrey.blake@arm.com    void deschedule();
2688518Sgeoffrey.blake@arm.com
2698518Sgeoffrey.blake@arm.com    /// Squash the current event
2708518Sgeoffrey.blake@arm.com    void squash() { setFlags(Squashed); }
2718518Sgeoffrey.blake@arm.com
2728518Sgeoffrey.blake@arm.com    /// Check whether the event is squashed
2732829Sksewell@umich.edu    bool squashed() const { return getFlags(Squashed); }
2742829Sksewell@umich.edu
2752829Sksewell@umich.edu    /// See if this is a SimExitEvent (without resorting to RTTI)
2766221Snate@binkert.org    bool isExitEvent() const { return getFlags(IsExitEvent); }
2776221Snate@binkert.org
2782829Sksewell@umich.edu    /// Get the time that the event is scheduled
2792829Sksewell@umich.edu    Tick when() const { return _when; }
2802829Sksewell@umich.edu
2812829Sksewell@umich.edu    /// Get the event priority
2822829Sksewell@umich.edu    int priority() const { return _priority; }
2832829Sksewell@umich.edu
2842829Sksewell@umich.edu    struct priority_compare
2852829Sksewell@umich.edu        : public std::binary_function<Event *, Event *, bool>
2862875Sksewell@umich.edu    {
2872875Sksewell@umich.edu        bool
2882875Sksewell@umich.edu        operator()(const Event *l, const Event *r) const
2893221Sktlim@umich.edu        {
2906221Snate@binkert.org            return l->when() >= r->when() || l->priority() >= r->priority();
2912875Sksewell@umich.edu        }
2923221Sktlim@umich.edu    };
2933221Sktlim@umich.edu
2943221Sktlim@umich.edu    virtual void serialize(std::ostream &os);
2952875Sksewell@umich.edu    virtual void unserialize(Checkpoint *cp, const std::string &section);
2962875Sksewell@umich.edu};
2972875Sksewell@umich.edu
2982875Sksewell@umich.edutemplate <class T, void (T::* F)()>
2992875Sksewell@umich.eduvoid
3002875Sksewell@umich.eduDelayFunction(Tick when, T *object)
3012875Sksewell@umich.edu{
3022875Sksewell@umich.edu    class DelayEvent : public Event
3032875Sksewell@umich.edu    {
3042875Sksewell@umich.edu      private:
3052875Sksewell@umich.edu        T *object;
3062875Sksewell@umich.edu
3072875Sksewell@umich.edu      public:
3083221Sktlim@umich.edu        DelayEvent(Tick when, T *o)
3093221Sktlim@umich.edu            : Event(&mainEventQueue), object(o)
3103221Sktlim@umich.edu            { setFlags(this->AutoDestroy); schedule(when); }
3112875Sksewell@umich.edu        void process() { (object->*F)(); }
3125336Shines@cs.fsu.edu        const char *description() const { return "delay"; }
3132875Sksewell@umich.edu    };
3142875Sksewell@umich.edu
3152875Sksewell@umich.edu    new DelayEvent(when, object);
3166221Snate@binkert.org}
3179180Sandreas.hansson@arm.com
3182875Sksewell@umich.edutemplate <class T, void (T::* F)()>
3192875Sksewell@umich.educlass EventWrapper : public Event
3202875Sksewell@umich.edu{
3215606Snate@binkert.org  private:
3229179Sandreas.hansson@arm.com    T *object;
3232875Sksewell@umich.edu
3245606Snate@binkert.org  public:
3259179Sandreas.hansson@arm.com    EventWrapper(T *obj, bool del = false,
3262875Sksewell@umich.edu                 EventQueue *q = &mainEventQueue,
3272875Sksewell@umich.edu                 Priority p = Default_Pri)
3282875Sksewell@umich.edu        : Event(q, p), object(obj)
3296221Snate@binkert.org    {
3306221Snate@binkert.org        if (del)
3312875Sksewell@umich.edu            setFlags(AutoDelete);
3322875Sksewell@umich.edu    }
3332875Sksewell@umich.edu
3342875Sksewell@umich.edu    EventWrapper(T *obj, Tick t, bool del = false,
3352875Sksewell@umich.edu                 EventQueue *q = &mainEventQueue,
3362875Sksewell@umich.edu                 Priority p = Default_Pri)
3372875Sksewell@umich.edu        : Event(q, p), object(obj)
3382875Sksewell@umich.edu    {
3391060SN/A        if (del)
3402292SN/A            setFlags(AutoDelete);
3415595Sgblack@eecs.umich.edu        schedule(t);
3422292SN/A    }
3431755SN/A
3441060SN/A    void process() { (object->*F)(); }
3452292SN/A};
3465595Sgblack@eecs.umich.edu
3471684SN/A/*
3485358Sgblack@eecs.umich.edu * Queue of events sorted in time order
3495358Sgblack@eecs.umich.edu */
3505358Sgblack@eecs.umich.educlass EventQueue : public Serializable
3515358Sgblack@eecs.umich.edu{
3525358Sgblack@eecs.umich.edu  protected:
3535358Sgblack@eecs.umich.edu    std::string objName;
3545358Sgblack@eecs.umich.edu
3555358Sgblack@eecs.umich.edu  private:
3565358Sgblack@eecs.umich.edu    Event *head;
3575358Sgblack@eecs.umich.edu
3585358Sgblack@eecs.umich.edu    void insert(Event *event);
3595358Sgblack@eecs.umich.edu    void remove(Event *event);
3605358Sgblack@eecs.umich.edu
3615358Sgblack@eecs.umich.edu  public:
3625358Sgblack@eecs.umich.edu
3635358Sgblack@eecs.umich.edu    // constructor
3642292SN/A    EventQueue(const std::string &n)
3652292SN/A        : objName(n), head(NULL)
3662292SN/A    {}
3671684SN/A
3681684SN/A    virtual const std::string name() const { return objName; }
3692292SN/A
3701060SN/A    // schedule the given event on this queue
3711060SN/A    void schedule(Event *ev, Tick when);
3729427SAndreas.Sandberg@ARM.com    void deschedule(Event *ev);
3739427SAndreas.Sandberg@ARM.com    void reschedule(Event *ev, Tick when);
3742834Sksewell@umich.edu
3752834Sksewell@umich.edu    Tick nextTick() const { return head->when(); }
3762834Sksewell@umich.edu    Event *serviceOne();
3772834Sksewell@umich.edu
3782829Sksewell@umich.edu    // process all events up to the given timestamp.  we inline a
3796221Snate@binkert.org    // quick test to see if there are any events to process; if so,
3802875Sksewell@umich.edu    // call the internal out-of-line version to process them all.
3812875Sksewell@umich.edu    void
3826221Snate@binkert.org    serviceEvents(Tick when)
3832829Sksewell@umich.edu    {
3842292SN/A        while (!empty()) {
3856221Snate@binkert.org            if (nextTick() > when)
3861060SN/A                break;
3872292SN/A
3886221Snate@binkert.org            /**
3892292SN/A             * @todo this assert is a good bug catcher.  I need to
3902292SN/A             * make it true again.
3918834Satgutier@umich.edu             */
3928834Satgutier@umich.edu            //assert(head->when() >= when && "event scheduled in the past");
3938834Satgutier@umich.edu            serviceOne();
3948834Satgutier@umich.edu        }
3952292SN/A    }
3962292SN/A
3979180Sandreas.hansson@arm.com    // default: process all events up to 'now' (curTick)
3982292SN/A    void serviceEvents() { serviceEvents(curTick); }
3992292SN/A
4006221Snate@binkert.org    // return true if no events are queued
4012292SN/A    bool empty() const { return head == NULL; }
4022292SN/A
4033221Sktlim@umich.edu    void dump() const;
4042292SN/A
4059180Sandreas.hansson@arm.com    Tick nextEventTime() { return empty() ? curTick : head->when(); }
4069180Sandreas.hansson@arm.com
4072292SN/A    bool debugVerify() const;
4082292SN/A
4092292SN/A    virtual void serialize(std::ostream &os);
4102292SN/A    virtual void unserialize(Checkpoint *cp, const std::string &section);
4116221Snate@binkert.org};
4122292SN/A
4132292SN/A
4146221Snate@binkert.org//////////////////////
4152292SN/A//
4162292SN/A// inline functions
4172292SN/A//
4182292SN/A// can't put these inside declaration due to circular dependence
4192292SN/A// between Event and EventQueue classes.
4202292SN/A//
4212292SN/A//////////////////////
4222864Sktlim@umich.edu
4232864Sktlim@umich.edu// schedule at specified time (place on event queue specified via
4242864Sktlim@umich.edu// constructor)
4252864Sktlim@umich.eduinline void
4262864Sktlim@umich.eduEvent::schedule(Tick when)
4272864Sktlim@umich.edu{
4282864Sktlim@umich.edu    _queue->schedule(this, when);
4295595Sgblack@eecs.umich.edu}
4305595Sgblack@eecs.umich.edu
4312292SN/Ainline void
4326221Snate@binkert.orgEvent::deschedule()
4332292SN/A{
4342843Sktlim@umich.edu    _queue->deschedule(this);
4352843Sktlim@umich.edu}
4369342SAndreas.Sandberg@arm.com
4372843Sktlim@umich.eduinline void
4382843Sktlim@umich.eduEvent::reschedule(Tick when, bool always)
4399342SAndreas.Sandberg@arm.com{
4402292SN/A    if (scheduled()) {
4412348SN/A        _queue->reschedule(this, when);
4422843Sktlim@umich.edu    } else {
4432843Sktlim@umich.edu        assert(always);
4442843Sktlim@umich.edu        _queue->schedule(this, when);
4452843Sktlim@umich.edu    }
4462316SN/A}
4472348SN/A
4482843Sktlim@umich.eduinline bool
4491060SN/Aoperator<(const Event &l, const Event &r)
4501060SN/A{
4512316SN/A    return l.when() < r.when() ||
4522316SN/A        (l.when() == r.when() && l.priority() < r.priority());
4531060SN/A}
4545595Sgblack@eecs.umich.edu
4557684Sgblack@eecs.umich.eduinline bool
4565595Sgblack@eecs.umich.eduoperator>(const Event &l, const Event &r)
4575702Ssaidi@eecs.umich.edu{
4586221Snate@binkert.org    return l.when() > r.when() ||
4595702Ssaidi@eecs.umich.edu        (l.when() == r.when() && l.priority() > r.priority());
4606221Snate@binkert.org}
4615702Ssaidi@eecs.umich.edu
4625595Sgblack@eecs.umich.eduinline bool
4635595Sgblack@eecs.umich.eduoperator<=(const Event &l, const Event &r)
4645595Sgblack@eecs.umich.edu{
4655595Sgblack@eecs.umich.edu    return l.when() < r.when() ||
4665595Sgblack@eecs.umich.edu        (l.when() == r.when() && l.priority() <= r.priority());
4675595Sgblack@eecs.umich.edu}
4685595Sgblack@eecs.umich.eduinline bool
4695595Sgblack@eecs.umich.eduoperator>=(const Event &l, const Event &r)
4705595Sgblack@eecs.umich.edu{
4711060SN/A    return l.when() > r.when() ||
4721060SN/A        (l.when() == r.when() && l.priority() >= r.priority());
4731060SN/A}
4741060SN/A
4751060SN/Ainline bool
4761060SN/Aoperator==(const Event &l, const Event &r)
4772348SN/A{
4785595Sgblack@eecs.umich.edu    return l.when() == r.when() && l.priority() == r.priority();
4795595Sgblack@eecs.umich.edu}
4806221Snate@binkert.org
4815595Sgblack@eecs.umich.eduinline bool
4825595Sgblack@eecs.umich.eduoperator!=(const Event &l, const Event &r)
4835595Sgblack@eecs.umich.edu{
4845595Sgblack@eecs.umich.edu    return l.when() != r.when() || l.priority() != r.priority();
4856221Snate@binkert.org}
4865595Sgblack@eecs.umich.edu
4875595Sgblack@eecs.umich.eduinline void
4886221Snate@binkert.orgEventQueue::schedule(Event *event, Tick when)
4896221Snate@binkert.org{
4905595Sgblack@eecs.umich.edu    assert(when >= curTick);
4915595Sgblack@eecs.umich.edu    assert(!event->scheduled());
4925595Sgblack@eecs.umich.edu
4935595Sgblack@eecs.umich.edu    event->setWhen(when);
4945595Sgblack@eecs.umich.edu    insert(event);
4956221Snate@binkert.org    event->setFlags(Event::Scheduled);
4965595Sgblack@eecs.umich.edu
4971060SN/A    if (DTRACE(Event))
4981060SN/A        event->trace("scheduled");
4993781Sgblack@eecs.umich.edu}
5001060SN/A
5013781Sgblack@eecs.umich.eduinline void
5022455SN/AEventQueue::deschedule(Event *event)
5031060SN/A{
5041060SN/A    assert(event->scheduled());
5053781Sgblack@eecs.umich.edu
5061060SN/A    remove(event);
5073781Sgblack@eecs.umich.edu
5082455SN/A    event->clearFlags(Event::Squashed);
5096221Snate@binkert.org    event->clearFlags(Event::Scheduled);
5101060SN/A
5116314Sgblack@eecs.umich.edu    if (event->getFlags(Event::AutoDelete))
5122292SN/A        delete event;
5136221Snate@binkert.org
5142292SN/A    if (DTRACE(Event))
5152348SN/A        event->trace("descheduled");
5162348SN/A}
5172348SN/A
5182348SN/Ainline void
5192348SN/AEventQueue::reschedule(Event *event, Tick when)
5206221Snate@binkert.org{
5212292SN/A    assert(when >= curTick);
5226314Sgblack@eecs.umich.edu    assert(event->scheduled());
5232292SN/A
5246221Snate@binkert.org    remove(event);
5252292SN/A    event->setWhen(when);
5267720Sgblack@eecs.umich.edu    insert(event);
5277720Sgblack@eecs.umich.edu    event->clearFlags(Event::Squashed);
5287720Sgblack@eecs.umich.edu
5297720Sgblack@eecs.umich.edu    if (DTRACE(Event))
5307720Sgblack@eecs.umich.edu        event->trace("rescheduled");
5317720Sgblack@eecs.umich.edu}
5322348SN/A
5337720Sgblack@eecs.umich.edu#endif // __SIM_EVENTQ_HH__
5342292SN/A