From 41e4bf5db7580db8895fbbf5488bda51a3c04f5b Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Thu, 30 Apr 2020 02:35:46 -0700 Subject: [PATCH] misc,sim: Tagged API methods and variables in eventq.hh Change-Id: I76018d4aa08f9bd42a152ec7e0222a0385d3b895 Issue-on: https://gem5.atlassian.net/browse/GEM5-172 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28388 Tested-by: kokoro Reviewed-by: Bobby R. Bruce Maintainer: Bobby R. Bruce --- src/doxygen/group_definitions.hh | 6 + src/sim/eventq.hh | 320 ++++++++++++++++++++++++++----- 2 files changed, 276 insertions(+), 50 deletions(-) diff --git a/src/doxygen/group_definitions.hh b/src/doxygen/group_definitions.hh index e8a1cd903..c0599bb45 100644 --- a/src/doxygen/group_definitions.hh +++ b/src/doxygen/group_definitions.hh @@ -9,3 +9,9 @@ * * These methods related to the "Serialize" interface. */ + +/** + * @defgroup api_eventq The Event Queue API. + * + * These methods relate to the event queue interface. + */ diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index 2976e11cb..522b394f7 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -111,6 +111,9 @@ class EventBase static const FlagsType InitMask = 0xffc0; // mask for init bits public: + /** + * @ingroup api_eventq + */ typedef int8_t Priority; /// Event priorities, to provide tie-breakers for events scheduled @@ -118,61 +121,117 @@ class EventBase /// priority; these values are used to control events that need to /// be ordered within a cycle. - /// Minimum priority + /** + * Minimum priority + * + * @ingroup api_eventq + */ static const Priority Minimum_Pri = SCHAR_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). + /** + * 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). + * + * @ingroup api_eventq + */ static const Priority Debug_Enable_Pri = -101; - /// Breakpoints should happen before anything else (except - /// enabling trace output), so we don't miss any action when - /// debugging. + /** + * Breakpoints should happen before anything else (except + * enabling trace output), so we don't miss any action when + * debugging. + * + * @ingroup api_eventq + */ static const Priority Debug_Break_Pri = -100; - /// CPU switches schedule the new CPU's tick event for the - /// same cycle (after unscheduling the old CPU's tick event). - /// The switch needs to come before any tick events to make - /// sure we don't tick both CPUs in the same cycle. + /** + * CPU switches schedule the new CPU's tick event for the + * same cycle (after unscheduling the old CPU's tick event). + * The switch needs to come before any tick events to make + * sure we don't tick both CPUs in the same cycle. + * + * @ingroup api_eventq + */ static const Priority CPU_Switch_Pri = -31; - /// For some reason "delayed" inter-cluster writebacks are - /// scheduled before regular writebacks (which have default - /// priority). Steve? + /** + * For some reason "delayed" inter-cluster writebacks are + * scheduled before regular writebacks (which have default + * priority). Steve? + * + * @ingroup api_eventq + */ static const Priority Delayed_Writeback_Pri = -1; - /// Default is zero for historical reasons. + /** + * Default is zero for historical reasons. + * + * @ingroup api_eventq + */ static const Priority Default_Pri = 0; - /// DVFS update event leads to stats dump therefore given a lower priority - /// to ensure all relevant states have been updated + /** + * DVFS update event leads to stats dump therefore given a lower priority + * to ensure all relevant states have been updated + * + * @ingroup api_eventq + */ static const Priority DVFS_Update_Pri = 31; - /// Serailization needs to occur before tick events also, so - /// that a serialize/unserialize is identical to an on-line - /// CPU switch. + /** + * Serailization needs to occur before tick events also, so + * that a serialize/unserialize is identical to an on-line + * CPU switch. + * + * @ingroup api_eventq + */ static const Priority Serialize_Pri = 32; - /// CPU ticks must come after other associated CPU events - /// (such as writebacks). + /** + * CPU ticks must come after other associated CPU events + * (such as writebacks). + * + * @ingroup api_eventq + */ static const Priority CPU_Tick_Pri = 50; - /// If we want to exit a thread in a CPU, it comes after CPU_Tick_Pri + /** + * If we want to exit a thread in a CPU, it comes after CPU_Tick_Pri + * + * @ingroup api_eventq + */ static const Priority CPU_Exit_Pri = 64; - /// Statistics events (dump, reset, etc.) come after - /// everything else, but before exit. + /** + * Statistics events (dump, reset, etc.) come after + * everything else, but before exit. + * + * @ingroup api_eventq + */ static const Priority Stat_Event_Pri = 90; - /// Progress events come at the end. + /** + * Progress events come at the end. + * + * @ingroup api_eventq + */ static const Priority Progress_Event_Pri = 95; - /// If we want to exit on this cycle, it's the very last thing - /// we do. + /** + * If we want to exit on this cycle, it's the very last thing + * we do. + * + * @ingroup api_eventq + */ static const Priority Sim_Exit_Pri = 100; - /// Maximum priority + /** + * Maximum priority + * + * @ingroup api_eventq + */ static const Priority Maximum_Pri = SCHAR_MAX; }; @@ -246,7 +305,6 @@ class Event : public EventBase, public Serializable } protected: - /// Accessor for flags. Flags getFlags() const { @@ -260,7 +318,6 @@ class Event : public EventBase, public Serializable return flags.isSet(_flags); } - /// Accessor for flags. void setFlags(Flags _flags) { @@ -281,7 +338,11 @@ class Event : public EventBase, public Serializable flags.clear(PublicWrite); } - // This function isn't really useful if TRACING_ON is not defined + /** + * This function isn't really useful if TRACING_ON is not defined + * + * @ingroup api_eventq + */ virtual void trace(const char *action); //!< trace event activity /// Return the instance number as a string. @@ -341,6 +402,8 @@ class Event : public EventBase, public Serializable /* * Event constructor * @param queue that the event gets scheduled on + * + * @ingroup api_eventq */ Event(Priority p = Default_Pri, Flags f = 0) : nextBin(nullptr), nextInBin(nullptr), _when(0), _priority(p), @@ -357,6 +420,10 @@ class Event : public EventBase, public Serializable #endif } + /** + * @ingroup api_eventq + * @{ + */ virtual ~Event(); virtual const std::string name() const; @@ -367,6 +434,7 @@ class Event : public EventBase, public Serializable /// Dump the current event data void dump() const; + /** @}*/ //end of api group public: /* @@ -378,29 +446,63 @@ class Event : public EventBase, public Serializable * * If the AutoDestroy flag is set, the object is deleted once it * is processed. + * + * @ingroup api_eventq */ virtual void process() = 0; - /// Determine if the current event is scheduled + /** + * Determine if the current event is scheduled + * + * @ingroup api_eventq + */ bool scheduled() const { return flags.isSet(Scheduled); } - /// Squash the current event + /** + * Squash the current event + * + * @ingroup api_eventq + */ void squash() { flags.set(Squashed); } - /// Check whether the event is squashed + /** + * Check whether the event is squashed + * + * @ingroup api_eventq + */ bool squashed() const { return flags.isSet(Squashed); } - /// See if this is a SimExitEvent (without resorting to RTTI) + /** + * See if this is a SimExitEvent (without resorting to RTTI) + * + * @ingroup api_eventq + */ bool isExitEvent() const { return flags.isSet(IsExitEvent); } - /// Check whether this event will auto-delete + /** + * Check whether this event will auto-delete + * + * @ingroup api_eventq + */ bool isManaged() const { return flags.isSet(Managed); } + + /** + * @ingroup api_eventq + */ bool isAutoDelete() const { return isManaged(); } - /// Get the time that the event is scheduled + /** + * Get the time that the event is scheduled + * + * @ingroup api_eventq + */ Tick when() const { return _when; } - /// Get the event priority + /** + * Get the event priority + * + * @ingroup api_eventq + */ Priority priority() const { return _priority; } //! If this is part of a GlobalEvent, return the pointer to the @@ -412,6 +514,9 @@ class Event : public EventBase, public Serializable void unserialize(CheckpointIn &cp) override; }; +/** + * @ingroup api_eventq + */ inline bool operator<(const Event &l, const Event &r) { @@ -419,6 +524,9 @@ operator<(const Event &l, const Event &r) (l.when() == r.when() && l.priority() < r.priority()); } +/** + * @ingroup api_eventq + */ inline bool operator>(const Event &l, const Event &r) { @@ -426,12 +534,19 @@ operator>(const Event &l, const Event &r) (l.when() == r.when() && l.priority() > r.priority()); } +/** + * @ingroup api_eventq + */ inline bool operator<=(const Event &l, const Event &r) { return l.when() < r.when() || (l.when() == r.when() && l.priority() <= r.priority()); } + +/** + * @ingroup api_eventq + */ inline bool operator>=(const Event &l, const Event &r) { @@ -439,12 +554,18 @@ operator>=(const Event &l, const Event &r) (l.when() == r.when() && l.priority() >= r.priority()); } +/** + * @ingroup api_eventq + */ inline bool operator==(const Event &l, const Event &r) { return l.when() == r.when() && l.priority() == r.priority(); } +/** + * @ingroup api_eventq + */ inline bool operator!=(const Event &l, const Event &r) { @@ -552,6 +673,9 @@ class EventQueue class ScopedMigration { public: + /** + * @ingroup api_eventq + */ ScopedMigration(EventQueue *_new_eq, bool _doMigrate = true) :new_eq(*_new_eq), old_eq(*curEventQueue()), doMigrate((&new_eq != &old_eq)&&_doMigrate) @@ -590,6 +714,9 @@ class EventQueue class ScopedRelease { public: + /** + * @group api_eventq + */ ScopedRelease(EventQueue *_eq) : eq(*_eq) { @@ -605,33 +732,71 @@ class EventQueue EventQueue &eq; }; + /** + * @ingroup api_eventq + */ EventQueue(const std::string &n); + /** + * @ingroup api_eventq + * @{ + */ virtual const std::string name() const { return objName; } void name(const std::string &st) { objName = st; } + /** @}*/ //end of api_eventq group - //! Schedule the given event on this queue. Safe to call from any - //! thread. + /** + * Schedule the given event on this queue. Safe to call from any thread. + * + * @ingroup api_eventq + */ void schedule(Event *event, Tick when, bool global = false); - //! Deschedule the specified event. Should be called only from the - //! owning thread. + /** + * Deschedule the specified event. Should be called only from the owning + * thread. + * @ingroup api_eventq + */ void deschedule(Event *event); - //! Reschedule the specified event. Should be called only from - //! the owning thread. + /** + * Reschedule the specified event. Should be called only from the owning + * thread. + * + * @ingroup api_eventq + */ void reschedule(Event *event, Tick when, bool always = false); Tick nextTick() const { return head->when(); } void setCurTick(Tick newVal) { _curTick = newVal; } + + /** + * While curTick() is useful for any object assigned to this event queue, + * if an object that is assigned to another event queue (or a non-event + * object) need to access the current tick of this event queue, this + * function is used. + * + * @return Tick The current tick of this event queue. + * @ingroup api_eventq + */ Tick getCurTick() const { return _curTick; } Event *getHead() const { return head; } 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. + /** + * 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. + * + * Notes: + * - This is only used for "instruction" event queues. Instead of counting + * ticks, this is actually counting instructions. + * - This updates the current tick value to the value of the entry at the + * head of the queue. + * + * @ingroup api_eventq + */ void serviceEvents(Tick when) { @@ -650,14 +815,26 @@ class EventQueue setCurTick(when); } - // return true if no events are queued + /** + * Returns true if no events are queued + * + * @ingroup api_eventq + */ bool empty() const { return head == NULL; } + /** + * This is a debugging function which will print everything on the event + * queue. + * + * @ingroup api_eventq + */ void dump() const; bool debugVerify() const; - //! Function for moving events from the async_queue to the main queue. + /** + * Function for moving events from the async_queue to the main queue. + */ void handleAsyncInsertions(); /** @@ -672,6 +849,8 @@ class EventQueue * 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. + * + * @ingroup api_eventq */ virtual void wakeup(Tick when = (Tick)-1) { } @@ -730,52 +909,81 @@ class EventManager EventQueue *eventq; public: + /** + * @ingroup api_eventq + * @{ + */ EventManager(EventManager &em) : eventq(em.eventq) {} EventManager(EventManager *em) : eventq(em->eventq) {} EventManager(EventQueue *eq) : eventq(eq) {} + /** @}*/ //end of api_eventq group + /** + * @ingroup api_eventq + */ EventQueue * eventQueue() const { return eventq; } + /** + * @ingroup api_eventq + */ void schedule(Event &event, Tick when) { eventq->schedule(&event, when); } + /** + * @ingroup api_eventq + */ void deschedule(Event &event) { eventq->deschedule(&event); } + /** + * @ingroup api_eventq + */ void reschedule(Event &event, Tick when, bool always = false) { eventq->reschedule(&event, when, always); } + /** + * @ingroup api_eventq + */ void schedule(Event *event, Tick when) { eventq->schedule(event, when); } + /** + * @ingroup api_eventq + */ void deschedule(Event *event) { eventq->deschedule(event); } + /** + * @ingroup api_eventq + */ void reschedule(Event *event, Tick when, bool always = false) { eventq->reschedule(event, when, always); } + /** + * @ingroup api_eventq + */ void wakeupEventQueue(Tick when = (Tick)-1) { eventq->wakeup(when); @@ -823,6 +1031,9 @@ class EventFunctionWrapper : public Event std::string _name; public: + /** + * @ingroup api_eventq + */ EventFunctionWrapper(const std::function &callback, const std::string &name, bool del = false, @@ -833,14 +1044,23 @@ class EventFunctionWrapper : public Event setFlags(AutoDelete); } + /** + * @ingroup api_eventq + */ void process() { callback(); } + /** + * @ingroup api_eventq + */ const std::string name() const { return _name + ".wrapped_function_event"; } + /** + * @ingroup api_eventq + */ const char *description() const { return "EventFunctionWrapped"; } }; -- 2.30.2