diff -r e4f63f1d502d -r b8de61e29ce1 src/mem/snoop_filter.hh --- a/src/mem/snoop_filter.hh Sun Jun 21 20:52:13 2015 +0100 +++ b/src/mem/snoop_filter.hh Thu Jun 25 12:00:53 2015 +0900 @@ -54,6 +54,9 @@ #include "sim/sim_object.hh" #include "sim/system.hh" +#define MAX_CORES 64 +#define MAX_SLAVE_PORTS MAX_CORES*2+1 + /** * This snoop filter keeps track of which connected port has a * particular line of data. It can be queried (through lookup*) on @@ -191,7 +194,7 @@ virtual void regStats(); protected: - typedef uint64_t SnoopMask; + typedef std::bitset SnoopMask; /** * Per cache line item tracking a bitmask of SlavePorts who have an * outstanding request to this line (requested) or already share a cache line @@ -219,6 +222,7 @@ * @return SnoopList containing all the requested SlavePorts */ SnoopList maskToPortList(SnoopMask ports) const; + bool isMaskPow2(SnoopMask mask); private: /** Simple hash set of cached addresses. */ @@ -247,7 +251,7 @@ assert(id != (unsigned)InvalidPortID); assert((int)id < 8 * sizeof(SnoopMask)); - return ((SnoopMask)1) << id; + return SnoopMask(0).set(id,true); } inline SnoopFilter::SnoopMask @@ -264,8 +268,17 @@ { SnoopList res; for (auto port = slavePorts.begin(); port != slavePorts.end(); ++port) - if (port_mask & portToMask(**port)) + if ((port_mask & portToMask(**port)).any()) res.push_back(*port); return res; } + +/** + * Checks if a number is a power of two, or zero. + */ +inline bool +SnoopFilter::isMaskPow2(SnoopMask v) +{ + return v.count() <= 1; +} #endif // __MEM_SNOOP_FILTER_HH__ diff -r e4f63f1d502d -r b8de61e29ce1 src/mem/snoop_filter.cc --- a/src/mem/snoop_filter.cc Sun Jun 21 20:52:13 2015 +0100 +++ b/src/mem/snoop_filter.cc Thu Jun 25 12:00:53 2015 +0900 @@ -65,7 +65,7 @@ totRequests++; if (is_hit) { // Single bit set -> value is a power of two - if (isPow2(interested)) + if (isMaskPow2(interested)) hitSingleRequests++; else hitMultiRequests++; @@ -77,7 +77,7 @@ if (!cpkt->req->isUncacheable() && cpkt->needsResponse()) { if (!cpkt->memInhibitAsserted()) { // Max one request per address per port - panic_if(sf_item.requested & req_port, "double request :( "\ + panic_if((sf_item.requested & req_port).any(), "double request :( "\ "SF value %x.%x\n", sf_item.requested, sf_item.holder); // Mark in-flight requests to distinguish later on @@ -87,7 +87,7 @@ // to the CPU, already -> the response will not be seen by this // filter -> we do not need to keep the in-flight request, but make // sure that we know that that cluster has a copy - panic_if(!(sf_item.holder & req_port), "Need to hold the value!"); + panic_if((sf_item.holder & req_port).none(), "Need to hold the value!"); DPRINTF(SnoopFilter, "%s: not marking request. SF value %x.%x\n", __func__, sf_item.requested, sf_item.holder); } @@ -126,9 +126,9 @@ // snoop filter; WRITEBACKs for now only if (cpkt->cmd == MemCmd::Writeback) { // make sure that the sender actually had the line - panic_if(sf_item.requested & req_port, "double request :( "\ + panic_if((sf_item.requested & req_port).any(), "double request :( "\ "SF value %x.%x\n", sf_item.requested, sf_item.holder); - panic_if(!(sf_item.holder & req_port), "requester %x is not a "\ + panic_if((sf_item.holder & req_port).none(), "requester %x is not a "\ "holder :( SF value %x.%x\n", req_port, sf_item.requested, sf_item.holder); // Writebacks -> the sender does not have the line anymore @@ -169,14 +169,14 @@ totSnoops++; if (is_hit) { // Single bit set -> value is a power of two - if (isPow2(interested)) + if (isMaskPow2(interested)) hitSingleSnoops++; else hitMultiSnoops++; } assert(cpkt->isInvalidate() == cpkt->needsExclusive()); - if (cpkt->isInvalidate() && !sf_item.requested) { + if (cpkt->isInvalidate() && sf_item.requested.none()) { // Early clear of the holder, if no other request is currently going on // @todo: This should possibly be updated even though we do not filter // upward snoops @@ -213,11 +213,11 @@ __func__, sf_item.requested, sf_item.holder); // The source should have the line - panic_if(!(sf_item.holder & rsp_mask), "SF value %x.%x does not have "\ + panic_if((sf_item.holder & rsp_mask).none(), "SF value %x.%x does not have "\ "the line\n", sf_item.requested, sf_item.holder); // The destination should have had a request in - panic_if(!(sf_item.requested & req_mask), "SF value %x.%x missing "\ + panic_if((sf_item.requested & req_mask).none(), "SF value %x.%x missing "\ "the original request\n", sf_item.requested, sf_item.holder); // Update the residency of the cache line. @@ -289,7 +289,7 @@ __func__, sf_item.requested, sf_item.holder); // Make sure we have seen the actual request, too - panic_if(!(sf_item.requested & slave_mask), "SF value %x.%x missing "\ + panic_if((sf_item.requested & slave_mask).none(), "SF value %x.%x missing "\ "request bit\n", sf_item.requested, sf_item.holder); // Update the residency of the cache line.