x86 isa: This patch attempts an implementation at mwait.
Mwait works as follows: 1. A cpu monitors an address of interest (monitor instruction) 2. A cpu calls mwait - this loads the cache line into that cpu's cache. 3. The cpu goes to sleep. 4. When another processor requests write permission for the line, it is evicted from the sleeping cpu's cache. This eviction is forwarded to the sleeping cpu, which then wakes up. Committed by: Nilay Vaish <nilay@cs.wisc.edu>
This commit is contained in:
@@ -272,6 +272,12 @@ AtomicSimpleCPU::AtomicCPUDPort::recvAtomicSnoop(PacketPtr pkt)
|
||||
DPRINTF(SimpleCPU, "received snoop pkt for addr:%#x %s\n", pkt->getAddr(),
|
||||
pkt->cmdString());
|
||||
|
||||
// X86 ISA: Snooping an invalidation for monitor/mwait
|
||||
AtomicSimpleCPU *cpu = (AtomicSimpleCPU *)(&owner);
|
||||
if(cpu->getAddrMonitor()->doMonitor(pkt)) {
|
||||
cpu->wakeup();
|
||||
}
|
||||
|
||||
// if snoop invalidates, release any associated locks
|
||||
if (pkt->isInvalidate()) {
|
||||
DPRINTF(SimpleCPU, "received invalidation for addr:%#x\n",
|
||||
@@ -288,6 +294,12 @@ AtomicSimpleCPU::AtomicCPUDPort::recvFunctionalSnoop(PacketPtr pkt)
|
||||
DPRINTF(SimpleCPU, "received snoop pkt for addr:%#x %s\n", pkt->getAddr(),
|
||||
pkt->cmdString());
|
||||
|
||||
// X86 ISA: Snooping an invalidation for monitor/mwait
|
||||
AtomicSimpleCPU *cpu = (AtomicSimpleCPU *)(&owner);
|
||||
if(cpu->getAddrMonitor()->doMonitor(pkt)) {
|
||||
cpu->wakeup();
|
||||
}
|
||||
|
||||
// if snoop invalidates, release any associated locks
|
||||
if (pkt->isInvalidate()) {
|
||||
DPRINTF(SimpleCPU, "received invalidation for addr:%#x\n",
|
||||
|
||||
@@ -347,6 +347,8 @@ BaseSimpleCPU::dbg_vtophys(Addr addr)
|
||||
void
|
||||
BaseSimpleCPU::wakeup()
|
||||
{
|
||||
getAddrMonitor()->gotWakeup = true;
|
||||
|
||||
if (thread->status() != ThreadContext::Suspended)
|
||||
return;
|
||||
|
||||
|
||||
@@ -462,6 +462,14 @@ class BaseSimpleCPU : public BaseCPU, public ExecContext
|
||||
|
||||
private:
|
||||
TheISA::PCState pred_pc;
|
||||
|
||||
public:
|
||||
// monitor/mwait funtions
|
||||
void armMonitor(Addr address) { BaseCPU::armMonitor(address); }
|
||||
bool mwait(PacketPtr pkt) { return BaseCPU::mwait(pkt); }
|
||||
void mwaitAtomic(ThreadContext *tc)
|
||||
{ return BaseCPU::mwaitAtomic(tc, thread->dtb); }
|
||||
AddressMonitor *getAddrMonitor() { return BaseCPU::getCpuAddrMonitor(); }
|
||||
};
|
||||
|
||||
#endif // __CPU_SIMPLE_BASE_HH__
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
#include "sim/full_system.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
#include "debug/Mwait.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace TheISA;
|
||||
|
||||
@@ -818,9 +820,21 @@ TimingSimpleCPU::updateCycleCounts()
|
||||
void
|
||||
TimingSimpleCPU::DcachePort::recvTimingSnoopReq(PacketPtr pkt)
|
||||
{
|
||||
// X86 ISA: Snooping an invalidation for monitor/mwait
|
||||
if(cpu->getAddrMonitor()->doMonitor(pkt)) {
|
||||
cpu->wakeup();
|
||||
}
|
||||
TheISA::handleLockedSnoop(cpu->thread, pkt, cacheBlockMask);
|
||||
}
|
||||
|
||||
void
|
||||
TimingSimpleCPU::DcachePort::recvFunctionalSnoop(PacketPtr pkt)
|
||||
{
|
||||
// X86 ISA: Snooping an invalidation for monitor/mwait
|
||||
if(cpu->getAddrMonitor()->doMonitor(pkt)) {
|
||||
cpu->wakeup();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TimingSimpleCPU::DcachePort::recvTimingResp(PacketPtr pkt)
|
||||
|
||||
@@ -228,11 +228,16 @@ class TimingSimpleCPU : public BaseSimpleCPU
|
||||
* a wakeup event on a cpu that is monitoring an address
|
||||
*/
|
||||
virtual void recvTimingSnoopReq(PacketPtr pkt);
|
||||
virtual void recvFunctionalSnoop(PacketPtr pkt);
|
||||
|
||||
virtual bool recvTimingResp(PacketPtr pkt);
|
||||
|
||||
virtual void recvRetry();
|
||||
|
||||
virtual bool isSnooping() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct DTickEvent : public TickEvent
|
||||
{
|
||||
DTickEvent(TimingSimpleCPU *_cpu)
|
||||
|
||||
Reference in New Issue
Block a user