From: Mitch Hayenga Date: Wed, 30 Sep 2015 16:14:19 +0000 (-0500) Subject: cpu,isa,mem: Add per-thread wakeup logic X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9e07a7504c94973e7837d1d3e96dbdb8d95cfad3;p=gem5.git cpu,isa,mem: Add per-thread wakeup logic Changes wakeup functionality so that only specific threads on SMT capable cpus are woken. --- diff --git a/src/arch/arm/locked_mem.hh b/src/arch/arm/locked_mem.hh index 24c78e721..f324f773b 100644 --- a/src/arch/arm/locked_mem.hh +++ b/src/arch/arm/locked_mem.hh @@ -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()); } } diff --git a/src/arch/null/cpu_dummy.hh b/src/arch/null/cpu_dummy.hh index f546b4141..6f6311bcb 100644 --- a/src/arch/null/cpu_dummy.hh +++ b/src/arch/null/cpu_dummy.hh @@ -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__ diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 556cdda37..1f7002ebe 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -290,7 +290,7 @@ X86ISA::Interrupts::requestInterrupt(uint8_t vector, } } if (FullSystem) - cpu->wakeup(); + cpu->wakeup(0); } diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 2a57c01ba..95ae4fc43 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -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 diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 69f47894b..0351ec2e0 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -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) { } diff --git a/src/cpu/kvm/base.cc b/src/cpu/kvm/base.cc index 47cff5917..32f94eca8 100644 --- a/src/cpu/kvm/base.cc +++ b/src/cpu/kvm/base.cc @@ -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 diff --git a/src/cpu/kvm/base.hh b/src/cpu/kvm/base.hh index df6a67808..89c52cf6b 100644 --- a/src/cpu/kvm/base.hh +++ b/src/cpu/kvm/base.hh @@ -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); diff --git a/src/cpu/minor/cpu.cc b/src/cpu/minor/cpu.cc index 51a3f3ae8..cd39a8b93 100644 --- a/src/cpu/minor/cpu.cc +++ b/src/cpu/minor/cpu.cc @@ -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(); } diff --git a/src/cpu/minor/cpu.hh b/src/cpu/minor/cpu.hh index 2e877d786..99b915693 100644 --- a/src/cpu/minor/cpu.hh +++ b/src/cpu/minor/cpu.hh @@ -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); diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index d4ee5ffe7..c17b7a9dc 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -120,7 +120,7 @@ FullO3CPU::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::wakeCPU() template void -FullO3CPU::wakeup() +FullO3CPU::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 diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index aa02ee2ea..bd9c44752 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -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(); diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 2d9da2587..77706966b 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -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); } } diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index b0810517f..4d5ddebb2 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -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(); } } diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index c108cb986..1fcd5c203 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -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; diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index f3241f7e5..6d67f610b 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -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); } } } diff --git a/src/mem/abstract_mem.cc b/src/mem/abstract_mem.cc index 4690a5d80..9b9c6e2c3 100644 --- a/src/mem/abstract_mem.cc +++ b/src/mem/abstract_mem.cc @@ -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++;