diff options
author | Mitch Hayenga <mitch.hayenga@arm.com> | 2015-09-30 11:14:19 -0500 |
---|---|---|
committer | Mitch Hayenga <mitch.hayenga@arm.com> | 2015-09-30 11:14:19 -0500 |
commit | fafa83ed32933fe250d34dfca23fba348429b176 (patch) | |
tree | 3bf8fd636f1e879273045fefda3b5d7319a38479 /src/cpu/simple | |
parent | 582a0148b441fe9f4a6f977094c5ce6bf7ab6313 (diff) | |
download | gem5-fafa83ed32933fe250d34dfca23fba348429b176.tar.xz |
cpu: Add per-thread monitors
Adds per-thread address monitors to support FullSystem SMT.
Diffstat (limited to 'src/cpu/simple')
-rw-r--r-- | src/cpu/simple/atomic.cc | 49 | ||||
-rw-r--r-- | src/cpu/simple/atomic.hh | 3 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 3 | ||||
-rw-r--r-- | src/cpu/simple/exec_context.hh | 8 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 28 | ||||
-rw-r--r-- | src/cpu/simple/timing.hh | 1 |
6 files changed, 70 insertions, 22 deletions
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 6690c1da6..2d9da2587 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -86,9 +86,10 @@ AtomicSimpleCPU::init() { 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 @@ AtomicSimpleCPU::drain() } 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 @@ AtomicSimpleCPU::AtomicCPUDPort::recvAtomicSnoop(PacketPtr pkt) // 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 @@ AtomicSimpleCPU::AtomicCPUDPort::recvFunctionalSnoop(PacketPtr pkt) // 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 @@ AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size, 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 @@ AtomicSimpleCPU::tick() // Set memroy request ids to current thread if (numThreads > 1) { - ifetch_req.setThreadContext(_cpuId, curThread); - data_read_req.setThreadContext(_cpuId, curThread); - data_write_req.setThreadContext(_cpuId, curThread); + ContextID cid = threadContexts[curThread]->contextId(); + + ifetch_req.setThreadContext(cid, curThread); + data_read_req.setThreadContext(cid, curThread); + data_write_req.setThreadContext(cid, curThread); } SimpleExecContext& t_info = *threadInfo[curThread]; diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index 76ee9f897..2bea12ab2 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -186,6 +186,9 @@ class AtomicSimpleCPU : public BaseSimpleCPU /** Return a reference to the instruction port. */ virtual MasterPort &getInstPort() { return icachePort; } + /** Perform snoop for other cpu-local thread contexts. */ + void threadSnoop(PacketPtr pkt, ThreadID sender); + public: DrainState drain() M5_ATTR_OVERRIDE; diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 673cadd77..6e8845bf7 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -418,9 +418,8 @@ BaseSimpleCPU::dbg_vtophys(Addr addr) void BaseSimpleCPU::wakeup() { - getCpuAddrMonitor()->gotWakeup = true; - 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(); diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh index f474cc358..591cf8227 100644 --- a/src/cpu/simple/exec_context.hh +++ b/src/cpu/simple/exec_context.hh @@ -376,22 +376,22 @@ class SimpleExecContext : public ExecContext { void armMonitor(Addr address) M5_ATTR_OVERRIDE { - cpu->armMonitor(address); + cpu->armMonitor(thread->threadId(), address); } bool mwait(PacketPtr pkt) M5_ATTR_OVERRIDE { - return cpu->mwait(pkt); + return cpu->mwait(thread->threadId(), pkt); } void mwaitAtomic(ThreadContext *tc) M5_ATTR_OVERRIDE { - cpu->mwaitAtomic(tc, thread->dtb); + cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb); } AddressMonitor *getAddrMonitor() M5_ATTR_OVERRIDE { - return cpu->getCpuAddrMonitor(); + return cpu->getCpuAddrMonitor(thread->threadId()); } #if THE_ISA == MIPS_ISA diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 487da36ea..f3241f7e5 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -302,6 +302,7 @@ TimingSimpleCPU::sendData(RequestPtr req, uint8_t *data, uint64_t *res, if (do_access) { dcache_pkt = pkt; handleWritePacket(); + threadSnoop(pkt, curThread); } else { _status = DcacheWaitResponse; completeDataAccess(pkt); @@ -538,6 +539,19 @@ TimingSimpleCPU::writeMem(uint8_t *data, unsigned size, return NoFault; } +void +TimingSimpleCPU::threadSnoop(PacketPtr pkt, ThreadID sender) +{ + 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 TimingSimpleCPU::finishTranslation(WholeTranslationState *state) @@ -849,9 +863,10 @@ TimingSimpleCPU::updateCycleCounts() void TimingSimpleCPU::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(); + } } for (auto &t_info : cpu->threadInfo) { @@ -862,9 +877,10 @@ TimingSimpleCPU::DcachePort::recvTimingSnoopReq(PacketPtr pkt) void TimingSimpleCPU::DcachePort::recvFunctionalSnoop(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(); + } } } diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index d409ac5d2..f1cc09e42 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -132,6 +132,7 @@ class TimingSimpleCPU : public BaseSimpleCPU }; FetchTranslation fetchTranslation; + void threadSnoop(PacketPtr pkt, ThreadID sender); void sendData(RequestPtr req, uint8_t *data, uint64_t *res, bool read); void sendSplitData(RequestPtr req1, RequestPtr req2, RequestPtr req, uint8_t *data, bool read); |