# HG changeset patch
# User Nathan Binkert <[EMAIL PROTECTED]>
# Date 1213057781 25200
# Node ID ad5af63d60375b99e633ef71ef687bacab0c8a82
# Parent  a31128ea7b6f9bc3242898efc2f5689db2ca6d06
eventq: Clean up the Event class so that it uses fewer bytes. This
will hopefullly allow it to fit in a cache line.

diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc
--- a/src/sim/eventq.cc
+++ b/src/sim/eventq.cc
@@ -53,8 +53,8 @@ using namespace std;
 //
 EventQueue mainEventQueue("MainEventQueue");
 
-#ifndef NDEBUG
-Counter Event::instanceCounter = 0;
+#if TRACING_ON
+Counter Event::Debug::instanceCounter = 0;
 #endif
 
 void
@@ -203,7 +203,7 @@ EventQueue::unserialize(Checkpoint *cp, 
 }
 
 void
-EventQueue::dump()
+EventQueue::dump() const
 {
     cprintf("============================================================\n");
     cprintf("EventQueue Dump  (cycle %d)\n", curTick);
@@ -235,7 +235,6 @@ Event::description() const
     return "generic";
 }
 
-#if TRACING_ON
 void
 Event::trace(const char *action)
 {
@@ -250,23 +249,21 @@ Event::trace(const char *action)
     // needs to be printed.
     DPRINTFN("%s event %s @ %d\n", description(), action, when());
 }
-#endif
 
 void
-Event::dump()
+Event::dump() const
 {
-    cprintf("Event  (%s)\n", description());
+    cprintf("Event %s (%s)\n", name(), description());
     cprintf("Flags: %#x\n", _flags);
 #if TRACING_ON
-    cprintf("Created: %d\n", when_created);
+    cprintf("Created: %d\n", debug->created);
 #endif
     if (scheduled()) {
 #if TRACING_ON
-        cprintf("Scheduled at  %d\n", when_scheduled);
+        cprintf("Scheduled at  %d\n", debug->scheduled);
 #endif
         cprintf("Scheduled for %d, priority %d\n", when(), _priority);
-    }
-    else {
+    } else {
         cprintf("Not Scheduled\n");
     }
 }
diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh
--- a/src/sim/eventq.hh
+++ b/src/sim/eventq.hh
@@ -64,38 +64,55 @@ class EventQueue;   // forward declaration
 //////////////////////
 extern EventQueue mainEventQueue;
 
-
 /*
  * An item on an event queue.  The action caused by a given
  * event is specified by deriving a subclass and overriding the
  * process() member function.
+ *
+ * Caution, the order of members is chosen to maximize data packing.
  */
 class Event : public Serializable, public FastAlloc
 {
     friend class EventQueue;
 
+#if TRACING_ON
   private:
+    struct Debug : public FastAlloc
+    {
+        /// Global counter to generate unique IDs for Event instances
+        static Counter instanceCounter;
 
-#ifndef NDEBUG
-    /// Global counter to generate unique IDs for Event instances
-    static Counter instanceCounter;
+        /// This event's unique ID.  We can also use pointer values for
+        /// this but they're not consistent across runs making debugging
+        /// more difficult.  Thus we use a global counter value when
+        /// debugging.
+        Counter instance;
 
-    /// This event's unique ID.  We can also use pointer values for
-    /// this but they're not consistent across runs making debugging
-    /// more difficult.  Thus we use a global counter value when
-    /// debugging.
-    Counter instanceId;
-#endif // NDEBUG
+        Tick created;   //!< time created
+        Tick scheduled; //!< time scheduled
+
+
+        Debug()
+            : instance(++instanceCounter), created(curTick), scheduled(0)
+        {
+        }
+    };
+#endif
+
+  private:
+    Event *next;
+
+#if TRACING_ON
+    Debug *debug;
+#endif
 
     /// queue to which this event belongs (though it may or may not be
     /// scheduled on this queue yet)
-    EventQueue *queue;
+    EventQueue *_queue;
 
-    Event *next;
-
-    Tick _when;        //!< timestamp when event should be processed
-    int _priority;     //!< event priority
-    char _flags;
+    Tick _when;                //!< timestamp when event should be processed
+    short _priority;   //!< event priority
+    short _flags;
 
   protected:
     enum Flags {
@@ -112,26 +129,20 @@ class Event : public Serializable, publi
     void clearFlags(Flags f) { _flags &= ~f; }
 
   protected:
-    EventQueue *theQueue() const { return queue; }
+    EventQueue *queue() const { return _queue; }
 
-#if TRACING_ON
-    Tick when_created; //!< Keep track of creation time For debugging
-    Tick when_scheduled;       //!< Keep track of creation time For debugging
-
+    // This function isn't really useful if TRACING_ON is not defined
     virtual void trace(const char *action);    //!< trace event activity
-#else
-    void trace(const char *) {}
-#endif
-
-    unsigned annotated_value;
 
   public:
-
     /// Event priorities, to provide tie-breakers for events scheduled
     /// at the same cycle.  Most events are scheduled at the default
     /// priority; these values are used to control events that need to
     /// be ordered within a cycle.
     enum Priority {
+        /// Minimum priority
+        Minimum_Pri            = SHRT_MIN,
+
         /// If we enable tracing on a particular cycle, do that as the
         /// very first thing so we don't miss any of the events on
         /// that cycle (even if we enter the debugger).
@@ -174,7 +185,10 @@ class Event : public Serializable, publi
 
         /// If we want to exit on this cycle, it's the very last thing
         /// we do.
-        Sim_Exit_Pri           =  100
+        Sim_Exit_Pri           =  100,
+
+        /// Maximum priority
+        Maximum_Pri            = SHRT_MAX
     };
 
     /*
@@ -182,26 +196,50 @@ class Event : public Serializable, publi
      * @param queue that the event gets scheduled on
      */
     Event(EventQueue *q, Priority p = Default_Pri)
-        : queue(q), next(NULL), _priority(p), _flags(None),
+        : next(NULL), _queue(q), _priority(p), _flags(None)
+    {
 #if TRACING_ON
-          when_created(curTick), when_scheduled(0),
-#endif
-          annotated_value(0)
-    {
-#ifndef NDEBUG
-        instanceId = ++instanceCounter;
+        debug = new Debug;
 #endif
     }
 
-    ~Event() {}
+    ~Event()
+    {
+#if TRACING_ON
+        delete debug;
+#endif
+    }
 
-    virtual const std::string name() const {
-#ifndef NDEBUG
-        return csprintf("Event_%d", instanceId);
+    virtual const std::string
+    name() const
+    {
+#if TRACING_ON
+        return csprintf("Event_%d", debug->instance);
 #else
         return csprintf("Event_%x", (uintptr_t)this);
 #endif
     }
+
+    /// Return a C string describing the event.  This string should
+    /// *not* be dynamically allocated; just a const char array
+    /// describing the event class.
+    virtual const char *description() const;
+
+    /// Dump the current event data
+    void dump() const;
+
+  public:
+    /*
+     * This member function is invoked when the event is processed
+     * (occurs).  There is no default implementation; each subclass
+     * must provide its own implementation.  The event is not
+     * automatically deleted after it is processed (to allow for
+     * statically allocated event objects).
+     *
+     * If the AutoDestroy flag is set, the object is deleted once it
+     * is processed.
+     */
+    virtual void process() = 0;
 
     /// Determine if the current event is scheduled
     bool scheduled() const { return getFlags(Scheduled); }
@@ -216,37 +254,14 @@ class Event : public Serializable, publi
     /// Remove the event from the current schedule
     void deschedule();
 
-    /// Return a C string describing the event.  This string should
-    /// *not* be dynamically allocated; just a const char array
-    /// describing the event class.
-    virtual const char *description() const;
-
-    /// Dump the current event data
-    void dump();
-
-    /*
-     * This member function is invoked when the event is processed
-     * (occurs).  There is no default implementation; each subclass
-     * must provide its own implementation.  The event is not
-     * automatically deleted after it is processed (to allow for
-     * statically allocated event objects).
-     *
-     * If the AutoDestroy flag is set, the object is deleted once it
-     * is processed.
-     */
-    virtual void process() = 0;
-
-    void annotate(unsigned value) { annotated_value = value; };
-    unsigned annotation() { return annotated_value; }
-
     /// Squash the current event
     void squash() { setFlags(Squashed); }
 
     /// Check whether the event is squashed
-    bool squashed() { return getFlags(Squashed); }
+    bool squashed() const { return getFlags(Squashed); }
 
     /// See if this is a SimExitEvent (without resorting to RTTI)
-    bool isExitEvent() { return getFlags(IsExitEvent); }
+    bool isExitEvent() const { return getFlags(IsExitEvent); }
 
     /// Get the time that the event is scheduled
     Tick when() const { return _when; }
@@ -254,10 +269,12 @@ class Event : public Serializable, publi
     /// Get the event priority
     int priority() const { return _priority; }
 
-    struct priority_compare :
-    public std::binary_function<Event *, Event *, bool>
+    struct priority_compare
+        : public std::binary_function<Event *, Event *, bool>
     {
-        bool operator()(const Event *l, const Event *r) const {
+        bool
+        operator()(const Event *l, const Event *r) const
+        {
             return l->when() >= r->when() || l->priority() >= r->priority();
         }
     };
@@ -343,13 +360,15 @@ class EventQueue : public Serializable
     void deschedule(Event *ev);
     void reschedule(Event *ev);
 
-    Tick nextTick() { return head->when(); }
+    Tick nextTick() const { return head->when(); }
     Event *serviceOne();
 
     // process all events up to the given timestamp.  we inline a
     // quick test to see if there are any events to process; if so,
     // call the internal out-of-line version to process them all.
-    void serviceEvents(Tick when) {
+    void
+    serviceEvents(Tick when)
+    {
         while (!empty()) {
             if (nextTick() > when)
                 break;
@@ -367,9 +386,9 @@ class EventQueue : public Serializable
     void serviceEvents() { serviceEvents(curTick); }
 
     // return true if no events are queued
-    bool empty() { return head == NULL; }
+    bool empty() const { return head == NULL; }
 
-    void dump();
+    void dump() const;
 
     Tick nextEventTime() { return empty() ? curTick : head->when(); }
 
@@ -393,15 +412,14 @@ Event::schedule(Tick t)
 Event::schedule(Tick t)
 {
     assert(!scheduled());
-//    if (t < curTick)
-//        warn("t is less than curTick, ensure you don't want cycles");
+    assert(t >= curTick);
 
     setFlags(Scheduled);
 #if TRACING_ON
-    when_scheduled = curTick;
+    debug->scheduled = curTick;
 #endif
     _when = t;
-    queue->schedule(this);
+    _queue->schedule(this);
 }
 
 inline void
@@ -411,25 +429,26 @@ Event::deschedule()
 
     clearFlags(Squashed);
     clearFlags(Scheduled);
-    queue->deschedule(this);
+    _queue->deschedule(this);
 }
 
 inline void
 Event::reschedule(Tick t, bool always)
 {
     assert(scheduled() || always);
+    assert(t >= curTick);
 
 #if TRACING_ON
-    when_scheduled = curTick;
+    debug->scheduled = curTick;
 #endif
     _when = t;
 
     if (scheduled()) {
         clearFlags(Squashed);
-        queue->reschedule(this);
+        _queue->reschedule(this);
     } else {
         setFlags(Scheduled);
-        queue->schedule(this);
+        _queue->schedule(this);
     }
 }
 
@@ -447,6 +466,9 @@ EventQueue::deschedule(Event *event)
     remove(event);
     if (DTRACE(Event))
         event->trace("descheduled");
+
+    if (event->getFlags(Event::AutoDelete))
+        delete event;
 }
 
 inline void
@@ -458,6 +480,4 @@ EventQueue::reschedule(Event *event)
         event->trace("rescheduled");
 }
 
-
-
 #endif // __SIM_EVENTQ_HH__
diff --git a/src/sim/sim_events.cc b/src/sim/sim_events.cc
--- a/src/sim/sim_events.cc
+++ b/src/sim/sim_events.cc
@@ -49,7 +49,7 @@ SimLoopExitEvent::process()
     // if this got scheduled on a different queue (e.g. the committed
     // instruction queue) then make a corresponding event on the main
     // queue.
-    if (theQueue() != &mainEventQueue) {
+    if (queue() != &mainEventQueue) {
         exitSimLoop(cause, code);
         delete this;
     }
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to