From 6c7ab02682aba37c173962ec907b97483625d18b Mon Sep 17 00:00:00 2001
From: Ron Dreslinski <rdreslin@umich.edu>
Date: Mon, 9 Oct 2006 00:26:10 -0400
Subject: Update the Memtester, commit a config file/test for it.

src/cpu/SConscript:
    Add memtester to the compilation environment.
    Someone who knows this better should make the MemTest a cpu model parameter.

    For now attached with the build of o3 cpu.
src/cpu/memtest/memtest.cc:
src/cpu/memtest/memtest.hh:
    Update Memtest for new mem system
src/python/m5/objects/MemTest.py:
    Update memtest python description

--HG--
extra : convert_revision : d6a63e08fda0975a7abfb23814a86a0caf53e482
---
 src/cpu/memtest/memtest.cc | 328 +++++++++++++++++++++++++++------------------
 src/cpu/memtest/memtest.hh | 102 +++++++++-----
 2 files changed, 269 insertions(+), 161 deletions(-)

(limited to 'src/cpu/memtest')

diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc
index 7ea9eaefc..186b6ba50 100644
--- a/src/cpu/memtest/memtest.cc
+++ b/src/cpu/memtest/memtest.cc
@@ -38,39 +38,80 @@
 
 #include "base/misc.hh"
 #include "base/statistics.hh"
-#include "cpu/simple_thread.hh"
+//#include "cpu/simple_thread.hh"
 #include "cpu/memtest/memtest.hh"
-#include "mem/cache/base_cache.hh"
+//#include "mem/cache/base_cache.hh"
+//#include "mem/physical.hh"
 #include "sim/builder.hh"
 #include "sim/sim_events.hh"
 #include "sim/stats.hh"
+#include "mem/packet.hh"
+#include "mem/request.hh"
+#include "mem/port.hh"
+#include "mem/mem_object.hh"
 
 using namespace std;
-using namespace TheISA;
 
 int TESTER_ALLOCATOR=0;
 
+bool
+MemTest::CpuPort::recvTiming(Packet *pkt)
+{
+    memtest->completeRequest(pkt);
+    return true;
+}
+
+Tick
+MemTest::CpuPort::recvAtomic(Packet *pkt)
+{
+    panic("MemTest doesn't expect recvAtomic callback!");
+    return curTick;
+}
+
+void
+MemTest::CpuPort::recvFunctional(Packet *pkt)
+{
+    memtest->completeRequest(pkt);
+}
+
+void
+MemTest::CpuPort::recvStatusChange(Status status)
+{
+    if (status == RangeChange)
+        return;
+
+    panic("MemTest doesn't expect recvStatusChange callback!");
+}
+
+void
+MemTest::CpuPort::recvRetry()
+{
+    memtest->doRetry();
+}
+
 MemTest::MemTest(const string &name,
-                 MemInterface *_cache_interface,
-                 FunctionalMemory *main_mem,
-                 FunctionalMemory *check_mem,
+//		 MemInterface *_cache_interface,
+//		 PhysicalMemory *main_mem,
+//		 PhysicalMemory *check_mem,
                  unsigned _memorySize,
                  unsigned _percentReads,
-                 unsigned _percentCopies,
+//		 unsigned _percentCopies,
                  unsigned _percentUncacheable,
                  unsigned _progressInterval,
                  unsigned _percentSourceUnaligned,
                  unsigned _percentDestUnaligned,
                  Addr _traceAddr,
                  Counter _max_loads)
-    : SimObject(name),
+    : MemObject(name),
       tickEvent(this),
-      cacheInterface(_cache_interface),
-      mainMem(main_mem),
-      checkMem(check_mem),
+      cachePort("test", this),
+      funcPort("functional", this),
+      retryPkt(NULL),
+//      mainMem(main_mem),
+//      checkMem(check_mem),
       size(_memorySize),
       percentReads(_percentReads),
-      percentCopies(_percentCopies),
+//      percentCopies(_percentCopies),
       percentUncacheable(_percentUncacheable),
       progressInterval(_progressInterval),
       nextProgressMessage(_progressInterval),
@@ -81,43 +122,52 @@ MemTest::MemTest(const string &name,
     vector<string> cmd;
     cmd.push_back("/bin/ls");
     vector<string> null_vec;
-    thread = new SimpleThread(NULL, 0, mainMem, 0);
-
-    blockSize = cacheInterface->getBlockSize();
-    blockAddrMask = blockSize - 1;
-    traceBlockAddr = blockAddr(_traceAddr);
-
-    //setup data storage with interesting values
-    uint8_t *data1 = new uint8_t[size];
-    uint8_t *data2 = new uint8_t[size];
-    uint8_t *data3 = new uint8_t[size];
-    memset(data1, 1, size);
-    memset(data2, 2, size);
-    memset(data3, 3, size);
+    //  thread = new SimpleThread(NULL, 0, NULL, 0, mainMem);
     curTick = 0;
 
+    // Needs to be masked off once we know the block size.
+    traceBlockAddr = _traceAddr;
     baseAddr1 = 0x100000;
     baseAddr2 = 0x400000;
     uncacheAddr = 0x800000;
 
-    // set up intial memory contents here
-    mainMem->prot_write(baseAddr1, data1, size);
-    checkMem->prot_write(baseAddr1, data1, size);
-    mainMem->prot_write(baseAddr2, data2, size);
-    checkMem->prot_write(baseAddr2, data2, size);
-    mainMem->prot_write(uncacheAddr, data3, size);
-    checkMem->prot_write(uncacheAddr, data3, size);
-
-    delete [] data1;
-    delete [] data2;
-    delete [] data3;
-
     // set up counters
     noResponseCycles = 0;
     numReads = 0;
     tickEvent.schedule(0);
 
     id = TESTER_ALLOCATOR++;
+
+    accessRetry = false;
+}
+
+Port *
+MemTest::getPort(const std::string &if_name, int idx)
+{
+    if (if_name == "functional")
+        return &funcPort;
+    else if (if_name == "test")
+        return &cachePort;
+    else
+        panic("No Such Port\n");
+}
+
+void
+MemTest::init()
+{
+    // By the time init() is called, the ports should be hooked up.
+    blockSize = cachePort.peerBlockSize();
+    blockAddrMask = blockSize - 1;
+    traceBlockAddr = blockAddr(traceBlockAddr);
+
+    // set up intial memory contents here
+
+    cachePort.memsetBlob(baseAddr1, 1, size);
+    funcPort.memsetBlob(baseAddr1, 1, size);
+    cachePort.memsetBlob(baseAddr2, 2, size);
+    funcPort.memsetBlob(baseAddr2, 2, size);
+    cachePort.memsetBlob(uncacheAddr, 3, size);
+    funcPort.memsetBlob(uncacheAddr, 3, size);
 }
 
 static void
@@ -132,23 +182,31 @@ printData(ostream &os, uint8_t *data, int nbytes)
 }
 
 void
-MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
+MemTest::completeRequest(Packet *pkt)
 {
+    MemTestSenderState *state =
+        dynamic_cast<MemTestSenderState *>(pkt->senderState);
+
+    uint8_t *data = state->data;
+    uint8_t *pkt_data = pkt->getPtr<uint8_t>();
+    Request *req = pkt->req;
+
     //Remove the address from the list of outstanding
-    std::set<unsigned>::iterator removeAddr = outstandingAddrs.find(req->paddr);
+    std::set<unsigned>::iterator removeAddr = outstandingAddrs.find(req->getPaddr());
     assert(removeAddr != outstandingAddrs.end());
     outstandingAddrs.erase(removeAddr);
 
-    switch (req->cmd) {
-      case Read:
-        if (memcmp(req->data, data, req->size) != 0) {
-            cerr << name() << ": on read of 0x" << hex << req->paddr
-                 << " (0x" << hex << blockAddr(req->paddr) << ")"
+    switch (pkt->cmd) {
+      case Packet::ReadResp:
+
+        if (memcmp(pkt_data, data, pkt->getSize()) != 0) {
+            cerr << name() << ": on read of 0x" << hex << req->getPaddr()
+                 << " (0x" << hex << blockAddr(req->getPaddr()) << ")"
                  << "@ cycle " << dec << curTick
                  << ", cache returns 0x";
-            printData(cerr, req->data, req->size);
+            printData(cerr, pkt_data, pkt->getSize());
             cerr << ", expected 0x";
-            printData(cerr, data, req->size);
+            printData(cerr, data, pkt->getSize());
             cerr << endl;
             fatal("");
         }
@@ -163,13 +221,13 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
         }
 
         if (numReads >= maxLoads)
-            SimExit(curTick, "Maximum number of loads reached!");
+            exitSimLoop("Maximum number of loads reached!");
         break;
 
-      case Write:
+      case Packet::WriteResp:
         numWritesStat++;
         break;
-
+/*
       case Copy:
         //Also remove dest from outstanding list
         removeAddr = outstandingAddrs.find(req->dest);
@@ -177,36 +235,37 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
         outstandingAddrs.erase(removeAddr);
         numCopiesStat++;
         break;
-
+*/
       default:
         panic("invalid command");
     }
 
-    if (blockAddr(req->paddr) == traceBlockAddr) {
+    if (blockAddr(req->getPaddr()) == traceBlockAddr) {
         cerr << name() << ": completed "
-             << (req->cmd.isWrite() ? "write" : "read")
+             << (pkt->isWrite() ? "write" : "read")
              << " access of "
-             << dec << req->size << " bytes at address 0x"
-             << hex << req->paddr
-             << " (0x" << hex << blockAddr(req->paddr) << ")"
+             << dec << pkt->getSize() << " bytes at address 0x"
+             << hex << req->getPaddr()
+             << " (0x" << hex << blockAddr(req->getPaddr()) << ")"
              << ", value = 0x";
-        printData(cerr, req->data, req->size);
+        printData(cerr, pkt_data, pkt->getSize());
         cerr << " @ cycle " << dec << curTick;
 
         cerr << endl;
     }
 
     noResponseCycles = 0;
+    delete state;
     delete [] data;
+    delete pkt->req;
+    delete pkt;
 }
 
-
 void
 MemTest::regStats()
 {
     using namespace Stats;
 
-
     numReadsStat
         .name(name() + ".num_reads")
         .desc("number of read accesses completed")
@@ -234,7 +293,7 @@ MemTest::tick()
         fatal("");
     }
 
-    if (cacheInterface->isBlocked()) {
+    if (accessRetry) {
         return;
     }
 
@@ -248,30 +307,30 @@ MemTest::tick()
 
     //If we aren't doing copies, use id as offset, and do a false sharing
     //mem tester
-    if (percentCopies == 0) {
-        //We can eliminate the lower bits of the offset, and then use the id
-        //to offset within the blks
-        offset &= ~63; //Not the low order bits
-        offset += id;
-        access_size = 0;
-    }
+    //We can eliminate the lower bits of the offset, and then use the id
+    //to offset within the blks
+    offset &= ~63; //Not the low order bits
+    offset += id;
+    access_size = 0;
 
-    MemReqPtr req = new MemReq();
+    Request *req = new Request();
+    uint32_t flags = 0;
+    Addr paddr;
 
     if (cacheable < percentUncacheable) {
-        req->flags |= UNCACHEABLE;
-        req->paddr = uncacheAddr + offset;
+        flags |= UNCACHEABLE;
+        paddr = uncacheAddr + offset;
     } else {
-        req->paddr = ((base) ? baseAddr1 : baseAddr2) + offset;
+        paddr = ((base) ? baseAddr1 : baseAddr2) + offset;
     }
     // bool probe = (random() % 2 == 1) && !req->isUncacheable();
     bool probe = false;
 
-    req->size = 1 << access_size;
-    req->data = new uint8_t[req->size];
-    req->paddr &= ~(req->size - 1);
-    req->time = curTick;
-    req->xc = thread->getProxy();
+    paddr &= ~((1 << access_size) - 1);
+    req->setPhys(paddr, 1 << access_size, flags);
+    req->setThreadContext(id,0);
+
+    uint8_t *result = new uint8_t[8];
 
     if (cmd < percentReads) {
         // read
@@ -279,60 +338,81 @@ MemTest::tick()
         //For now we only allow one outstanding request per addreess per tester
         //This means we assume CPU does write forwarding to reads that alias something
         //in the cpu store buffer.
-        if (outstandingAddrs.find(req->paddr) != outstandingAddrs.end()) return;
-        else outstandingAddrs.insert(req->paddr);
+        if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) return;
+        else outstandingAddrs.insert(paddr);
 
-        req->cmd = Read;
-        uint8_t *result = new uint8_t[8];
-        checkMem->access(Read, req->paddr, result, req->size);
-        if (blockAddr(req->paddr) == traceBlockAddr) {
+        // ***** NOTE FOR RON: I'm not sure how to access checkMem. - Kevin
+        funcPort.readBlob(req->getPaddr(), result, req->getSize());
+
+        if (blockAddr(paddr) == traceBlockAddr) {
             cerr << name()
                  << ": initiating read "
                  << ((probe) ? "probe of " : "access of ")
-                 << dec << req->size << " bytes from addr 0x"
-                 << hex << req->paddr
-                 << " (0x" << hex << blockAddr(req->paddr) << ")"
+                 << dec << req->getSize() << " bytes from addr 0x"
+                 << hex << paddr
+                 << " (0x" << hex << blockAddr(paddr) << ")"
                  << " at cycle "
                  << dec << curTick << endl;
         }
+
+        Packet *pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
+        pkt->dataDynamicArray(new uint8_t[req->getSize()]);
+        MemTestSenderState *state = new MemTestSenderState(result);
+        pkt->senderState = state;
+
         if (probe) {
-            cacheInterface->probeAndUpdate(req);
-            completeRequest(req, result);
+            cachePort.sendFunctional(pkt);
+//	    completeRequest(pkt, result);
         } else {
-            req->completionEvent = new MemCompleteEvent(req, result, this);
-            cacheInterface->access(req);
+//	    req->completionEvent = new MemCompleteEvent(req, result, this);
+            if (!cachePort.sendTiming(pkt)) {
+                accessRetry = true;
+                retryPkt = pkt;
+            }
         }
-    } else if (cmd < (100 - percentCopies)){
+    } else {
         // write
 
         //For now we only allow one outstanding request per addreess per tester
         //This means we assume CPU does write forwarding to reads that alias something
         //in the cpu store buffer.
-        if (outstandingAddrs.find(req->paddr) != outstandingAddrs.end()) return;
-        else outstandingAddrs.insert(req->paddr);
+        if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) return;
+        else outstandingAddrs.insert(paddr);
 
-        req->cmd = Write;
-        memcpy(req->data, &data, req->size);
-        checkMem->access(Write, req->paddr, req->data, req->size);
-        if (blockAddr(req->paddr) == traceBlockAddr) {
+/*
+        if (blockAddr(req->getPaddr()) == traceBlockAddr) {
             cerr << name() << ": initiating write "
                  << ((probe)?"probe of ":"access of ")
-                 << dec << req->size << " bytes (value = 0x";
-            printData(cerr, req->data, req->size);
+                 << dec << req->getSize() << " bytes (value = 0x";
+            printData(cerr, data_pkt->getPtr(), req->getSize());
             cerr << ") to addr 0x"
-                 << hex << req->paddr
-                 << " (0x" << hex << blockAddr(req->paddr) << ")"
+                 << hex << req->getPaddr()
+                 << " (0x" << hex << blockAddr(req->getPaddr()) << ")"
                  << " at cycle "
                  << dec << curTick << endl;
         }
+*/
+        Packet *pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
+        uint8_t *pkt_data = new uint8_t[req->getSize()];
+        pkt->dataDynamicArray(pkt_data);
+        memcpy(pkt_data, &data, req->getSize());
+        MemTestSenderState *state = new MemTestSenderState(result);
+        pkt->senderState = state;
+
+        funcPort.writeBlob(req->getPaddr(), pkt_data, req->getSize());
+
         if (probe) {
-            cacheInterface->probeAndUpdate(req);
-            completeRequest(req, NULL);
+            cachePort.sendFunctional(pkt);
+//	    completeRequest(req, NULL);
         } else {
-            req->completionEvent = new MemCompleteEvent(req, NULL, this);
-            cacheInterface->access(req);
+//	    req->completionEvent = new MemCompleteEvent(req, NULL, this);
+            if (!cachePort.sendTiming(pkt)) {
+                accessRetry = true;
+                retryPkt = pkt;
+            }
         }
-    } else {
+    }
+/*    else {
         // copy
         unsigned source_align = random() % 100;
         unsigned dest_align = random() % 100;
@@ -369,38 +449,32 @@ MemTest::tick()
                  << " (0x" << hex << blockAddr(dest) << ")"
                  << " at cycle "
                  << dec << curTick << endl;
-        }
+        }*
         cacheInterface->access(req);
         uint8_t result[blockSize];
         checkMem->access(Read, source, &result, blockSize);
         checkMem->access(Write, dest, &result, blockSize);
     }
+*/
 }
 
-
 void
-MemCompleteEvent::process()
-{
-    tester->completeRequest(req, data);
-    delete this;
-}
-
-
-const char *
-MemCompleteEvent::description()
+MemTest::doRetry()
 {
-    return "memory access completion";
+    if (cachePort.sendTiming(retryPkt)) {
+        accessRetry = false;
+        retryPkt = NULL;
+    }
 }
 
-
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest)
 
-    SimObjectParam<BaseCache *> cache;
-    SimObjectParam<FunctionalMemory *> main_mem;
-    SimObjectParam<FunctionalMemory *> check_mem;
+//    SimObjectParam<BaseCache *> cache;
+//    SimObjectParam<PhysicalMemory *> main_mem;
+//    SimObjectParam<PhysicalMemory *> check_mem;
     Param<unsigned> memory_size;
     Param<unsigned> percent_reads;
-    Param<unsigned> percent_copies;
+//    Param<unsigned> percent_copies;
     Param<unsigned> percent_uncacheable;
     Param<unsigned> progress_interval;
     Param<unsigned> percent_source_unaligned;
@@ -413,12 +487,12 @@ END_DECLARE_SIM_OBJECT_PARAMS(MemTest)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(MemTest)
 
-    INIT_PARAM(cache, "L1 cache"),
-    INIT_PARAM(main_mem, "hierarchical memory"),
-    INIT_PARAM(check_mem, "check memory"),
+//    INIT_PARAM(cache, "L1 cache"),
+//    INIT_PARAM(main_mem, "hierarchical memory"),
+//    INIT_PARAM(check_mem, "check memory"),
     INIT_PARAM(memory_size, "memory size"),
     INIT_PARAM(percent_reads, "target read percentage"),
-    INIT_PARAM(percent_copies, "target copy percentage"),
+//    INIT_PARAM(percent_copies, "target copy percentage"),
     INIT_PARAM(percent_uncacheable, "target uncacheable percentage"),
     INIT_PARAM(progress_interval, "progress report interval (in accesses)"),
     INIT_PARAM(percent_source_unaligned,
@@ -433,8 +507,8 @@ END_INIT_SIM_OBJECT_PARAMS(MemTest)
 
 CREATE_SIM_OBJECT(MemTest)
 {
-    return new MemTest(getInstanceName(), cache->getInterface(), main_mem,
-                       check_mem, memory_size, percent_reads, percent_copies,
+    return new MemTest(getInstanceName(), /*cache->getInterface(),*/ /*main_mem,*/
+                       /*check_mem,*/ memory_size, percent_reads, /*percent_copies,*/
                        percent_uncacheable, progress_interval,
                        percent_source_unaligned, percent_dest_unaligned,
                        trace_addr, max_loads);
diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh
index 42fb235db..278012eba 100644
--- a/src/cpu/memtest/memtest.hh
+++ b/src/cpu/memtest/memtest.hh
@@ -35,25 +35,27 @@
 #include <set>
 
 #include "base/statistics.hh"
-#include "mem/functional/functional.hh"
-#include "mem/mem_interface.hh"
+//#include "mem/functional/functional.hh"
+//#include "mem/mem_interface.hh"
 #include "sim/eventq.hh"
 #include "sim/sim_exit.hh"
 #include "sim/sim_object.hh"
 #include "sim/stats.hh"
+#include "mem/mem_object.hh"
+#include "mem/port.hh"
 
-class ThreadContext;
-class MemTest : public SimObject
+class Packet;
+class MemTest : public MemObject
 {
   public:
 
     MemTest(const std::string &name,
-            MemInterface *_cache_interface,
-            FunctionalMemory *main_mem,
-            FunctionalMemory *check_mem,
+//	    MemInterface *_cache_interface,
+//	    PhysicalMemory *main_mem,
+//	    PhysicalMemory *check_mem,
             unsigned _memorySize,
             unsigned _percentReads,
-            unsigned _percentCopies,
+//	    unsigned _percentCopies,
             unsigned _percentUncacheable,
             unsigned _progressInterval,
             unsigned _percentSourceUnaligned,
@@ -61,6 +63,8 @@ class MemTest : public SimObject
             Addr _traceAddr,
             Counter _max_loads);
 
+    virtual void init();
+
     // register statistics
     virtual void regStats();
 
@@ -69,6 +73,8 @@ class MemTest : public SimObject
     // main simulation loop (one cycle)
     void tick();
 
+    virtual Port *getPort(const std::string &if_name, int idx = -1);
+
   protected:
     class TickEvent : public Event
     {
@@ -82,16 +88,62 @@ class MemTest : public SimObject
     };
 
     TickEvent tickEvent;
+    class CpuPort : public Port
+    {
+
+        MemTest *memtest;
+
+      public:
+
+        CpuPort(const std::string &_name, MemTest *_memtest)
+            : Port(_name), memtest(_memtest)
+        { }
+
+      protected:
+
+        virtual bool recvTiming(Packet *pkt);
+
+        virtual Tick recvAtomic(Packet *pkt);
+
+        virtual void recvFunctional(Packet *pkt);
+
+        virtual void recvStatusChange(Status status);
+
+        virtual void recvRetry();
+
+        virtual void getDeviceAddressRanges(AddrRangeList &resp,
+            AddrRangeList &snoop)
+        { resp.clear(); snoop.clear(); }
+    };
+
+    CpuPort cachePort;
+    CpuPort funcPort;
+
+    class MemTestSenderState : public Packet::SenderState
+    {
+      public:
+        /** Constructor. */
+        MemTestSenderState(uint8_t *_data)
+            : data(_data)
+        { }
+
+        // Hold onto data pointer
+        uint8_t *data;
+    };
+
+//    Request *dataReq;
+    Packet  *retryPkt;
+//    MemInterface *cacheInterface;
+//    PhysicalMemory *mainMem;
+//    PhysicalMemory *checkMem;
+//    SimpleThread *thread;
 
-    MemInterface *cacheInterface;
-    FunctionalMemory *mainMem;
-    FunctionalMemory *checkMem;
-    SimpleThread *thread;
+    bool accessRetry;
 
     unsigned size;		// size of testing memory region
 
     unsigned percentReads;	// target percentage of read accesses
-    unsigned percentCopies;	// target percentage of copy accesses
+//    unsigned percentCopies;	// target percentage of copy accesses
     unsigned percentUncacheable;
 
     int id;
@@ -128,29 +180,11 @@ class MemTest : public SimObject
     Stats::Scalar<> numCopiesStat;
 
     // called by MemCompleteEvent::process()
-    void completeRequest(MemReqPtr &req, uint8_t *data);
+    void completeRequest(Packet *pkt);
 
-    friend class MemCompleteEvent;
-};
+    void doRetry();
 
-
-class MemCompleteEvent : public Event
-{
-    MemReqPtr req;
-    uint8_t *data;
-    MemTest *tester;
-
-  public:
-
-    MemCompleteEvent(MemReqPtr &_req, uint8_t *_data, MemTest *_tester)
-        : Event(&mainEventQueue),
-          req(_req), data(_data), tester(_tester)
-    {
-    }
-
-    void process();
-
-    virtual const char *description();
+    friend class MemCompleteEvent;
 };
 
 #endif // __CPU_MEMTEST_MEMTEST_HH__
-- 
cgit v1.2.3


From 095d5991f50aaccd2a25792cb7ce44b43a98b29c Mon Sep 17 00:00:00 2001
From: Ron Dreslinski <rdreslin@umich.edu>
Date: Mon, 9 Oct 2006 00:31:24 -0400
Subject: Put a check in so people know not to create more than 8 memtesters.

--HG--
extra : convert_revision : 41ab297dc681b2601be1df33aba30c39f49466d8
---
 src/cpu/memtest/memtest.cc | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'src/cpu/memtest')

diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc
index 186b6ba50..609a07a8e 100644
--- a/src/cpu/memtest/memtest.cc
+++ b/src/cpu/memtest/memtest.cc
@@ -137,6 +137,8 @@ MemTest::MemTest(const string &name,
     tickEvent.schedule(0);
 
     id = TESTER_ALLOCATOR++;
+    if (TESTER_ALLOCATOR > 8)
+        panic("False sharing memtester only allows up to 8 testers");
 
     accessRetry = false;
 }
-- 
cgit v1.2.3