dev: Replace EventWrapper use with EventFunctionWrapper

Change-Id: I6b03cc6f67e76dffb79940431711ae6171901c6a
Signed-off-by: Sean Wilson <spwilson2@wisc.edu>
Reviewed-on: https://gem5-review.googlesource.com/3748
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
diff --git a/src/dev/arm/ufs_device.cc b/src/dev/arm/ufs_device.cc
index 5a5a132..cd1bbca 100644
--- a/src/dev/arm/ufs_device.cc
+++ b/src/dev/arm/ufs_device.cc
@@ -733,8 +733,8 @@
     transferTrack(0),
     taskCommandTrack(0),
     idlePhaseStart(0),
-    SCSIResumeEvent(this),
-    UTPEvent(this)
+    SCSIResumeEvent([this]{ SCSIStart(); }, name()),
+    UTPEvent([this]{ finalUTP(); }, name())
 {
     DPRINTF(UFSHostDevice, "The hostcontroller hosts %d Logic units\n",
             lunAvail);
@@ -1280,7 +1280,8 @@
             task_info.size = size;
             task_info.done = UFSHCIMem.TMUTMRLDBR;
             taskInfo.push_back(task_info);
-            taskEventQueue.push_back(this);
+            taskEventQueue.push_back(
+                EventFunctionWrapper([this]{ taskStart(); }, name()));
             writeDevice(&taskEventQueue.back(), false, address, size,
                         reinterpret_cast<uint8_t*>
                         (&taskInfo.back().destination), 0, 0);
@@ -1328,7 +1329,8 @@
                 UTPTransferReqDesc;
             DPRINTF(UFSHostDevice, "Initial transfer start: 0x%8x\n",
                     transferstart_info.done);
-            transferEventQueue.push_back(this);
+            transferEventQueue.push_back(
+                EventFunctionWrapper([this]{ transferStart(); }, name()));
 
             if (transferEventQueue.size() < 2) {
                 writeDevice(&transferEventQueue.front(), false,
@@ -2260,7 +2262,8 @@
         UFSDevice[this_lun]->clearReadSignal();
         SSDReadPending.push_back(UFSDevice[this_lun]->SSDReadInfo.front());
         UFSDevice[this_lun]->SSDReadInfo.pop_front();
-        readGarbageEventQueue.push_back(this);
+        readGarbageEventQueue.push_back(
+            EventFunctionWrapper([this]{ readGarbage(); }, name()));
 
         //make sure the queue is popped a the end of the dma transaction
         readDevice(false, SSDReadPending.front().offset,
diff --git a/src/dev/arm/ufs_device.hh b/src/dev/arm/ufs_device.hh
index 24a05b0..69abc27 100644
--- a/src/dev/arm/ufs_device.hh
+++ b/src/dev/arm/ufs_device.hh
@@ -1150,28 +1150,25 @@
     /**
      * Wait for the SCSI specific data to arive
      */
-    EventWrapper<UFSHostDevice, &UFSHostDevice::SCSIStart> SCSIResumeEvent;
+    EventFunctionWrapper SCSIResumeEvent;
 
     /**
      * Wait for the moment where we can send the last frame
      */
-    EventWrapper<UFSHostDevice, &UFSHostDevice::finalUTP> UTPEvent;
+    EventFunctionWrapper UTPEvent;
 
     /**
      * Event after a read to clean up the UTP data structures
      */
-    std::deque<EventWrapper<UFSHostDevice, &UFSHostDevice::readGarbage> >
-    readGarbageEventQueue;
+    std::deque<EventFunctionWrapper> readGarbageEventQueue;
 
     /**
      * Multiple tasks transfers can be scheduled at once for the device, the
      * only thing we know for sure about them is that they will happen in a
      * first come first serve order; hence we need to queue.
      */
-    std::deque<EventWrapper<UFSHostDevice, &UFSHostDevice::taskStart> >
-    taskEventQueue;
-    std::deque<EventWrapper<UFSHostDevice, &UFSHostDevice::transferStart> >
-    transferEventQueue;
+    std::deque<EventFunctionWrapper> taskEventQueue;
+    std::deque<EventFunctionWrapper> transferEventQueue;
 
     /**
      * Bits of interest within UFS data packages
diff --git a/src/dev/dma_device.cc b/src/dev/dma_device.cc
index f84b4c3..a78819a 100644
--- a/src/dev/dma_device.cc
+++ b/src/dev/dma_device.cc
@@ -56,7 +56,8 @@
 DmaPort::DmaPort(MemObject *dev, System *s)
     : MasterPort(dev->name() + ".dma", dev),
       device(dev), sys(s), masterId(s->getMasterId(dev->name())),
-      sendEvent(this), pendingCount(0), inRetry(false)
+      sendEvent([this]{ sendDma(); }, dev->name()),
+      pendingCount(0), inRetry(false)
 { }
 
 void
diff --git a/src/dev/dma_device.hh b/src/dev/dma_device.hh
index 4a1946a..f354d38 100644
--- a/src/dev/dma_device.hh
+++ b/src/dev/dma_device.hh
@@ -123,7 +123,7 @@
     std::deque<PacketPtr> transmitList;
 
     /** Event used to schedule a future sending from the transmit list. */
-    EventWrapper<DmaPort, &DmaPort::sendDma> sendEvent;
+    EventFunctionWrapper sendEvent;
 
     /** Number of outstanding packets the dma port has. */
     uint32_t pendingCount;
diff --git a/src/dev/net/dist_etherlink.hh b/src/dev/net/dist_etherlink.hh
index e821894..83f28f2 100644
--- a/src/dev/net/dist_etherlink.hh
+++ b/src/dev/net/dist_etherlink.hh
@@ -118,15 +118,13 @@
          * Send done callback. Called from doneEvent.
          */
         void txDone();
-        typedef EventWrapper<TxLink, &TxLink::txDone> DoneEvent;
-        friend void DoneEvent::process();
-        DoneEvent doneEvent;
+        EventFunctionWrapper doneEvent;
 
       public:
         TxLink(const std::string &name, DistEtherLink *p,
                double invBW, Tick delay_var, EtherDump *d) :
             Link(name, p, d, &doneEvent), ticksPerByte(invBW),
-            delayVar(delay_var), doneEvent(this) {}
+            delayVar(delay_var), doneEvent([this]{ txDone(); }, name) {}
         ~TxLink() {}
 
         /**
@@ -159,16 +157,14 @@
          * Receive done callback method. Called from doneEvent.
          */
         void rxDone();
-        typedef EventWrapper<RxLink, &RxLink::rxDone> DoneEvent;
-        friend void DoneEvent::process();
-        DoneEvent _doneEvent;
+        EventFunctionWrapper _doneEvent;
 
       public:
 
         RxLink(const std::string &name, DistEtherLink *p,
                Tick delay, EtherDump *d) :
-            Link(name, p, d, &_doneEvent),
-            linkDelay(delay), _doneEvent(this) {}
+            Link(name, p, d, &_doneEvent), linkDelay(delay),
+            _doneEvent([this]{ rxDone(); }, name) {}
         ~RxLink() {}
 
         /**
@@ -178,7 +174,7 @@
         /**
          * Done events will be scheduled by DistIface (so we need the accessor)
          */
-        const DoneEvent *doneEvent() const { return &_doneEvent; }
+        const EventFunctionWrapper *doneEvent() const { return &_doneEvent; }
     };
 
     /**
diff --git a/src/dev/net/etherlink.cc b/src/dev/net/etherlink.cc
index 0975ba4..9a11018 100644
--- a/src/dev/net/etherlink.cc
+++ b/src/dev/net/etherlink.cc
@@ -116,7 +116,8 @@
                       double rate, Tick delay, Tick delay_var, EtherDump *d)
     : objName(name), parent(p), number(num), txint(NULL), rxint(NULL),
       ticksPerByte(rate), linkDelay(delay), delayVar(delay_var), dump(d),
-      doneEvent(this), txQueueEvent(this)
+      doneEvent([this]{ txDone(); }, name),
+      txQueueEvent([this]{ processTxQueue(); }, name)
 { }
 
 void
diff --git a/src/dev/net/etherlink.hh b/src/dev/net/etherlink.hh
index 1d02dec..7a98708 100644
--- a/src/dev/net/etherlink.hh
+++ b/src/dev/net/etherlink.hh
@@ -92,9 +92,7 @@
          */
         EthPacketPtr packet;
         void txDone();
-        typedef EventWrapper<Link, &Link::txDone> DoneEvent;
-        friend void DoneEvent::process();
-        DoneEvent doneEvent;
+        EventFunctionWrapper doneEvent;
 
         /**
          * Maintain a queue of in-flight packets. Assume that the
@@ -104,9 +102,7 @@
         std::deque<std::pair<Tick, EthPacketPtr>> txQueue;
 
         void processTxQueue();
-        typedef EventWrapper<Link, &Link::processTxQueue> TxQueueEvent;
-        friend void TxQueueEvent::process();
-        TxQueueEvent txQueueEvent;
+        EventFunctionWrapper txQueueEvent;
 
         void txComplete(EthPacketPtr packet);
 
diff --git a/src/dev/net/etherswitch.cc b/src/dev/net/etherswitch.cc
index 995e29a..0e1d6f3 100644
--- a/src/dev/net/etherswitch.cc
+++ b/src/dev/net/etherswitch.cc
@@ -131,7 +131,8 @@
                                   Tick delay_var, double rate, unsigned id)
     : EtherInt(name), ticksPerByte(rate), switchDelay(delay),
       delayVar(delay_var), interfaceId(id), parent(etherSwitch),
-      outputFifo(name + ".outputFifo", outputBufferSize), txEvent(this)
+      outputFifo(name + ".outputFifo", outputBufferSize),
+      txEvent([this]{ transmit(); }, name)
 {
 }
 
diff --git a/src/dev/net/etherswitch.hh b/src/dev/net/etherswitch.hh
index debe331..0887d94 100644
--- a/src/dev/net/etherswitch.hh
+++ b/src/dev/net/etherswitch.hh
@@ -172,7 +172,7 @@
          */
         PortFifo outputFifo;
         void transmit();
-        EventWrapper<Interface, &Interface::transmit> txEvent;
+        EventFunctionWrapper txEvent;
     };
 
     struct SwitchTableEntry {
diff --git a/src/dev/net/i8254xGBe.cc b/src/dev/net/i8254xGBe.cc
index 7437959..3dde72a 100644
--- a/src/dev/net/i8254xGBe.cc
+++ b/src/dev/net/i8254xGBe.cc
@@ -64,8 +64,12 @@
       pktOffset(0), fetchDelay(p->fetch_delay), wbDelay(p->wb_delay),
       fetchCompDelay(p->fetch_comp_delay), wbCompDelay(p->wb_comp_delay),
       rxWriteDelay(p->rx_write_delay), txReadDelay(p->tx_read_delay),
-      rdtrEvent(this), radvEvent(this),
-      tadvEvent(this), tidvEvent(this), tickEvent(this), interEvent(this),
+      rdtrEvent([this]{ rdtrProcess(); }, name()),
+      radvEvent([this]{ radvProcess(); }, name()),
+      tadvEvent([this]{ tadvProcess(); }, name()),
+      tidvEvent([this]{ tidvProcess(); }, name()),
+      tickEvent([this]{ tick(); }, name()),
+      interEvent([this]{ delayIntEvent(); }, name()),
       rxDescCache(this, name()+".RxDesc", p->rx_desc_cache_size),
       txDescCache(this, name()+".TxDesc", p->tx_desc_cache_size),
       lastInterrupt(0)
@@ -825,8 +829,10 @@
 IGbE::DescCache<T>::DescCache(IGbE *i, const std::string n, int s)
     : igbe(i), _name(n), cachePnt(0), size(s), curFetching(0),
       wbOut(0), moreToWb(false), wbAlignment(0), pktPtr(NULL),
-      wbDelayEvent(this), fetchDelayEvent(this), fetchEvent(this),
-      wbEvent(this)
+      wbDelayEvent([this]{ writeback1(); }, n),
+      fetchDelayEvent([this]{ fetchDescriptors1(); }, n),
+      fetchEvent([this]{ fetchComplete(); }, n),
+      wbEvent([this]{ wbComplete(); }, n)
 {
     fetchBuf = new T[size];
     wbBuf = new T[size];
@@ -1197,7 +1203,9 @@
 
 IGbE::RxDescCache::RxDescCache(IGbE *i, const std::string n, int s)
     : DescCache<RxDesc>(i, n, s), pktDone(false), splitCount(0),
-      pktEvent(this), pktHdrEvent(this), pktDataEvent(this)
+    pktEvent([this]{ pktComplete(); }, n),
+    pktHdrEvent([this]{ pktSplitDone(); }, n),
+    pktDataEvent([this]{ pktSplitDone(); }, n)
 
 {
     annSmFetch = "RX Desc Fetch";
@@ -1549,7 +1557,9 @@
       useTso(false), tsoHeaderLen(0), tsoMss(0), tsoTotalLen(0), tsoUsedLen(0),
       tsoPrevSeq(0), tsoPktPayloadBytes(0), tsoLoadedHeader(false),
       tsoPktHasHeader(false), tsoDescBytesUsed(0), tsoCopyBytes(0), tsoPkts(0),
-      pktEvent(this), headerEvent(this), nullEvent(this)
+    pktEvent([this]{ pktComplete(); }, n),
+    headerEvent([this]{ headerComplete(); }, n),
+    nullEvent([this]{ nullCallback(); }, n)
 {
     annSmFetch = "TX Desc Fetch";
     annSmWb = "TX Desc Writeback";
diff --git a/src/dev/net/i8254xGBe.hh b/src/dev/net/i8254xGBe.hh
index 80e2104..402e61d 100644
--- a/src/dev/net/i8254xGBe.hh
+++ b/src/dev/net/i8254xGBe.hh
@@ -98,8 +98,7 @@
         postInterrupt(iGbReg::IT_RXT);
     }
 
-    //friend class EventWrapper<IGbE, &IGbE::rdtrProcess>;
-    EventWrapper<IGbE, &IGbE::rdtrProcess> rdtrEvent;
+    EventFunctionWrapper rdtrEvent;
 
     // Event and function to deal with RADV timer expiring
     void radvProcess() {
@@ -109,8 +108,7 @@
         postInterrupt(iGbReg::IT_RXT);
     }
 
-    //friend class EventWrapper<IGbE, &IGbE::radvProcess>;
-    EventWrapper<IGbE, &IGbE::radvProcess> radvEvent;
+    EventFunctionWrapper radvEvent;
 
     // Event and function to deal with TADV timer expiring
     void tadvProcess() {
@@ -120,8 +118,7 @@
         postInterrupt(iGbReg::IT_TXDW);
     }
 
-    //friend class EventWrapper<IGbE, &IGbE::tadvProcess>;
-    EventWrapper<IGbE, &IGbE::tadvProcess> tadvEvent;
+    EventFunctionWrapper tadvEvent;
 
     // Event and function to deal with TIDV timer expiring
     void tidvProcess() {
@@ -130,13 +127,11 @@
                 "Posting TXDW interrupt because TIDV timer expired\n");
         postInterrupt(iGbReg::IT_TXDW);
     }
-    //friend class EventWrapper<IGbE, &IGbE::tidvProcess>;
-    EventWrapper<IGbE, &IGbE::tidvProcess> tidvEvent;
+    EventFunctionWrapper tidvEvent;
 
     // Main event to tick the device
     void tick();
-    //friend class EventWrapper<IGbE, &IGbE::tick>;
-    EventWrapper<IGbE, &IGbE::tick> tickEvent;
+    EventFunctionWrapper tickEvent;
 
 
     uint64_t macAddr;
@@ -162,7 +157,7 @@
     void delayIntEvent();
     void cpuPostInt();
     // Event to moderate interrupts
-    EventWrapper<IGbE, &IGbE::delayIntEvent> interEvent;
+    EventFunctionWrapper interEvent;
 
     /** Clear the interupt line to the cpu
      */
@@ -284,24 +279,24 @@
 
         void writeback(Addr aMask);
         void writeback1();
-        EventWrapper<DescCache, &DescCache::writeback1> wbDelayEvent;
+        EventFunctionWrapper wbDelayEvent;
 
         /** Fetch a chunk of descriptors into the descriptor cache.
          * Calls fetchComplete when the memory system returns the data
          */
         void fetchDescriptors();
         void fetchDescriptors1();
-        EventWrapper<DescCache, &DescCache::fetchDescriptors1> fetchDelayEvent;
+        EventFunctionWrapper fetchDelayEvent;
 
         /** Called by event when dma to read descriptors is completed
          */
         void fetchComplete();
-        EventWrapper<DescCache, &DescCache::fetchComplete> fetchEvent;
+        EventFunctionWrapper fetchEvent;
 
         /** Called by event when dma to writeback descriptors is completed
          */
         void wbComplete();
-        EventWrapper<DescCache, &DescCache::wbComplete> wbEvent;
+        EventFunctionWrapper wbEvent;
 
         /* Return the number of descriptors left in the ring, so the device has
          * a way to figure out if it needs to interrupt.
@@ -384,13 +379,13 @@
          */
         bool packetDone();
 
-        EventWrapper<RxDescCache, &RxDescCache::pktComplete> pktEvent;
+        EventFunctionWrapper pktEvent;
 
         // Event to handle issuing header and data write at the same time
         // and only callking pktComplete() when both are completed
         void pktSplitDone();
-        EventWrapper<RxDescCache, &RxDescCache::pktSplitDone> pktHdrEvent;
-        EventWrapper<RxDescCache, &RxDescCache::pktSplitDone> pktDataEvent;
+        EventFunctionWrapper pktHdrEvent;
+        EventFunctionWrapper pktDataEvent;
 
         bool hasOutstandingEvents() override;
 
@@ -484,10 +479,10 @@
         /** Called by event when dma to write packet is completed
          */
         void pktComplete();
-        EventWrapper<TxDescCache, &TxDescCache::pktComplete> pktEvent;
+        EventFunctionWrapper pktEvent;
 
         void headerComplete();
-        EventWrapper<TxDescCache, &TxDescCache::headerComplete> headerEvent;
+        EventFunctionWrapper headerEvent;
 
 
         void completionWriteback(Addr a, bool enabled) {
@@ -503,7 +498,7 @@
         void nullCallback() {
             DPRINTF(EthernetDesc, "Completion writeback complete\n");
         }
-        EventWrapper<TxDescCache, &TxDescCache::nullCallback> nullEvent;
+        EventFunctionWrapper nullEvent;
 
         void serialize(CheckpointOut &cp) const override;
         void unserialize(CheckpointIn &cp) override;
diff --git a/src/dev/net/ns_gige.cc b/src/dev/net/ns_gige.cc
index 50bb6ed..dbed29f 100644
--- a/src/dev/net/ns_gige.cc
+++ b/src/dev/net/ns_gige.cc
@@ -111,12 +111,18 @@
       dmaReadFactor(p->dma_read_factor), dmaWriteFactor(p->dma_write_factor),
       rxDmaData(NULL), rxDmaAddr(0), rxDmaLen(0),
       txDmaData(NULL), txDmaAddr(0), txDmaLen(0),
-      rxDmaReadEvent(this), rxDmaWriteEvent(this),
-      txDmaReadEvent(this), txDmaWriteEvent(this),
+      rxDmaReadEvent([this]{ rxDmaReadDone(); }, name()),
+      rxDmaWriteEvent([this]{ rxDmaWriteDone(); }, name()),
+      txDmaReadEvent([this]{ txDmaReadDone(); }, name()),
+      txDmaWriteEvent([this]{ txDmaWriteDone(); }, name()),
       dmaDescFree(p->dma_desc_free), dmaDataFree(p->dma_data_free),
       txDelay(p->tx_delay), rxDelay(p->rx_delay),
-      rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
-      txEvent(this), rxFilterEnable(p->rx_filter),
+      rxKickTick(0),
+      rxKickEvent([this]{ rxKick(); }, name()),
+      txKickTick(0),
+      txKickEvent([this]{ txKick(); }, name()),
+      txEvent([this]{ txEventTransmit(); }, name()),
+      rxFilterEnable(p->rx_filter),
       acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false),
       acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
       intrDelay(p->intr_delay), intrTick(0), cpuPendingIntr(false),
@@ -959,7 +965,9 @@
 
     if (intrEvent)
         intrEvent->squash();
-    intrEvent = new IntrEvent(this, true);
+
+    intrEvent = new EventFunctionWrapper([this]{ cpuInterrupt(); },
+                                         name(), true);
     schedule(intrEvent, intrTick);
 }
 
@@ -2470,7 +2478,8 @@
     Tick intrEventTick;
     UNSERIALIZE_SCALAR(intrEventTick);
     if (intrEventTick) {
-        intrEvent = new IntrEvent(this, true);
+        intrEvent = new EventFunctionWrapper([this]{ cpuInterrupt(); },
+                                             name(), true);
         schedule(intrEvent, intrEventTick);
     }
 }
diff --git a/src/dev/net/ns_gige.hh b/src/dev/net/ns_gige.hh
index 096b2b6..f9be028 100644
--- a/src/dev/net/ns_gige.hh
+++ b/src/dev/net/ns_gige.hh
@@ -256,20 +256,16 @@
     bool  doTxDmaWrite();
 
     void rxDmaReadDone();
-    friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
-    EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
+    EventFunctionWrapper rxDmaReadEvent;
 
     void rxDmaWriteDone();
-    friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
-    EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
+    EventFunctionWrapper rxDmaWriteEvent;
 
     void txDmaReadDone();
-    friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
-    EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
+    EventFunctionWrapper txDmaReadEvent;
 
     void txDmaWriteDone();
-    friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
-    EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
+    EventFunctionWrapper txDmaWriteEvent;
 
     bool dmaDescFree;
     bool dmaDataFree;
@@ -284,15 +280,11 @@
 
     void rxKick();
     Tick rxKickTick;
-    typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
-    friend void RxKickEvent::process();
-    RxKickEvent rxKickEvent;
+    EventFunctionWrapper rxKickEvent;
 
     void txKick();
     Tick txKickTick;
-    typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
-    friend void TxKickEvent::process();
-    TxKickEvent txKickEvent;
+    EventFunctionWrapper txKickEvent;
 
     void eepromKick();
 
@@ -306,9 +298,7 @@
         if (txState == txFifoBlock)
             txKick();
     }
-    typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
-    friend void TxEvent::process();
-    TxEvent txEvent;
+    EventFunctionWrapper txEvent;
 
     void txDump() const;
     void rxDump() const;
@@ -339,9 +329,7 @@
     void cpuInterrupt();
     void cpuIntrClear();
 
-    typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
-    friend void IntrEvent::process();
-    IntrEvent *intrEvent;
+    EventFunctionWrapper *intrEvent;
     NSGigEInt *interface;
 
   public:
diff --git a/src/dev/net/sinic.cc b/src/dev/net/sinic.cc
index e86e1ab..50341a4 100644
--- a/src/dev/net/sinic.cc
+++ b/src/dev/net/sinic.cc
@@ -91,7 +91,9 @@
       virtualRegs(p->virtual_count < 1 ? 1 : p->virtual_count),
       rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size),
       rxKickTick(0), txKickTick(0),
-      txEvent(this), rxDmaEvent(this), txDmaEvent(this),
+      txEvent([this]{ txEventTransmit(); }, name()),
+      rxDmaEvent([this]{ rxDmaDone(); }, name()),
+      txDmaEvent([this]{ txDmaDone(); }, name()),
       dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor),
       dmaWriteDelay(p->dma_write_delay), dmaWriteFactor(p->dma_write_factor)
 {
@@ -535,7 +537,9 @@
 
     if (intrEvent)
         intrEvent->squash();
-    intrEvent = new IntrEvent(this, true);
+
+    intrEvent = new EventFunctionWrapper([this]{ cpuInterrupt(); },
+                                         name(), true);
     schedule(intrEvent, intrTick);
 }
 
@@ -1297,7 +1301,8 @@
     Tick intrEventTick;
     UNSERIALIZE_SCALAR(intrEventTick);
     if (intrEventTick) {
-        intrEvent = new IntrEvent(this, true);
+        intrEvent = new EventFunctionWrapper([this]{ cpuInterrupt(); },
+                                             name(), true);
         schedule(intrEvent, intrEventTick);
     }
 }
diff --git a/src/dev/net/sinic.hh b/src/dev/net/sinic.hh
index b041cb1..70d22f1 100644
--- a/src/dev/net/sinic.hh
+++ b/src/dev/net/sinic.hh
@@ -61,9 +61,7 @@
     void cpuInterrupt();
     void cpuIntrClear();
 
-    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
-    friend void IntrEvent::process();
-    IntrEvent *intrEvent;
+    EventFunctionWrapper *intrEvent;
     Interface *interface;
 
     bool cpuIntrPending() const;
@@ -196,13 +194,9 @@
 
     void rxKick();
     Tick rxKickTick;
-    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
-    friend void RxKickEvent::process();
 
     void txKick();
     Tick txKickTick;
-    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
-    friend void TxKickEvent::process();
 
     /**
      * Retransmit event
@@ -214,9 +208,7 @@
         if (txState == txFifoBlock)
             txKick();
     }
-    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
-    friend void TxEvent::process();
-    TxEvent txEvent;
+    EventFunctionWrapper txEvent;
 
     void txDump() const;
     void rxDump() const;
@@ -245,12 +237,10 @@
  */
   protected:
     void rxDmaDone();
-    friend class EventWrapper<Device, &Device::rxDmaDone>;
-    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
+    EventFunctionWrapper rxDmaEvent;
 
     void txDmaDone();
-    friend class EventWrapper<Device, &Device::txDmaDone>;
-    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
+    EventFunctionWrapper txDmaEvent;
 
     Tick dmaReadDelay;
     Tick dmaReadFactor;
diff --git a/src/dev/pci/copy_engine.cc b/src/dev/pci/copy_engine.cc
index 326c51d..3c7df7d 100644
--- a/src/dev/pci/copy_engine.cc
+++ b/src/dev/pci/copy_engine.cc
@@ -81,12 +81,14 @@
 CopyEngine::CopyEngineChannel::CopyEngineChannel(CopyEngine *_ce, int cid)
     : cePort(_ce, _ce->sys),
       ce(_ce), channelId(cid), busy(false), underReset(false),
-    refreshNext(false), latBeforeBegin(ce->params()->latBeforeBegin),
-    latAfterCompletion(ce->params()->latAfterCompletion),
-    completionDataReg(0), nextState(Idle),
-    fetchCompleteEvent(this), addrCompleteEvent(this),
-    readCompleteEvent(this), writeCompleteEvent(this),
-    statusCompleteEvent(this)
+      refreshNext(false), latBeforeBegin(ce->params()->latBeforeBegin),
+      latAfterCompletion(ce->params()->latAfterCompletion),
+      completionDataReg(0), nextState(Idle),
+      fetchCompleteEvent([this]{ fetchDescComplete(); }, name()),
+      addrCompleteEvent([this]{ fetchAddrComplete(); }, name()),
+      readCompleteEvent([this]{ readCopyBytesComplete(); }, name()),
+      writeCompleteEvent([this]{ writeCopyBytesComplete(); }, name()),
+      statusCompleteEvent([this]{ writeStatusComplete(); }, name())
 
 {
         cr.status.dma_transfer_status(3);
diff --git a/src/dev/pci/copy_engine.hh b/src/dev/pci/copy_engine.hh
index f548c47..1ec29f0 100644
--- a/src/dev/pci/copy_engine.hh
+++ b/src/dev/pci/copy_engine.hh
@@ -115,28 +115,23 @@
       private:
         void fetchDescriptor(Addr address);
         void fetchDescComplete();
-        EventWrapper<CopyEngineChannel, &CopyEngineChannel::fetchDescComplete>
-            fetchCompleteEvent;
+        EventFunctionWrapper fetchCompleteEvent;
 
         void fetchNextAddr(Addr address);
         void fetchAddrComplete();
-        EventWrapper<CopyEngineChannel, &CopyEngineChannel::fetchAddrComplete>
-            addrCompleteEvent;
+        EventFunctionWrapper addrCompleteEvent;
 
         void readCopyBytes();
         void readCopyBytesComplete();
-        EventWrapper<CopyEngineChannel, &CopyEngineChannel::readCopyBytesComplete>
-            readCompleteEvent;
+        EventFunctionWrapper readCompleteEvent;
 
         void writeCopyBytes();
         void writeCopyBytesComplete();
-        EventWrapper <CopyEngineChannel, &CopyEngineChannel::writeCopyBytesComplete>
-            writeCompleteEvent;
+        EventFunctionWrapper writeCompleteEvent;
 
         void writeCompletionStatus();
         void writeStatusComplete();
-        EventWrapper <CopyEngineChannel, &CopyEngineChannel::writeStatusComplete>
-            statusCompleteEvent;
+        EventFunctionWrapper statusCompleteEvent;
 
 
         void continueProcessing();
diff --git a/src/dev/storage/ide_disk.cc b/src/dev/storage/ide_disk.cc
index de0986e..08d374f 100644
--- a/src/dev/storage/ide_disk.cc
+++ b/src/dev/storage/ide_disk.cc
@@ -68,9 +68,14 @@
 
 IdeDisk::IdeDisk(const Params *p)
     : SimObject(p), ctrl(NULL), image(p->image), diskDelay(p->delay),
-      dmaTransferEvent(this), dmaReadCG(NULL), dmaReadWaitEvent(this),
-      dmaWriteCG(NULL), dmaWriteWaitEvent(this), dmaPrdReadEvent(this),
-      dmaReadEvent(this), dmaWriteEvent(this)
+      dmaTransferEvent([this]{ doDmaTransfer(); }, name()),
+      dmaReadCG(NULL),
+      dmaReadWaitEvent([this]{ doDmaRead(); }, name()),
+      dmaWriteCG(NULL),
+      dmaWriteWaitEvent([this]{ doDmaWrite(); }, name()),
+      dmaPrdReadEvent([this]{ dmaPrdReadDone(); }, name()),
+      dmaReadEvent([this]{ dmaReadDone(); }, name()),
+      dmaWriteEvent([this]{ dmaWriteDone(); }, name())
 {
     // Reset the device state
     reset(p->driveID);
diff --git a/src/dev/storage/ide_disk.hh b/src/dev/storage/ide_disk.hh
index 9214599..fa5bb76 100644
--- a/src/dev/storage/ide_disk.hh
+++ b/src/dev/storage/ide_disk.hh
@@ -306,34 +306,28 @@
 
     // DMA stuff
     void doDmaTransfer();
-    friend class EventWrapper<IdeDisk, &IdeDisk::doDmaTransfer>;
-    EventWrapper<IdeDisk, &IdeDisk::doDmaTransfer> dmaTransferEvent;
+    EventFunctionWrapper dmaTransferEvent;
 
     void doDmaDataRead();
 
     void doDmaRead();
     ChunkGenerator *dmaReadCG;
-    friend class EventWrapper<IdeDisk, &IdeDisk::doDmaRead>;
-    EventWrapper<IdeDisk, &IdeDisk::doDmaRead> dmaReadWaitEvent;
+    EventFunctionWrapper dmaReadWaitEvent;
 
     void doDmaDataWrite();
 
     void doDmaWrite();
     ChunkGenerator *dmaWriteCG;
-    friend class EventWrapper<IdeDisk, &IdeDisk::doDmaWrite>;
-    EventWrapper<IdeDisk, &IdeDisk::doDmaWrite> dmaWriteWaitEvent;
+    EventFunctionWrapper dmaWriteWaitEvent;
 
     void dmaPrdReadDone();
-    friend class EventWrapper<IdeDisk, &IdeDisk::dmaPrdReadDone>;
-    EventWrapper<IdeDisk, &IdeDisk::dmaPrdReadDone> dmaPrdReadEvent;
+    EventFunctionWrapper dmaPrdReadEvent;
 
     void dmaReadDone();
-    friend class EventWrapper<IdeDisk, &IdeDisk::dmaReadDone>;
-    EventWrapper<IdeDisk, &IdeDisk::dmaReadDone> dmaReadEvent;
+    EventFunctionWrapper dmaReadEvent;
 
     void dmaWriteDone();
-    friend class EventWrapper<IdeDisk, &IdeDisk::dmaWriteDone>;
-    EventWrapper<IdeDisk, &IdeDisk::dmaWriteDone> dmaWriteEvent;
+    EventFunctionWrapper dmaWriteEvent;
 
     // Disk image read/write
     void readDisk(uint32_t sector, uint8_t *data);