changeset 1bc3d93c7eaa in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=1bc3d93c7eaa
description:
        cpu: Add per-thread monitors

        Adds per-thread address monitors to support FullSystem SMT.

diffstat:

 src/cpu/base.cc                |  47 ++++++++++++++++++++++++----------------
 src/cpu/base.hh                |  15 +++++++-----
 src/cpu/base_dyn_inst.hh       |   9 ++++---
 src/cpu/checker/cpu.hh         |   8 +++---
 src/cpu/minor/exec_context.hh  |   8 +++---
 src/cpu/minor/fetch1.cc        |   3 +-
 src/cpu/minor/lsq.cc           |   3 +-
 src/cpu/o3/cpu.cc              |   7 +++--
 src/cpu/simple/atomic.cc       |  49 +++++++++++++++++++++++++++++++++--------
 src/cpu/simple/atomic.hh       |   3 ++
 src/cpu/simple/base.cc         |   3 +-
 src/cpu/simple/exec_context.hh |   8 +++---
 src/cpu/simple/timing.cc       |  28 ++++++++++++++++++-----
 src/cpu/simple/timing.hh       |   1 +
 14 files changed, 128 insertions(+), 64 deletions(-)

diffs (truncated from 441 to 300 lines):

diff -r cc8d6e99cf46 -r 1bc3d93c7eaa src/cpu/base.cc
--- a/src/cpu/base.cc   Wed Sep 30 11:14:19 2015 -0500
+++ b/src/cpu/base.cc   Wed Sep 30 11:14:19 2015 -0500
@@ -133,7 +133,7 @@
       numThreads(p->numThreads), system(p->system),
       functionTraceStream(nullptr), currentFunctionStart(0),
       currentFunctionEnd(0), functionEntryTick(0),
-      addressMonitor()
+      addressMonitor(p->numThreads)
 {
     // if Python did not provide a valid ID, do it here
     if (_cpuId == -1 ) {
@@ -271,39 +271,48 @@
 }
 
 void
-BaseCPU::armMonitor(Addr address)
+BaseCPU::armMonitor(ThreadID tid, Addr address)
 {
-    addressMonitor.armed = true;
-    addressMonitor.vAddr = address;
-    addressMonitor.pAddr = 0x0;
-    DPRINTF(Mwait,"Armed monitor (vAddr=0x%lx)\n", address);
+    assert(tid < numThreads);
+    AddressMonitor &monitor = addressMonitor[tid];
+
+    monitor.armed = true;
+    monitor.vAddr = address;
+    monitor.pAddr = 0x0;
+    DPRINTF(Mwait,"[tid:%d] Armed monitor (vAddr=0x%lx)\n", tid, address);
 }
 
 bool
-BaseCPU::mwait(PacketPtr pkt)
+BaseCPU::mwait(ThreadID tid, PacketPtr pkt)
 {
-    if(addressMonitor.gotWakeup == false) {
+    assert(tid < numThreads);
+    AddressMonitor &monitor = addressMonitor[tid];
+
+    if(monitor.gotWakeup == false) {
         int block_size = cacheLineSize();
         uint64_t mask = ~((uint64_t)(block_size - 1));
 
         assert(pkt->req->hasPaddr());
-        addressMonitor.pAddr = pkt->getAddr() & mask;
-        addressMonitor.waiting = true;
+        monitor.pAddr = pkt->getAddr() & mask;
+        monitor.waiting = true;
 
-        DPRINTF(Mwait,"mwait called (vAddr=0x%lx, line's paddr=0x%lx)\n",
-                addressMonitor.vAddr, addressMonitor.pAddr);
+        DPRINTF(Mwait,"[tid:%d] mwait called (vAddr=0x%lx, "
+                "line's paddr=0x%lx)\n", tid, monitor.vAddr, monitor.pAddr);
         return true;
     } else {
-        addressMonitor.gotWakeup = false;
+        monitor.gotWakeup = false;
         return false;
     }
 }
 
 void
-BaseCPU::mwaitAtomic(ThreadContext *tc, TheISA::TLB *dtb)
+BaseCPU::mwaitAtomic(ThreadID tid, ThreadContext *tc, TheISA::TLB *dtb)
 {
+    assert(tid < numThreads);
+    AddressMonitor &monitor = addressMonitor[tid];
+
     Request req;
-    Addr addr = addressMonitor.vAddr;
+    Addr addr = monitor.vAddr;
     int block_size = cacheLineSize();
     uint64_t mask = ~((uint64_t)(block_size - 1));
     int size = block_size;
@@ -320,11 +329,11 @@
     Fault fault = dtb->translateAtomic(&req, tc, BaseTLB::Read);
     assert(fault == NoFault);
 
-    addressMonitor.pAddr = req.getPaddr() & mask;
-    addressMonitor.waiting = true;
+    monitor.pAddr = req.getPaddr() & mask;
+    monitor.waiting = true;
 
-    DPRINTF(Mwait,"mwait called (vAddr=0x%lx, line's paddr=0x%lx)\n",
-            addressMonitor.vAddr, addressMonitor.pAddr);
+    DPRINTF(Mwait,"[tid:%d] mwait called (vAddr=0x%lx, line's paddr=0x%lx)\n",
+            tid, monitor.vAddr, monitor.pAddr);
 }
 
 void
diff -r cc8d6e99cf46 -r 1bc3d93c7eaa src/cpu/base.hh
--- a/src/cpu/base.hh   Wed Sep 30 11:14:19 2015 -0500
+++ b/src/cpu/base.hh   Wed Sep 30 11:14:19 2015 -0500
@@ -559,14 +559,17 @@
     Stats::Scalar numWorkItemsCompleted;
 
   private:
-    AddressMonitor addressMonitor;
+    std::vector<AddressMonitor> addressMonitor;
 
   public:
-    void armMonitor(Addr address);
-    bool mwait(PacketPtr pkt);
-    void mwaitAtomic(ThreadContext *tc, TheISA::TLB *dtb);
-    AddressMonitor *getCpuAddrMonitor() { return &addressMonitor; }
-    void atomicNotify(Addr address);
+    void armMonitor(ThreadID tid, Addr address);
+    bool mwait(ThreadID tid, PacketPtr pkt);
+    void mwaitAtomic(ThreadID tid, ThreadContext *tc, TheISA::TLB *dtb);
+    AddressMonitor *getCpuAddrMonitor(ThreadID tid)
+    {
+        assert(tid < numThreads);
+        return &addressMonitor[tid];
+    }
 };
 
 #endif // THE_ISA == NULL_ISA
diff -r cc8d6e99cf46 -r 1bc3d93c7eaa src/cpu/base_dyn_inst.hh
--- a/src/cpu/base_dyn_inst.hh  Wed Sep 30 11:14:19 2015 -0500
+++ b/src/cpu/base_dyn_inst.hh  Wed Sep 30 11:14:19 2015 -0500
@@ -863,11 +863,12 @@
 
   public:
     // monitor/mwait funtions
-    void armMonitor(Addr address) { cpu->armMonitor(address); }
-    bool mwait(PacketPtr pkt) { return cpu->mwait(pkt); }
+    void armMonitor(Addr address) { cpu->armMonitor(threadNumber, address); }
+    bool mwait(PacketPtr pkt) { return cpu->mwait(threadNumber, pkt); }
     void mwaitAtomic(ThreadContext *tc)
-    { return cpu->mwaitAtomic(tc, cpu->dtb); }
-    AddressMonitor *getAddrMonitor() { return cpu->getCpuAddrMonitor(); }
+    { return cpu->mwaitAtomic(threadNumber, tc, cpu->dtb); }
+    AddressMonitor *getAddrMonitor()
+    { return cpu->getCpuAddrMonitor(threadNumber); }
 };
 
 template<class Impl>
diff -r cc8d6e99cf46 -r 1bc3d93c7eaa src/cpu/checker/cpu.hh
--- a/src/cpu/checker/cpu.hh    Wed Sep 30 11:14:19 2015 -0500
+++ b/src/cpu/checker/cpu.hh    Wed Sep 30 11:14:19 2015 -0500
@@ -350,11 +350,11 @@
     }
 
     // monitor/mwait funtions
-    virtual void armMonitor(Addr address) { BaseCPU::armMonitor(address); }
-    bool mwait(PacketPtr pkt) { return BaseCPU::mwait(pkt); }
+    virtual void armMonitor(Addr address) { BaseCPU::armMonitor(0, address); }
+    bool mwait(PacketPtr pkt) { return BaseCPU::mwait(0, pkt); }
     void mwaitAtomic(ThreadContext *tc)
-    { return BaseCPU::mwaitAtomic(tc, thread->dtb); }
-    AddressMonitor *getAddrMonitor() { return BaseCPU::getCpuAddrMonitor(); }
+    { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); }
+    AddressMonitor *getAddrMonitor() { return BaseCPU::getCpuAddrMonitor(0); }
 
     void demapInstPage(Addr vaddr, uint64_t asn)
     {
diff -r cc8d6e99cf46 -r 1bc3d93c7eaa src/cpu/minor/exec_context.hh
--- a/src/cpu/minor/exec_context.hh     Wed Sep 30 11:14:19 2015 -0500
+++ b/src/cpu/minor/exec_context.hh     Wed Sep 30 11:14:19 2015 -0500
@@ -343,12 +343,12 @@
 
   public:
     // monitor/mwait funtions
-    void armMonitor(Addr address) { getCpuPtr()->armMonitor(address); }
-    bool mwait(PacketPtr pkt) { return getCpuPtr()->mwait(pkt); }
+    void armMonitor(Addr address) { getCpuPtr()->armMonitor(0, address); }
+    bool mwait(PacketPtr pkt) { return getCpuPtr()->mwait(0, pkt); }
     void mwaitAtomic(ThreadContext *tc)
-    { return getCpuPtr()->mwaitAtomic(tc, thread.dtb); }
+    { return getCpuPtr()->mwaitAtomic(0, tc, thread.dtb); }
     AddressMonitor *getAddrMonitor()
-    { return getCpuPtr()->getCpuAddrMonitor(); }
+    { return getCpuPtr()->getCpuAddrMonitor(0); }
 };
 
 }
diff -r cc8d6e99cf46 -r 1bc3d93c7eaa src/cpu/minor/fetch1.cc
--- a/src/cpu/minor/fetch1.cc   Wed Sep 30 11:14:19 2015 -0500
+++ b/src/cpu/minor/fetch1.cc   Wed Sep 30 11:14:19 2015 -0500
@@ -135,7 +135,8 @@
         "%s addr: 0x%x pc: %s line_offset: %d request_size: %d\n",
         request_id, aligned_pc, pc, line_offset, request_size);
 
-    request->request.setThreadContext(cpu.cpuId(), /* thread id */ 0);
+    request->request.setThreadContext(cpu.threads[0]->getTC()->contextId(),
+                                      /* thread id */ 0);
     request->request.setVirt(0 /* asid */,
         aligned_pc, request_size, Request::INST_FETCH, cpu.instMasterId(),
         /* I've no idea why we need the PC, but give it */
diff -r cc8d6e99cf46 -r 1bc3d93c7eaa src/cpu/minor/lsq.cc
--- a/src/cpu/minor/lsq.cc      Wed Sep 30 11:14:19 2015 -0500
+++ b/src/cpu/minor/lsq.cc      Wed Sep 30 11:14:19 2015 -0500
@@ -1501,7 +1501,8 @@
     if (inst->traceData)
         inst->traceData->setMem(addr, size, flags);
 
-    request->request.setThreadContext(cpu.cpuId(), /* thread id */ 0);
+    int cid = cpu.threads[inst->id.threadId]->getTC()->contextId();
+    request->request.setThreadContext(cid, /* thread id */ 0);
     request->request.setVirt(0 /* asid */,
         addr, size, flags, cpu.dataMasterId(),
         /* I've no idea why we need the PC, but give it */
diff -r cc8d6e99cf46 -r 1bc3d93c7eaa src/cpu/o3/cpu.cc
--- a/src/cpu/o3/cpu.cc Wed Sep 30 11:14:19 2015 -0500
+++ b/src/cpu/o3/cpu.cc Wed Sep 30 11:14:19 2015 -0500
@@ -118,9 +118,10 @@
 void
 FullO3CPU<Impl>::DcachePort::recvTimingSnoopReq(PacketPtr pkt)
 {
-    // X86 ISA: Snooping an invalidation for monitor/mwait
-    if(cpu->getCpuAddrMonitor()->doMonitor(pkt)) {
-        cpu->wakeup();
+    for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
+        if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
+            cpu->wakeup();
+        }
     }
     lsq->recvTimingSnoopReq(pkt);
 }
diff -r cc8d6e99cf46 -r 1bc3d93c7eaa src/cpu/simple/atomic.cc
--- a/src/cpu/simple/atomic.cc  Wed Sep 30 11:14:19 2015 -0500
+++ b/src/cpu/simple/atomic.cc  Wed Sep 30 11:14:19 2015 -0500
@@ -86,9 +86,10 @@
 {
     BaseSimpleCPU::init();
 
-    ifetch_req.setThreadContext(_cpuId, 0);
-    data_read_req.setThreadContext(_cpuId, 0);
-    data_write_req.setThreadContext(_cpuId, 0);
+    int cid = threadContexts[0]->contextId();
+    ifetch_req.setThreadContext(cid, 0);
+    data_read_req.setThreadContext(cid, 0);
+    data_write_req.setThreadContext(cid, 0);
 }
 
 AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p)
@@ -131,6 +132,24 @@
 }
 
 void
+AtomicSimpleCPU::threadSnoop(PacketPtr pkt, ThreadID sender)
+{
+    DPRINTF(SimpleCPU, "received snoop pkt for addr:%#x %s\n", pkt->getAddr(),
+            pkt->cmdString());
+
+    for (ThreadID tid = 0; tid < numThreads; tid++) {
+        if (tid != sender) {
+            if(getCpuAddrMonitor(tid)->doMonitor(pkt)) {
+                wakeup();
+            }
+
+            TheISA::handleLockedSnoop(threadInfo[tid]->thread,
+                                      pkt, dcachePort.cacheBlockMask);
+        }
+    }
+}
+
+void
 AtomicSimpleCPU::drainResume()
 {
     assert(!tickEvent.scheduled());
@@ -265,8 +284,11 @@
 
     // X86 ISA: Snooping an invalidation for monitor/mwait
     AtomicSimpleCPU *cpu = (AtomicSimpleCPU *)(&owner);
-    if(cpu->getCpuAddrMonitor()->doMonitor(pkt)) {
-        cpu->wakeup();
+
+    for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
+        if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
+            cpu->wakeup();
+        }
     }
 
     // if snoop invalidates, release any associated locks
@@ -289,8 +311,10 @@
 
     // X86 ISA: Snooping an invalidation for monitor/mwait
     AtomicSimpleCPU *cpu = (AtomicSimpleCPU *)(&owner);
-    if(cpu->getCpuAddrMonitor()->doMonitor(pkt)) {
-        cpu->wakeup();
+    for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
+        if(cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
+            cpu->wakeup();
+        }
     }
 
     // if snoop invalidates, release any associated locks
@@ -460,6 +484,9 @@
                         system->getPhysMem().access(&pkt);
                     else
                         dcache_latency += dcachePort.sendAtomic(&pkt);
+
+                    // Notify other threads on this CPU of write
+                    threadSnoop(&pkt, curThread);
                 }
                 dcache_access = true;
                 assert(!pkt.isError());
@@ -516,9 +543,11 @@
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to