sim: Define a new MemberEventWrapper event class

This new event class simplifies the use of EventWrapper and aims at
superseeding it. EventWrapper has been redefined in terms of
MemberEventWrapper.

MemberEventWrapper makes use of the new type traits to simplify
template parameterization and encourage its use over SimpleEvent that
often wraps a lambda that merely calls a member function.

Change-Id: Ie59e4c51705b9c2b2faa27097678d7d85f5b99c6
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67653
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Maintainer: Daniel Carvalho <odanrc@yahoo.com.br>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
This commit is contained in:
Gabriel Busnot
2023-02-02 16:09:57 +00:00
committed by Gabriel B.
parent 9fe9b2853c
commit 4ec432caa4

View File

@@ -46,7 +46,9 @@
#include "base/debug.hh"
#include "base/flags.hh"
#include "base/named.hh"
#include "base/trace.hh"
#include "base/type_traits.hh"
#include "base/types.hh"
#include "base/uncontended_mutex.hh"
#include "debug/Event.hh"
@@ -1071,38 +1073,64 @@ class EventManager
void setCurTick(Tick newVal) { eventq->setCurTick(newVal); }
};
template <class T, void (T::* F)()>
class EventWrapper : public Event
/**
* @brief Wrap a member function inside MemberEventWrapper to use it as an
* event callback. This wrapper should be prefered over EventFunctionWrapper
* for better performance and type safety.
*
* Wrapping a function *process* member of a class *klass* can be done by
* adding a member variable of the following type:
* MemberEventWrapper<&klass::process>.
*
* It is required that klass::process takes no explicit argument and returns no
* value as these could not be handled by the event scheduler.
*
* @tparam F Pointer to the member function wrapped in this event.
*/
template <auto F>
class MemberEventWrapper final: public Event, public Named
{
private:
T *object;
using CLASS = MemberFunctionClass_t<F>;
static_assert(std::is_same_v<void, MemberFunctionReturn_t<F>>);
static_assert(std::is_same_v<MemberFunctionArgsTuple_t<F>, std::tuple<>>);
public:
EventWrapper(T *obj, bool del = false, Priority p = Default_Pri)
: Event(p), object(obj)
public:
MemberEventWrapper(CLASS *object,
bool del = false,
Priority p = Default_Pri):
Event(p),
Named(object->name() + ".wrapped_event"),
mObject(object)
{
if (del)
setFlags(AutoDelete);
gem5_assert(mObject);
if (del) setFlags(AutoDelete);
}
EventWrapper(T &obj, bool del = false, Priority p = Default_Pri)
: Event(p), object(&obj)
{
if (del)
setFlags(AutoDelete);
/**
* @brief Construct a new MemberEventWrapper object
*
* @param object instance of the object to call the wrapped member func on
* @param del if true, flag this event as AutoDelete
* @param p priority of this event
*/
MemberEventWrapper(CLASS &object,
bool del = false,
Priority p = Default_Pri):
MemberEventWrapper(&object, del, p)
{}
void process() override {
(mObject->*F)();
}
void process() { (object->*F)(); }
const std::string
name() const
{
return object->name() + ".wrapped_event";
}
const char *description() const { return "EventWrapped"; }
const char *description() const override { return "EventWrapped"; }
private:
CLASS *mObject;
};
template <class T, void (T::* F)()>
using EventWrapper = MemberEventWrapper<F>;
class EventFunctionWrapper : public Event
{
private: