#include <cassert>
#include <climits>
#include <iosfwd>
+#include <memory>
#include <mutex>
#include <string>
static const FlagsType Squashed = 0x0001; // has been squashed
static const FlagsType Scheduled = 0x0002; // has been scheduled
static const FlagsType AutoDelete = 0x0004; // delete after dispatch
- static const FlagsType AutoSerialize = 0x0008; // must be serialized
+ /**
+ * This used to be AutoSerialize. This value can't be reused
+ * without changing the checkpoint version since the flag field
+ * gets serialized.
+ */
+ static const FlagsType Reserved0 = 0x0008;
static const FlagsType IsExitEvent = 0x0010; // special exit event
static const FlagsType IsMainQueue = 0x0020; // on main event queue
static const FlagsType Initialized = 0x7a40; // somewhat random bits
bool
initialized() const
{
- return this && (flags & InitMask) == Initialized;
+ return (flags & InitMask) == Initialized;
}
protected:
* @param queue that the event gets scheduled on
*/
Event(Priority p = Default_Pri, Flags f = 0)
- : nextBin(NULL), nextInBin(NULL), _priority(p),
+ : nextBin(nullptr), nextInBin(nullptr), _when(0), _priority(p),
flags(Initialized | f)
{
assert(f.noneSet(~PublicWrite));
/// See if this is a SimExitEvent (without resorting to RTTI)
bool isExitEvent() const { return flags.isSet(IsExitEvent); }
+ /// Check whether this event will auto-delete
+ bool isAutoDelete() const { return flags.isSet(AutoDelete); }
+
/// Get the time that the event is scheduled
Tick when() const { return _when; }
virtual BaseGlobalEvent *globalEvent() { return NULL; }
#ifndef SWIG
- virtual void serialize(std::ostream &os);
- virtual void unserialize(Checkpoint *cp, const std::string §ion);
-
- //! This function is required to support restoring from checkpoints
- //! when running with multiple queues. Since we still have not thrashed
- //! out all the details on checkpointing, this function is most likely
- //! to be revisited in future.
- virtual void unserialize(Checkpoint *cp, const std::string §ion,
- EventQueue *eventq);
+ void serialize(CheckpointOut &cp) const override;
+ void unserialize(CheckpointIn &cp) override;
#endif
};
* otherwise they risk being scheduled in the past by
* handleAsyncInsertions().
*/
-class EventQueue : public Serializable
+class EventQueue
{
private:
std::string objName;
Tick _curTick;
//! Mutex to protect async queue.
- std::mutex *async_queue_mutex;
+ std::mutex async_queue_mutex;
//! List of events added by other threads to this event queue.
std::list<Event*> async_queue;
Tick nextTick() const { return head->when(); }
void setCurTick(Tick newVal) { _curTick = newVal; }
- Tick getCurTick() { return _curTick; }
+ Tick getCurTick() const { return _curTick; }
+ Event *getHead() const { return head; }
Event *serviceOne();
//! Function for moving events from the async_queue to the main queue.
void handleAsyncInsertions();
+ /**
+ * Function to signal that the event loop should be woken up because
+ * an event has been scheduled by an agent outside the gem5 event
+ * loop(s) whose event insertion may not have been noticed by gem5.
+ * This function isn't needed by the usual gem5 event loop but may
+ * be necessary in derived EventQueues which host gem5 onto other
+ * schedulers.
+ *
+ * @param when Time of a delayed wakeup (if known). This parameter
+ * can be used by an implementation to schedule a wakeup in the
+ * future if it is sure it will remain active until then.
+ * Or it can be ignored and the event queue can be woken up now.
+ */
+ virtual void wakeup(Tick when = (Tick)-1) { }
+
/**
* function for replacing the head of the event queue, so that a
* different set of events can run without disturbing events that have
void unlock() { service_mutex.unlock(); }
/**@}*/
-#ifndef SWIG
- virtual void serialize(std::ostream &os);
- virtual void unserialize(Checkpoint *cp, const std::string §ion);
-#endif
+ /**
+ * Reschedule an event after a checkpoint.
+ *
+ * Since events don't know which event queue they belong to,
+ * parent objects need to reschedule events themselves. This
+ * method conditionally schedules an event that has the Scheduled
+ * flag set. It should be called by parent objects after
+ * unserializing an object.
+ *
+ * @warn Only use this method after unserializing an Event.
+ */
+ void checkpointReschedule(Event *event);
+
+ virtual ~EventQueue() { }
};
void dumpMainQueue();
eventq->reschedule(event, when, always);
}
+ void wakeupEventQueue(Tick when = (Tick)-1)
+ {
+ eventq->wakeup(when);
+ }
+
void setCurTick(Tick newVal) { eventq->setCurTick(newVal); }
};