cpu,isa,mem: Add per-thread wakeup logic

Changes wakeup functionality so that only specific threads on SMT
capable cpus are woken.
This commit is contained in:
Mitch Hayenga 2015-09-30 11:14:19 -05:00
parent a5c4eb3de9
commit 9e07a7504c
16 changed files with 35 additions and 36 deletions

View 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());
}
}

View 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__

View file

@ -290,7 +290,7 @@ X86ISA::Interrupts::requestInterrupt(uint8_t vector,
}
}
if (FullSystem)
cpu->wakeup();
cpu->wakeup(0);
}

View 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

View 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) { }

View 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

View 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);

View 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();
}

View 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);

View 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>

View 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();

View 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);
}
}

View 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();
}
}

View 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;

View 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);
}
}
}

View 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++;