cpu,isa,mem: Add per-thread wakeup logic
authorMitch Hayenga <mitch.hayenga@arm.com>
Wed, 30 Sep 2015 16:14:19 +0000 (11:14 -0500)
committerMitch Hayenga <mitch.hayenga@arm.com>
Wed, 30 Sep 2015 16:14:19 +0000 (11:14 -0500)
Changes wakeup functionality so that only specific threads on SMT
capable cpus are woken.

16 files changed:
src/arch/arm/locked_mem.hh
src/arch/null/cpu_dummy.hh
src/arch/x86/interrupts.cc
src/cpu/base.hh
src/cpu/checker/cpu.hh
src/cpu/kvm/base.cc
src/cpu/kvm/base.hh
src/cpu/minor/cpu.cc
src/cpu/minor/cpu.hh
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/simple/atomic.cc
src/cpu/simple/base.cc
src/cpu/simple/base.hh
src/cpu/simple/timing.cc
src/mem/abstract_mem.cc

index 24c78e72114846d56d4861215ab01ac64c7f6bd5..f324f773b2b04f411e34651ede901cbb22ac8777 100644 (file)
@@ -82,7 +82,7 @@ handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
         xc->setMiscReg(MISCREG_LOCKFLAG, false);
         // Implement ARMv8 WFE/SEV semantics
         xc->setMiscReg(MISCREG_SEV_MAILBOX, true);
-        xc->getCpuPtr()->wakeup();
+        xc->getCpuPtr()->wakeup(xc->threadId());
     }
 }
 
index f546b4141b1c9ae774735aa8864c970420c144a3..6f6311bcbdcfa650f5fa4f44a59099968be50405 100644 (file)
@@ -47,7 +47,7 @@ class BaseCPU
   public:
     static int numSimulatedInsts() { return 0; }
     static int numSimulatedOps() { return 0; }
-    static void wakeup() { ; }
+    static void wakeup(ThreadID tid) { ; }
 };
 
 #endif // __ARCH_NULL_CPU_DUMMY_HH__
index 556cdda3769a94b2f2e3d2ecc8cf20e5410aa9be..1f7002ebe095992992a5f26e6952194a1526a212 100644 (file)
@@ -290,7 +290,7 @@ X86ISA::Interrupts::requestInterrupt(uint8_t vector,
         }
     }
     if (FullSystem)
-        cpu->wakeup();
+        cpu->wakeup(0);
 }
 
 
index 2a57c01ba653de3ea17f3b2a9272179f5465126b..95ae4fc43d3c730e8700508aa4e12cdf3b1c1dea 100644 (file)
@@ -220,14 +220,14 @@ class BaseCPU : public MemObject
         return interrupts[tid];
     }
 
-    virtual void wakeup() = 0;
+    virtual void wakeup(ThreadID tid) = 0;
 
     void
     postInterrupt(ThreadID tid, int int_num, int index)
     {
         interrupts[tid]->post(int_num, index);
         if (FullSystem)
-            wakeup();
+            wakeup(tid);
     }
 
     void
index 69f47894b880f0be391297e4ced5e9b332ebb982..0351ec2e044b3ad9337012caa223bcff38d4c2a3 100644 (file)
@@ -380,7 +380,7 @@ class CheckerCPU : public BaseCPU, public ExecContext
 
     Fault hwrei() { return thread->hwrei(); }
     bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
-    void wakeup() { }
+    void wakeup(ThreadID tid) M5_ATTR_OVERRIDE { }
     // Assume that the normal CPU's call to syscall was successful.
     // The checker's state would have already been updated by the syscall.
     void syscall(int64_t callnum) { }
index 47cff59172e3618d58714053cca4da1e4dd0a7bd..32f94eca834fe565383eb2d2de82df358a0e3323 100644 (file)
@@ -408,7 +408,7 @@ BaseKvmCPU::verifyMemoryMode() const
 }
 
 void
-BaseKvmCPU::wakeup()
+BaseKvmCPU::wakeup(ThreadID tid)
 {
     DPRINTF(Kvm, "wakeup()\n");
     // This method might have been called from another
index df6a67808b886c105e0b66d2de171800d715a084..89c52cf6b6d962a320ff4dfcb61497ccaa01aacf 100644 (file)
@@ -100,7 +100,7 @@ class BaseKvmCPU : public BaseCPU
     MasterPort &getDataPort() { return dataPort; }
     MasterPort &getInstPort() { return instPort; }
 
-    void wakeup();
+    void wakeup(ThreadID tid = 0) M5_ATTR_OVERRIDE;
     void activateContext(ThreadID thread_num);
     void suspendContext(ThreadID thread_num);
     void deallocateContext(ThreadID thread_num);
index 51a3f3ae87c21353088d3c17fd3229eaa781f216..cd39a8b93e305ce2c9740923ce1eed3dfc8a3495 100644 (file)
@@ -167,14 +167,12 @@ MinorCPU::dbg_vtophys(Addr addr)
 }
 
 void
-MinorCPU::wakeup()
+MinorCPU::wakeup(ThreadID tid)
 {
-    DPRINTF(Drain, "MinorCPU wakeup\n");
+    DPRINTF(Drain, "[tid:%d] MinorCPU wakeup\n", tid);
 
-    for (auto i = threads.begin(); i != threads.end(); i ++) {
-        if ((*i)->status() == ThreadContext::Suspended)
-            (*i)->activate();
-    }
+    if (threads[tid]->status() == ThreadContext::Suspended)
+        threads[tid]->activate();
 
     DPRINTF(Drain,"Suspended Processor awoke\n");
 }
@@ -241,7 +239,8 @@ MinorCPU::drainResume()
             "'timing' mode.\n");
     }
 
-    wakeup();
+    for (ThreadID tid = 0; tid < numThreads; tid++)
+        wakeup(tid);
     pipeline->drainResume();
 }
 
index 2e877d786c6f75f7ad99a7a4c410467ba5abbf6d..99b91569391cd9ce8d231dc782fcba82eeac604d 100644 (file)
@@ -128,7 +128,7 @@ class MinorCPU : public BaseCPU
     /** Starting, waking and initialisation */
     void init();
     void startup();
-    void wakeup();
+    void wakeup(ThreadID tid) M5_ATTR_OVERRIDE;
 
     Addr dbg_vtophys(Addr addr);
 
index d4ee5ffe77067569ed4886e9638168bf4fb50f68..c17b7a9dcec0e53e6996cf4b800d31768dd6e5b3 100644 (file)
@@ -120,7 +120,7 @@ FullO3CPU<Impl>::DcachePort::recvTimingSnoopReq(PacketPtr pkt)
 {
     for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
         if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
-            cpu->wakeup();
+            cpu->wakeup(tid);
         }
     }
     lsq->recvTimingSnoopReq(pkt);
@@ -1633,15 +1633,15 @@ FullO3CPU<Impl>::wakeCPU()
 
 template <class Impl>
 void
-FullO3CPU<Impl>::wakeup()
+FullO3CPU<Impl>::wakeup(ThreadID tid)
 {
-    if (this->thread[0]->status() != ThreadContext::Suspended)
+    if (this->thread[tid]->status() != ThreadContext::Suspended)
         return;
 
     this->wakeCPU();
 
     DPRINTF(Quiesce, "Suspended Processor woken\n");
-    this->threadContexts[0]->activate();
+    this->threadContexts[tid]->activate();
 }
 
 template <class Impl>
index aa02ee2ea17a40d1bc8900dc01c3698d87e7c92c..bd9c44752c34440ae16335e807548e2007321ebf 100644 (file)
@@ -640,7 +640,7 @@ class FullO3CPU : public BaseO3CPU
     /** Wakes the CPU, rescheduling the CPU if it's not already active. */
     void wakeCPU();
 
-    virtual void wakeup();
+    virtual void wakeup(ThreadID tid) M5_ATTR_OVERRIDE;
 
     /** Gets a free thread id. Use if thread ids change across system. */
     ThreadID getFreeTid();
index 2d9da25875e58b1131b5fbc89890b6e85f4ae4e5..77706966bcde11bb837231de9920e37ac7a82383 100644 (file)
@@ -140,7 +140,7 @@ AtomicSimpleCPU::threadSnoop(PacketPtr pkt, ThreadID sender)
     for (ThreadID tid = 0; tid < numThreads; tid++) {
         if (tid != sender) {
             if(getCpuAddrMonitor(tid)->doMonitor(pkt)) {
-                wakeup();
+                wakeup(tid);
             }
 
             TheISA::handleLockedSnoop(threadInfo[tid]->thread,
@@ -287,7 +287,7 @@ AtomicSimpleCPU::AtomicCPUDPort::recvAtomicSnoop(PacketPtr pkt)
 
     for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
         if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
-            cpu->wakeup();
+            cpu->wakeup(tid);
         }
     }
 
@@ -313,7 +313,7 @@ AtomicSimpleCPU::AtomicCPUDPort::recvFunctionalSnoop(PacketPtr pkt)
     AtomicSimpleCPU *cpu = (AtomicSimpleCPU *)(&owner);
     for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
         if(cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
-            cpu->wakeup();
+            cpu->wakeup(tid);
         }
     }
 
index b0810517f61a41c624b853112e05b9b83d42084f..4d5ddebb28c4b36c6cf60c8a557c57b830ca1228 100644 (file)
@@ -416,14 +416,13 @@ BaseSimpleCPU::dbg_vtophys(Addr addr)
 }
 
 void
-BaseSimpleCPU::wakeup()
+BaseSimpleCPU::wakeup(ThreadID tid)
 {
-    for (ThreadID tid = 0; tid < numThreads; tid++) {
-        getCpuAddrMonitor(tid)->gotWakeup = true;
-        if (threadInfo[tid]->thread->status() == ThreadContext::Suspended) {
-            DPRINTF(Quiesce,"Suspended Processor awoke\n");
-            threadInfo[tid]->thread->activate();
-        }
+    getCpuAddrMonitor(tid)->gotWakeup = true;
+
+    if (threadInfo[tid]->thread->status() == ThreadContext::Suspended) {
+        DPRINTF(Quiesce,"[tid:%d] Suspended Processor awoke\n", tid);
+        threadInfo[tid]->thread->activate();
     }
 }
 
index c108cb986d44ecfdf998c20236e52d637126c380..1fcd5c20372a57d7012fe5efc01cd3bf484acc22 100644 (file)
@@ -93,7 +93,7 @@ class BaseSimpleCPU : public BaseCPU
   public:
     BaseSimpleCPU(BaseSimpleCPUParams *params);
     virtual ~BaseSimpleCPU();
-    void wakeup();
+    void wakeup(ThreadID tid) M5_ATTR_OVERRIDE;
     virtual void init();
   public:
     Trace::InstRecord *traceData;
index f3241f7e57dc55197981344d7666c7296ab65965..6d67f610b54a72a35fffbb4c7ae6e394eea5f757 100644 (file)
@@ -545,7 +545,7 @@ TimingSimpleCPU::threadSnoop(PacketPtr pkt, ThreadID sender)
     for (ThreadID tid = 0; tid < numThreads; tid++) {
         if (tid != sender) {
             if(getCpuAddrMonitor(tid)->doMonitor(pkt)) {
-                wakeup();
+                wakeup(tid);
             }
             TheISA::handleLockedSnoop(threadInfo[tid]->thread, pkt,
                     dcachePort.cacheBlockMask);
@@ -865,7 +865,7 @@ TimingSimpleCPU::DcachePort::recvTimingSnoopReq(PacketPtr pkt)
 {
     for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
         if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
-            cpu->wakeup();
+            cpu->wakeup(tid);
         }
     }
 
@@ -879,7 +879,7 @@ TimingSimpleCPU::DcachePort::recvFunctionalSnoop(PacketPtr pkt)
 {
     for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
         if(cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
-            cpu->wakeup();
+            cpu->wakeup(tid);
         }
     }
 }
index 4690a5d8091fb2f5e42808e7fcf6424b35356496..9b9c6e2c3ffb8af4d34ae400dbb915d5ee259451 100644 (file)
@@ -274,7 +274,8 @@ AbstractMemory::checkLockedAddrList(PacketPtr pkt)
                 // architecture specifies that an event is
                 // automatically generated when clearing the exclusive
                 // monitor to wake up the processor in WFE.
-                system()->getThreadContext(i->contextId)->getCpuPtr()->wakeup();
+                ThreadContext* ctx = system()->getThreadContext(i->contextId);
+                ctx->getCpuPtr()->wakeup(ctx->threadId());
                 i = lockedAddrList.erase(i);
             } else {
                 i++;