diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/base/addr_range_map.hh | 124 | ||||
-rw-r--r-- | src/mem/physical.cc | 10 | ||||
-rw-r--r-- | src/mem/xbar.cc | 11 | ||||
-rw-r--r-- | src/unittest/rangemaptest.cc | 11 |
4 files changed, 95 insertions, 61 deletions
diff --git a/src/base/addr_range_map.hh b/src/base/addr_range_map.hh index 30bd62456..5c627bef5 100644 --- a/src/base/addr_range_map.hh +++ b/src/base/addr_range_map.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 ARM Limited + * Copyright (c) 2012, 2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -59,71 +59,63 @@ class AddrRangeMap { private: typedef std::map<AddrRange, V> RangeMap; - RangeMap tree; public: typedef typename RangeMap::iterator iterator; typedef typename RangeMap::const_iterator const_iterator; + /** + * Find entry that contains the given address range + * + * Searches through the ranges in the address map and returns an + * iterator to the entry which range is a superset of the input + * address range. Returns end() if none found. + * + * @param r An input address range + * @return An iterator that contains the input address range + */ const_iterator - find(const AddrRange &r) const + contains(const AddrRange &r) const { - if (tree.empty()) - return tree.end(); - - const_iterator i = tree.upper_bound(r); - - if (i == tree.begin()) { - if (i->first.intersects(r)) { - return i; - } else { - return tree.end(); - } - } - - --i; - - if (i->first.intersects(r)) - return i; - - // if we are looking at an interleaved range, also step - // backwards through the ranges while we are looking at ranges - // that are part of the same contigous chunk - if (i->first.interleaved()) { - AddrRange orig_range = i->first; - - while (i != tree.begin() && i->first.mergesWith(orig_range)) { - --i; - if (i->first.intersects(r)) { - return i; - } - } - - // we could leave the loop based on reaching the first - // element, so we must still check for an intersection - if (i->first.intersects(r)) - return i; - } - - return tree.end(); + return find(r, [r](const AddrRange r1) { return r.isSubset(r1); }); } + /** + * Find entry that contains the given address + * + * Searches through the ranges in the address map and returns an + * iterator to the entry which range is a superset of the input + * address. Returns end() if none found. + * + * @param r An input address + * @return An iterator that contains the input address + */ const_iterator - find(const Addr &r) const + contains(Addr r) const { - return find(RangeSize(r, 1)); + return contains(RangeSize(r, 1)); } - bool - intersect(const AddrRange &r) const + /** + * Find entry that intersects with the given address range + * + * Searches through the ranges in the address map and returns an + * iterator to the first entry which range intersects with the + * input address. + * + * @param r An input address + * @return An iterator that intersects with the input address range + */ + const_iterator + intersects(const AddrRange &r) const { - return find(r) != tree.end(); + return find(r, [r](const AddrRange r1) { return r.intersects(r1); }); } const_iterator insert(const AddrRange &r, const V& d) { - if (intersect(r)) + if (intersects(r) != end()) return tree.end(); return tree.insert(std::make_pair(r, d)).first; @@ -182,6 +174,44 @@ class AddrRangeMap { return tree.empty(); } + + private: + /** + * Find entry that satisfies a condition on an address range + * + * Searches through the ranges in the address map and returns an + * iterator to the entry that satisfies the input conidition on + * the input address range. Returns end() if none found. + * + * @param r An input address range + * @param f A condition on an address range + * @return An iterator that contains the input address range + */ + const_iterator + find(const AddrRange &r, std::function<bool(const AddrRange)> cond) const + { + const_iterator next = tree.upper_bound(r); + if (next != end() && cond(next->first)) { + return next; + } + if (next == begin()) + return end(); + next--; + + const_iterator i; + do { + i = next; + if (cond(i->first)) { + return i; + } + // Keep looking if the next range merges with the current one. + } while (next != begin() && + (--next)->first.mergesWith(i->first)); + + return end(); + } + + RangeMap tree; }; #endif //__BASE_ADDR_RANGE_MAP_HH__ diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 586f1c475..c7dbb3bcb 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014 ARM Limited + * Copyright (c) 2012, 2014, 2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -241,7 +241,7 @@ PhysicalMemory::isMemAddr(Addr addr) const return true; } else { // lookup in the interval tree - const auto& r = addrMap.find(addr); + const auto& r = addrMap.contains(addr); if (r == addrMap.end()) { // not in the cache, and not in the tree return false; @@ -298,7 +298,7 @@ PhysicalMemory::access(PacketPtr pkt) } else { // do not update the cache here, as we typically call // isMemAddr before calling access - const auto& m = addrMap.find(addr); + const auto& m = addrMap.contains(addr); assert(m != addrMap.end()); m->second->access(pkt); } @@ -314,7 +314,7 @@ PhysicalMemory::functionalAccess(PacketPtr pkt) } else { // do not update the cache here, as we typically call // isMemAddr before calling functionalAccess - const auto& m = addrMap.find(addr); + const auto& m = addrMap.contains(addr); assert(m != addrMap.end()); m->second->functionalAccess(pkt); } @@ -406,7 +406,7 @@ PhysicalMemory::unserialize(CheckpointIn &cp) UNSERIALIZE_CONTAINER(lal_addr); UNSERIALIZE_CONTAINER(lal_cid); for (size_t i = 0; i < lal_addr.size(); ++i) { - const auto& m = addrMap.find(lal_addr[i]); + const auto& m = addrMap.contains(lal_addr[i]); m->second->addLockedAddr(LockedAddr(lal_addr[i], lal_cid[i])); } diff --git a/src/mem/xbar.cc b/src/mem/xbar.cc index db0bf180e..1984a94aa 100644 --- a/src/mem/xbar.cc +++ b/src/mem/xbar.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015 ARM Limited + * Copyright (c) 2011-2015, 2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -333,7 +333,7 @@ BaseXBar::findPort(Addr addr) return dest_id; // Check the address map interval tree - auto i = portMap.find(addr); + auto i = portMap.contains(addr); if (i != portMap.end()) { dest_id = i->second; updatePortCache(dest_id, i->first); @@ -420,8 +420,9 @@ BaseXBar::recvRangeChange(PortID master_port_id) DPRINTF(AddrRanges, "Adding range %s for id %d\n", r.to_string(), master_port_id); if (portMap.insert(r, master_port_id) == portMap.end()) { - PortID conflict_id = portMap.find(r)->second; - fatal("%s has two ports responding within range %s:\n\t%s\n\t%s\n", + PortID conflict_id = portMap.intersects(r)->second; + fatal("%s has two ports responding within range " + "%s:\n\t%s\n\t%s\n", name(), r.to_string(), masterPorts[master_port_id]->getSlavePort().name(), @@ -496,7 +497,7 @@ BaseXBar::recvRangeChange(PortID master_port_id) } } - // also check that no range partially overlaps with the + // also check that no range partially intersects with the // default range, this has to be done after all ranges are set // as there are no guarantees for when the default range is // update with respect to the other ones diff --git a/src/unittest/rangemaptest.cc b/src/unittest/rangemaptest.cc index 6975f66ef..88e1c4d66 100644 --- a/src/unittest/rangemaptest.cc +++ b/src/unittest/rangemaptest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 ARM Limited + * Copyright (c) 2012, 2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -59,11 +59,14 @@ main() i = r.insert(RangeIn(60, 90), 3); assert(i != r.end()); - i = r.find(RangeIn(20, 30)); + i = r.intersects(RangeIn(20, 30)); assert(i != r.end()); cout << i->first.to_string() << " " << i->second << endl; - i = r.find(RangeIn(55, 55)); + i = r.contains(RangeIn(55, 55)); + assert(i == r.end()); + + i = r.intersects(RangeIn(55, 55)); assert(i == r.end()); i = r.insert(RangeIn(0, 12), 1); @@ -72,7 +75,7 @@ main() i = r.insert(RangeIn(0, 9), 1); assert(i != r.end()); - i = r.find(RangeIn(20, 30)); + i = r.contains(RangeIn(20, 30)); assert(i != r.end()); cout << i->first.to_string() << " " << i->second << endl; |