#if defined(__GNUC__) && __GNUC__ >= 3
#include <ext/hash_map>
+#include <ext/hash_set>
#else
#include <hash_map>
+#include <hash_set>
#endif
#include <string>
namespace m5 {
using ::__hash_namespace::hash_multimap;
+ using ::__hash_namespace::hash_multiset;
using ::__hash_namespace::hash_map;
+ using ::__hash_namespace::hash_set;
using ::__hash_namespace::hash;
}
return (__stl_hash_string(r.first.c_str())) ^ r.second;
}
};
-
-
-
-}
-
+/* namespace __hash_namespace */ }
#endif // __HASHMAP_HH__
void
operator()(const T &elem)
{
- out << elem;
// First one doesn't get a space before it. The rest do.
if (first)
first = false;
else
out << " ";
+
+ out << elem;
}
};
#include "cpu/rubytest/Check.hh"
#include "cpu/rubytest/CheckTable.hh"
#include "cpu/rubytest/CheckTable.hh"
-#include "mem/gems_common/Map.hh"
CheckTable::CheckTable(int _num_cpu_sequencers, RubyTester* _tester)
: m_num_cpu_sequencers(_num_cpu_sequencers), m_tester_ptr(_tester)
{
- m_lookup_map_ptr = new Map<Address, Check*>;
physical_address_t physical = 0;
Address address;
int size = m_check_vector.size();
for (int i = 0; i < size; i++)
delete m_check_vector[i];
- delete m_lookup_map_ptr;
}
void
}
for (int i = 0; i < CHECK_SIZE; i++) {
- if (m_lookup_map_ptr->exist(Address(address.getAddress()+i))) {
+ if (m_lookup_map.count(Address(address.getAddress()+i))) {
// A mapping for this byte already existed, discard the
// entire check
return;
m_num_cpu_sequencers, m_tester_ptr);
for (int i = 0; i < CHECK_SIZE; i++) {
// Insert it once per byte
- m_lookup_map_ptr->add(Address(address.getAddress() + i), check_ptr);
+ m_lookup_map[Address(address.getAddress() + i)] = check_ptr;
}
m_check_vector.push_back(check_ptr);
}
DEBUG_MSG(TESTER_COMP, MedPrio, "Looking for check by address");
DEBUG_EXPR(TESTER_COMP, MedPrio, address);
- if (m_lookup_map_ptr->exist(address)) {
- Check* check = m_lookup_map_ptr->lookup(address);
- assert(check != NULL);
- return check;
- } else {
+ m5::hash_map<Address, Check*>::iterator i = m_lookup_map.find(address);
+
+ if (i == m_lookup_map.end())
return NULL;
- }
+
+ Check* check = i->second;
+ assert(check != NULL);
+ return check;
}
void
#include <iostream>
#include <vector>
+#include "base/hashmap.hh"
+#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
-class Address;
class Check;
class RubyTester;
-template <class KEY_TYPE, class VALUE_TYPE> class Map;
class CheckTable
{
CheckTable& operator=(const CheckTable& obj);
std::vector<Check*> m_check_vector;
- Map<Address, Check*>* m_lookup_map_ptr;
+ m5::hash_map<Address, Check*> m_lookup_map;
int m_num_cpu_sequencers;
RubyTester* m_tester_ptr;
+++ /dev/null
-/*
- * Copyright (c) 1999-2005 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- */
-
-#ifndef MAP_H
-#define MAP_H
-
-#include <cassert>
-#include <iostream>
-#include <vector>
-
-#include "base/hashmap.hh"
-
-template <class KEY_TYPE, class VALUE_TYPE>
-class Map
-{
- private:
- typedef typename m5::hash_map<KEY_TYPE, VALUE_TYPE> MapType;
- typedef typename MapType::iterator iterator;
- typedef typename MapType::const_iterator const_iterator;
-
-public:
- Map() { /* empty */ }
- ~Map() { /* empty */ }
-
- void add(const KEY_TYPE& key, const VALUE_TYPE& value);
- bool exist(const KEY_TYPE& key) const;
- int size() const { return m_map.size(); }
- void erase(const KEY_TYPE& key) { assert(exist(key)); m_map.erase(key); }
- std::vector<KEY_TYPE> keys() const;
- std::vector<VALUE_TYPE> values() const;
- void deleteKeys();
- void deleteValues();
- VALUE_TYPE& lookup(const KEY_TYPE& key) const;
- void clear() { m_map.clear(); }
- void print(std::ostream& out) const;
-
- // Synonyms
- void remove(const KEY_TYPE& key) { erase(key); }
- void deallocate(const KEY_TYPE& key) { erase(key); }
- void allocate(const KEY_TYPE& key) { add(key, VALUE_TYPE()); }
- void insert(const KEY_TYPE& key, const VALUE_TYPE& value) { add(key, value); }
-
- // Use default copy constructor and assignment operator
-private:
- // Data members
-
- // m_map is declared mutable because some methods from the STL "map"
- // class that should be const are not. Thus we define this as
- // mutable so we can still have conceptually const accessors.
- mutable m5::hash_map<KEY_TYPE, VALUE_TYPE> m_map;
-};
-
-template <class KEY_TYPE, class VALUE_TYPE>
-std::ostream&
-operator<<(std::ostream& out, const Map<KEY_TYPE, VALUE_TYPE>& map);
-
-// *********************
-
-template <class KEY_TYPE, class VALUE_TYPE>
-void Map<KEY_TYPE, VALUE_TYPE>::add(const KEY_TYPE& key, const VALUE_TYPE& value)
-{
- // Update or add a new key/value pair
- m_map[key] = value;
-}
-
-template <class KEY_TYPE, class VALUE_TYPE>
-bool Map<KEY_TYPE, VALUE_TYPE>::exist(const KEY_TYPE& key) const
-{
- return (m_map.count(key) != 0);
-}
-
-template <class KEY_TYPE, class VALUE_TYPE>
-VALUE_TYPE& Map<KEY_TYPE, VALUE_TYPE>::lookup(const KEY_TYPE& key) const
-{
- if (!exist(key))
- std::cerr << *this << " is looking for " << key << std::endl;
- assert(exist(key));
- return m_map[key];
-}
-
-template <class KEY_TYPE, class VALUE_TYPE>
-std::vector<KEY_TYPE> Map<KEY_TYPE, VALUE_TYPE>::keys() const
-{
- std::vector<KEY_TYPE> keys(m_map.size());
- const_iterator iter = m_map.begin();
- for (int i = 0; i < m_map.size(); ++i) {
- keys[i] = iter->first;
- ++iter;
- }
- assert(iter == m_map.end());
- return keys;
-}
-
-template <class KEY_TYPE, class VALUE_TYPE>
-std::vector<VALUE_TYPE> Map<KEY_TYPE, VALUE_TYPE>::values() const
-{
- std::vector<VALUE_TYPE> values(m_map.size());
- const_iterator iter = m_map.begin();
-
- for (int i = 0; i < m_map.size(); ++i) {
- values[i] = iter->second;
- ++iter;
- }
- assert(iter == m_map.end());
- return values;
-}
-
-template <class KEY_TYPE, class VALUE_TYPE>
-void Map<KEY_TYPE, VALUE_TYPE>::deleteKeys()
-{
- const_iterator iter;
- std::pair<KEY_TYPE, VALUE_TYPE> p;
-
- for (iter = m_map.begin(); iter != m_map.end(); iter++) {
- p = *iter;
- delete p.first;
- }
-}
-
-template <class KEY_TYPE, class VALUE_TYPE>
-void Map<KEY_TYPE, VALUE_TYPE>::deleteValues()
-{
- const_iterator iter;
- std::pair<KEY_TYPE, VALUE_TYPE> p;
-
- for (iter = m_map.begin(); iter != m_map.end(); iter++) {
- p = *iter;
- delete p.second;
- }
-}
-
-template <class KEY_TYPE, class VALUE_TYPE>
-void Map<KEY_TYPE, VALUE_TYPE>::print(std::ostream& out) const
-{
- const_iterator iter;
- std::pair<KEY_TYPE, VALUE_TYPE> p;
-
- out << "[";
- for (iter = m_map.begin(); iter != m_map.end(); iter++) {
- // unparse each basic block
- p = *iter;
- out << " " << p.first << "=" << p.second;
- }
- out << " ]";
-}
-
-template <class KEY_TYPE, class VALUE_TYPE>
-std::ostream&
-operator<<(std::ostream& out, const Map<KEY_TYPE, VALUE_TYPE>& map)
-{
- map.print(out);
- return out;
-}
-
-#endif //MAP_H
#include "base/intmath.hh"
#include "base/str.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Address.hh"
#include "mem/ruby/filters/BlockBloomFilter.hh"
using namespace std;
#include "base/intmath.hh"
#include "base/str.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Address.hh"
#include "mem/ruby/filters/BulkBloomFilter.hh"
using namespace std;
#include "base/intmath.hh"
#include "base/str.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Address.hh"
#include "mem/ruby/filters/H3BloomFilter.hh"
using namespace std;
#include "base/intmath.hh"
#include "base/str.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Address.hh"
#include "mem/ruby/filters/LSB_CountingBloomFilter.hh"
using namespace std;
#include "base/intmath.hh"
#include "base/str.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Address.hh"
#include "mem/ruby/filters/MultiBitSelBloomFilter.hh"
using namespace std;
#include "base/intmath.hh"
#include "base/str.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Address.hh"
#include "mem/ruby/filters/MultiGrainBloomFilter.hh"
using namespace std;
#include "base/intmath.hh"
#include "base/str.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/ruby/common/Address.hh"
#include "mem/ruby/filters/NonCountingBloomFilter.hh"
using namespace std;
*/
#include "base/stl_helpers.hh"
-#include "mem/gems_common/Map.hh"
#include "mem/protocol/MachineType.hh"
#include "mem/protocol/Protocol.hh"
#include "mem/protocol/TopologyType.hh"
#include "mem/ruby/common/Histogram.hh"
#include "mem/ruby/profiler/AccessTraceForAddress.hh"
-AccessTraceForAddress::AccessTraceForAddress()
-{
- m_histogram_ptr = NULL;
-}
-
-AccessTraceForAddress::AccessTraceForAddress(const Address& addr)
-{
- m_addr = addr;
- m_total = 0;
- m_loads = 0;
- m_stores = 0;
- m_atomics = 0;
- m_user = 0;
- m_sharing = 0;
- m_histogram_ptr = NULL;
-}
-
AccessTraceForAddress::~AccessTraceForAddress()
{
- if (m_histogram_ptr != NULL) {
+ if (m_histogram_ptr) {
delete m_histogram_ptr;
m_histogram_ptr = NULL;
}
class AccessTraceForAddress
{
public:
- AccessTraceForAddress();
- explicit AccessTraceForAddress(const Address& addr);
+ AccessTraceForAddress()
+ : m_loads(0), m_stores(0), m_atomics(0), m_total(0), m_user(0),
+ m_sharing(0), m_histogram_ptr(NULL)
+ { }
~AccessTraceForAddress();
+ void setAddress(const Address& addr) { m_addr = addr; }
void update(CacheRequestType type, AccessModeType access_mode, NodeID cpu,
bool sharing_miss);
int getTotal() const;
#include <vector>
#include "base/stl_helpers.hh"
-#include "mem/gems_common/Map.hh"
#include "mem/gems_common/PrioHeap.hh"
#include "mem/protocol/CacheMsg.hh"
-#include "mem/ruby/profiler/AccessTraceForAddress.hh"
#include "mem/ruby/profiler/AddressProfiler.hh"
#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/system/System.hh"
// Helper functions
AccessTraceForAddress&
-lookupTraceForAddress(const Address& addr, AddressMap* record_map)
+lookupTraceForAddress(const Address& addr, AddressMap& record_map)
{
- if (!record_map->exist(addr)) {
- record_map->add(addr, AccessTraceForAddress(addr));
+ // we create a static default object here that is used to insert
+ // since the insertion will create a copy of the object in the
+ // process. Perhaps this is optimizing early, but it doesn't seem
+ // like it could hurt.
+ static const AccessTraceForAddress dflt;
+
+ pair<AddressMap::iterator, bool> r =
+ record_map.insert(make_pair(addr, dflt));
+ AddressMap::iterator i = r.first;
+ AccessTraceForAddress &access_trace = i->second;
+ if (r.second) {
+ // there was nothing there and the insert succeed, so we need
+ // to actually set the address.
+ access_trace.setAddress(addr);
}
- return record_map->lookup(addr);
+
+ return access_trace;
}
void
-printSorted(ostream& out, int num_of_sequencers, const AddressMap* record_map,
+printSorted(ostream& out, int num_of_sequencers, const AddressMap &record_map,
string description)
{
const int records_printed = 100;
uint64 misses = 0;
- PrioHeap<AccessTraceForAddress*> heap;
- std::vector<Address> keys = record_map->keys();
- for (int i = 0; i < keys.size(); i++) {
- AccessTraceForAddress* record = &(record_map->lookup(keys[i]));
+ PrioHeap<const AccessTraceForAddress*> heap;
+
+ AddressMap::const_iterator i = record_map.begin();
+ AddressMap::const_iterator end = record_map.end();
+ for (; i != end; ++i) {
+ const AccessTraceForAddress* record = &i->second;
misses += record->getTotal();
heap.insert(record);
}
- out << "Total_entries_" << description << ": " << keys.size() << endl;
+ out << "Total_entries_" << description << ": " << record_map.size()
+ << endl;
if (g_system_ptr->getProfiler()->getAllInstructions())
out << "Total_Instructions_" << description << ": " << misses << endl;
else
int counter = 0;
while (heap.size() > 0 && counter < records_printed) {
- AccessTraceForAddress* record = heap.extractMin();
+ const AccessTraceForAddress* record = heap.extractMin();
double percent = 100.0 * (record->getTotal() / double(misses));
out << description << " | " << percent << " % " << *record << endl;
all_records.add(record->getTotal());
}
while (heap.size() > 0) {
- AccessTraceForAddress* record = heap.extractMin();
+ const AccessTraceForAddress* record = heap.extractMin();
all_records.add(record->getTotal());
remaining_records.add(record->getTotal());
all_records_log.add(record->getTotal());
AddressProfiler::AddressProfiler(int num_of_sequencers)
{
- m_dataAccessTrace = new AddressMap;
- m_macroBlockAccessTrace = new AddressMap;
- m_programCounterAccessTrace = new AddressMap;
- m_retryProfileMap = new AddressMap;
m_num_of_sequencers = num_of_sequencers;
clearStats();
}
AddressProfiler::~AddressProfiler()
{
- delete m_dataAccessTrace;
- delete m_macroBlockAccessTrace;
- delete m_programCounterAccessTrace;
- delete m_retryProfileMap;
}
void
{
// Clear the maps
m_sharing_miss_counter = 0;
- m_dataAccessTrace->clear();
- m_macroBlockAccessTrace->clear();
- m_programCounterAccessTrace->clear();
- m_retryProfileMap->clear();
+ m_dataAccessTrace.clear();
+ m_macroBlockAccessTrace.clear();
+ m_programCounterAccessTrace.clear();
+ m_retryProfileMap.clear();
m_retryProfileHisto.clear();
m_retryProfileHistoRead.clear();
m_retryProfileHistoWrite.clear();
#include <iostream>
+#include "base/hashmap.hh"
#include "mem/protocol/AccessType.hh"
#include "mem/protocol/CacheMsg.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Histogram.hh"
+#include "mem/ruby/profiler/AccessTraceForAddress.hh"
#include "mem/ruby/system/NodeID.hh"
-class AccessTraceForAddress;
class Set;
-template <class KEY_TYPE, class VALUE_TYPE> class Map;
class AddressProfiler
{
public:
- typedef Map<Address, AccessTraceForAddress> AddressMap;
+ typedef m5::hash_map<Address, AccessTraceForAddress> AddressMap;
public:
AddressProfiler(int num_of_sequencers);
int64 m_sharing_miss_counter;
- AddressMap* m_dataAccessTrace;
- AddressMap* m_macroBlockAccessTrace;
- AddressMap* m_programCounterAccessTrace;
- AddressMap* m_retryProfileMap;
+ AddressMap m_dataAccessTrace;
+ AddressMap m_macroBlockAccessTrace;
+ AddressMap m_programCounterAccessTrace;
+ AddressMap m_retryProfileMap;
Histogram m_retryProfileHisto;
Histogram m_retryProfileHistoWrite;
Histogram m_retryProfileHistoRead;
*/
#include "mem/gems_common/PrioHeap.hh"
-#include "mem/ruby/profiler/AccessTraceForAddress.hh"
#include "mem/ruby/profiler/CacheProfiler.hh"
#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/system/System.hh"
#include "base/stl_helpers.hh"
#include "base/str.hh"
-#include "mem/gems_common/Map.hh"
#include "mem/gems_common/PrioHeap.hh"
#include "mem/protocol/CacheMsg.hh"
#include "mem/protocol/MachineType.hh"
Profiler::Profiler(const Params *p)
: SimObject(p)
{
- m_requestProfileMap_ptr = new Map<string, int>;
-
m_inst_profiler_ptr = NULL;
m_address_profiler_ptr = NULL;
if (m_periodic_output_file_ptr != &cerr) {
delete m_periodic_output_file_ptr;
}
-
- delete m_requestProfileMap_ptr;
}
void
out << "--------------------------------" << endl;
out << endl;
- vector<string> requestProfileKeys = m_requestProfileMap_ptr->keys();
- sort(requestProfileKeys.begin(), requestProfileKeys.end());
+ map<string, int>::const_iterator i = m_requestProfileMap.begin();
+ map<string, int>::const_iterator end = m_requestProfileMap.end();
+ for (; i != end; ++i) {
+ const string &key = i->first;
+ int count = i->second;
- for (int i = 0; i < requestProfileKeys.size(); i++) {
- int temp_int =
- m_requestProfileMap_ptr->lookup(requestProfileKeys[i]);
- double percent = (100.0 * double(temp_int)) / double(m_requests);
+ double percent = (100.0 * double(count)) / double(m_requests);
vector<string> items;
- tokenize(items, requestProfileKeys[i], ':');
- vector<string>::iterator i = items.begin();
+ tokenize(items, key, ':');
+ vector<string>::iterator j = items.begin();
vector<string>::iterator end = items.end();
- for (; i != end; ++i)
- out << setw(10) << *i;
- out << setw(11) << temp_int;
+ for (; j != end; ++i)
+ out << setw(10) << *j;
+ out << setw(11) << count;
out << setw(14) << percent << endl;
}
out << endl;
m_memory_to_cache = 0;
// clear HashMaps
- m_requestProfileMap_ptr->clear();
+ m_requestProfileMap.clear();
// count requests profiled
m_requests = 0;
{
m_requests++;
- if (m_requestProfileMap_ptr->exist(requestStr)) {
- (m_requestProfileMap_ptr->lookup(requestStr))++;
- } else {
- m_requestProfileMap_ptr->add(requestStr, 1);
- }
+ // if it doesn't exist, conveniently, it will be created with the
+ // default value which is 0
+ m_requestProfileMap[requestStr]++;
}
void
out << setw(ID_SPACES) << id << " "
<< "RUBY WATCH " << watch_address << endl;
- if (!m_watch_address_list_ptr->exist(watch_address)) {
- m_watch_address_list_ptr->add(watch_address, 1);
- }
+ // don't care about success or failure
+ m_watch_address_set.insert(watch_address);
}
bool
Profiler::watchAddress(Address addr)
{
- if (m_watch_address_list_ptr->exist(addr))
- return true;
- else
- return false;
+ return m_watch_address_set.count(addr) > 0;
}
Profiler *
#define __MEM_RUBY_PROFILER_PROFILER_HH__
#include <iostream>
+#include <map>
#include <string>
#include <vector>
+#include "base/hashmap.hh"
#include "mem/protocol/AccessModeType.hh"
#include "mem/protocol/AccessType.hh"
#include "mem/protocol/CacheRequestType.hh"
class CacheMsg;
class AddressProfiler;
-template <class KEY_TYPE, class VALUE_TYPE> class Map;
-
class Profiler : public SimObject, public Consumer
{
public:
Histogram m_average_latency_estimate;
- Map<Address, int>* m_watch_address_list_ptr;
+ m5::hash_set<Address> m_watch_address_set;
// counts all initiated cache request including PUTs
int m_requests;
- Map <std::string, int>* m_requestProfileMap_ptr;
+ std::map<std::string, int> m_requestProfileMap;
//added by SS
bool m_hot_lines;
*/
#include "base/cprintf.hh"
-#include "mem/gems_common/Map.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/common/Global.hh"
#include <list>
#include <string>
-#include "mem/gems_common/Map.hh"
#include "mem/protocol/MemoryMsg.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Consumer.hh"
#ifndef __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__
#define __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__
-#include "mem/gems_common/Map.hh"
+#include "base/hashmap.hh"
#include "mem/protocol/AccessPermission.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
PerfectCacheMemory& operator=(const PerfectCacheMemory& obj);
// Data Members (m_prefix)
- Map<Address, PerfectCacheLineState<ENTRY> > m_map;
+ m5::hash_map<Address, PerfectCacheLineState<ENTRY> > m_map;
};
template<class ENTRY>
inline bool
PerfectCacheMemory<ENTRY>::isTagPresent(const Address& address) const
{
- return m_map.exist(line_address(address));
+ return m_map.count(line_address(address)) > 0;
}
template<class ENTRY>
PerfectCacheLineState<ENTRY> line_state;
line_state.m_permission = AccessPermission_Busy;
line_state.m_entry = ENTRY();
- m_map.add(line_address(address), line_state);
+ m_map[line_address(address)] = line_state;
}
// deallocate entry
inline ENTRY&
PerfectCacheMemory<ENTRY>::lookup(const Address& address)
{
- return m_map.lookup(line_address(address)).m_entry;
+ return m_map[line_address(address)].m_entry;
}
// looks an address up in the cache
inline const ENTRY&
PerfectCacheMemory<ENTRY>::lookup(const Address& address) const
{
- return m_map.lookup(line_address(address)).m_entry;
+ return m_map[line_address(address)].m_entry;
}
template<class ENTRY>
inline AccessPermission
PerfectCacheMemory<ENTRY>::getPermission(const Address& address) const
{
- return m_map.lookup(line_address(address)).m_permission;
+ return m_map[line_address(address)].m_permission;
}
template<class ENTRY>
{
Address line_address = address;
line_address.makeLineAddress();
- PerfectCacheLineState<ENTRY>& line_state = m_map.lookup(line_address);
+ PerfectCacheLineState<ENTRY>& line_state = m_map[line_address];
AccessPermission old_perm = line_state.m_permission;
line_state.m_permission = new_perm;
}
PersistentTable::PersistentTable()
{
- m_map_ptr = new Map<Address, PersistentTableEntry>;
}
PersistentTable::~PersistentTable()
{
- delete m_map_ptr;
- m_map_ptr = NULL;
}
void
#endif
assert(address == line_address(address));
- if (!m_map_ptr->exist(address)) {
- // Allocate if not present
- PersistentTableEntry entry;
- entry.m_starving.add(locker);
- if (type == AccessType_Write) {
- entry.m_request_to_write.add(locker);
- }
- m_map_ptr->add(address, entry);
- } else {
- PersistentTableEntry& entry = m_map_ptr->lookup(address);
- //
+ static const PersistentTableEntry dflt;
+ pair<AddressMap::iterator, bool> r =
+ m_map.insert(AddressMap::value_type(address, dflt));
+ bool present = !r.second;
+ AddressMap::iterator i = r.first;
+ PersistentTableEntry &entry = i->second;
+
+ if (present) {
// Make sure we're not already in the locked set
- //
assert(!(entry.m_starving.isElement(locker)));
+ }
- entry.m_starving.add(locker);
- if (type == AccessType_Write) {
- entry.m_request_to_write.add(locker);
- }
+ entry.m_starving.add(locker);
+ if (type == AccessType_Write)
+ entry.m_request_to_write.add(locker);
+
+ if (present)
assert(entry.m_marked.isSubset(entry.m_starving));
- }
}
void
#endif
assert(address == line_address(address));
- assert(m_map_ptr->exist(address));
- PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ assert(m_map.count(address));
+ PersistentTableEntry& entry = m_map[address];
//
// Make sure we're in the locked set
// Deallocate if empty
if (entry.m_starving.isEmpty()) {
assert(entry.m_marked.isEmpty());
- m_map_ptr->erase(address);
+ m_map.erase(address);
}
}
MachineID machId) const
{
assert(address == line_address(address));
- if (!m_map_ptr->exist(address)) {
+
+ AddressMap::const_iterator i = m_map.find(address);
+ if (i == m_map.end()) {
// No entry present
return true;
- } else if (m_map_ptr->lookup(address).m_starving.isElement(machId)) {
+ }
+
+ const PersistentTableEntry &entry = i->second;
+
+ if (entry.m_starving.isElement(machId)) {
// We can't issue another lockdown until are previous unlock
// has occurred
return false;
- } else {
- return m_map_ptr->lookup(address).m_marked.isEmpty();
}
+
+ return entry.m_marked.isEmpty();
}
MachineID
PersistentTable::findSmallest(const Address& address) const
{
assert(address == line_address(address));
- assert(m_map_ptr->exist(address));
- const PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ AddressMap::const_iterator i = m_map.find(address);
+ assert(i != m_map.end());
+ const PersistentTableEntry& entry = i->second;
return entry.m_starving.smallestElement();
}
PersistentTable::typeOfSmallest(const Address& address) const
{
assert(address == line_address(address));
- assert(m_map_ptr->exist(address));
- const PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ AddressMap::const_iterator i = m_map.find(address);
+ assert(i != m_map.end());
+ const PersistentTableEntry& entry = i->second;
if (entry.m_request_to_write.
isElement(entry.m_starving.smallestElement())) {
return AccessType_Write;
PersistentTable::markEntries(const Address& address)
{
assert(address == line_address(address));
- if (m_map_ptr->exist(address)) {
- PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ AddressMap::iterator i = m_map.find(address);
+ if (i == m_map.end())
+ return;
- // None should be marked
- assert(entry.m_marked.isEmpty());
+ PersistentTableEntry& entry = i->second;
- // Mark all the nodes currently in the table
- entry.m_marked = entry.m_starving;
- }
+ // None should be marked
+ assert(entry.m_marked.isEmpty());
+
+ // Mark all the nodes currently in the table
+ entry.m_marked = entry.m_starving;
}
bool
assert(address == line_address(address));
// If an entry is present, it must be locked
- return m_map_ptr->exist(address);
+ return m_map.count(address) > 0;
}
int
PersistentTable::countStarvingForAddress(const Address& address) const
{
- if (m_map_ptr->exist(address)) {
- PersistentTableEntry& entry = m_map_ptr->lookup(address);
- return (entry.m_starving.count());
- } else {
+ assert(address == line_address(address));
+ AddressMap::const_iterator i = m_map.find(address);
+ if (i == m_map.end())
return 0;
- }
+
+ const PersistentTableEntry& entry = i->second;
+ return entry.m_starving.count();
}
int
PersistentTable::countReadStarvingForAddress(const Address& address) const
{
- if (m_map_ptr->exist(address)) {
- PersistentTableEntry& entry = m_map_ptr->lookup(address);
- return (entry.m_starving.count() - entry.m_request_to_write.count());
- } else {
+ assert(address == line_address(address));
+ AddressMap::const_iterator i = m_map.find(address);
+ if (i == m_map.end())
return 0;
- }
+
+ const PersistentTableEntry& entry = i->second;
+ return entry.m_starving.count() - entry.m_request_to_write.count();
}
void
#include <iostream>
-#include "mem/gems_common/Map.hh"
+#include "base/hashmap.hh"
#include "mem/protocol/AccessType.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
PersistentTable& operator=(const PersistentTable& obj);
// Data Members (m_prefix)
- Map<Address, PersistentTableEntry>* m_map_ptr;
+ typedef m5::hash_map<Address, PersistentTableEntry> AddressMap;
+ AddressMap m_map;
};
inline std::ostream&
#include "base/str.hh"
#include "cpu/rubytest/RubyTester.hh"
-#include "mem/gems_common/Map.hh"
#include "mem/protocol/CacheMsg.hh"
#include "mem/protocol/Protocol.hh"
#include "mem/protocol/Protocol.hh"
// Check across all outstanding requests
int total_outstanding = 0;
- std::vector<Address> keys = m_readRequestTable.keys();
- for (int i = 0; i < keys.size(); i++) {
- SequencerRequest* request = m_readRequestTable.lookup(keys[i]);
- if (current_time - request->issue_time >= m_deadlock_threshold) {
- WARN_MSG("Possible Deadlock detected");
- WARN_EXPR(request);
- WARN_EXPR(m_version);
- WARN_EXPR(request->ruby_request.paddr);
- WARN_EXPR(keys.size());
- WARN_EXPR(current_time);
- WARN_EXPR(request->issue_time);
- WARN_EXPR(current_time - request->issue_time);
- ERROR_MSG("Aborting");
- }
+ RequestTable::iterator read = m_readRequestTable.begin();
+ RequestTable::iterator read_end = m_readRequestTable.end();
+ for (; read != read_end; ++read) {
+ SequencerRequest* request = read->second;
+ if (current_time - request->issue_time < m_deadlock_threshold)
+ continue;
+
+ WARN_MSG("Possible Deadlock detected");
+ WARN_EXPR(request);
+ WARN_EXPR(m_version);
+ WARN_EXPR(request->ruby_request.paddr);
+ WARN_EXPR(m_readRequestTable.size());
+ WARN_EXPR(current_time);
+ WARN_EXPR(request->issue_time);
+ WARN_EXPR(current_time - request->issue_time);
+ ERROR_MSG("Aborting");
}
- keys = m_writeRequestTable.keys();
- for (int i = 0; i < keys.size(); i++) {
- SequencerRequest* request = m_writeRequestTable.lookup(keys[i]);
- if (current_time - request->issue_time >= m_deadlock_threshold) {
- WARN_MSG("Possible Deadlock detected");
- WARN_EXPR(request);
- WARN_EXPR(m_version);
- WARN_EXPR(current_time);
- WARN_EXPR(request->issue_time);
- WARN_EXPR(current_time - request->issue_time);
- WARN_EXPR(keys.size());
- ERROR_MSG("Aborting");
- }
+ RequestTable::iterator write = m_writeRequestTable.begin();
+ RequestTable::iterator write_end = m_writeRequestTable.end();
+ for (; write != write_end; ++write) {
+ SequencerRequest* request = write->second;
+ if (current_time - request->issue_time < m_deadlock_threshold)
+ continue;
+
+ WARN_MSG("Possible Deadlock detected");
+ WARN_EXPR(request);
+ WARN_EXPR(m_version);
+ WARN_EXPR(current_time);
+ WARN_EXPR(request->issue_time);
+ WARN_EXPR(current_time - request->issue_time);
+ WARN_EXPR(m_writeRequestTable.size());
+ ERROR_MSG("Aborting");
}
total_outstanding += m_writeRequestTable.size();
out << "---------------" << endl;
out << "outstanding requests" << endl;
- std::vector<Address> rkeys = m_readRequestTable.keys();
- int read_size = rkeys.size();
- out << "proc " << m_version << " Read Requests = " << read_size << endl;
+ out << "proc " << m_Read
+ << " version Requests = " << m_readRequestTable.size() << endl;
// print the request table
- for (int i = 0; i < read_size; ++i) {
- SequencerRequest *request = m_readRequestTable.lookup(rkeys[i]);
+ RequestTable::iterator read = m_readRequestTable.begin();
+ RequestTable::iterator read_end = m_readRequestTable.end();
+ for (; read != read_end; ++read) {
+ SequencerRequest* request = read->second;
out << "\tRequest[ " << i << " ] = " << request->type
<< " Address " << rkeys[i]
<< " Posted " << request->issue_time
total_demand++;
}
- std::vector<Address> wkeys = m_writeRequestTable.keys();
- int write_size = wkeys.size();
- out << "proc " << m_version << " Write Requests = " << write_size << endl;
+ out << "proc " << m_version
+ << " Write Requests = " << m_writeRequestTable.size << endl;
// print the request table
- for (int i = 0; i < write_size; ++i){
- CacheMsg &request = m_writeRequestTable.lookup(wkeys[i]);
+ RequestTable::iterator write = m_writeRequestTable.begin();
+ RequestTable::iterator write_end = m_writeRequestTable.end();
+ for (; write != write_end; ++write) {
+ SequencerRequest* request = write->second;
out << "\tRequest[ " << i << " ] = " << request.getType()
<< " Address " << wkeys[i]
<< " Posted " << request.getTime()
(request->ruby_request.type == RubyRequestType_RMW_Write) ||
(request->ruby_request.type == RubyRequestType_Locked_Read) ||
(request->ruby_request.type == RubyRequestType_Locked_Write)) {
- if (m_writeRequestTable.exist(line_addr)) {
- m_writeRequestTable.lookup(line_addr) = request;
+ pair<RequestTable::iterator, bool> r =
+ m_writeRequestTable.insert(RequestTable::value_type(line_addr, 0));
+ bool success = r.second;
+ RequestTable::iterator i = r.first;
+ if (!success) {
+ i->second = request;
// return true;
// drh5: isn't this an error? do you lose the initial request?
assert(0);
}
- m_writeRequestTable.allocate(line_addr);
- m_writeRequestTable.lookup(line_addr) = request;
+ i->second = request;
m_outstanding_count++;
} else {
- if (m_readRequestTable.exist(line_addr)) {
- m_readRequestTable.lookup(line_addr) = request;
+ pair<RequestTable::iterator, bool> r =
+ m_readRequestTable.insert(RequestTable::value_type(line_addr, 0));
+ bool success = r.second;
+ RequestTable::iterator i = r.first;
+ if (!success) {
+ i->second = request;
// return true;
// drh5: isn't this an error? do you lose the initial request?
assert(0);
}
- m_readRequestTable.allocate(line_addr);
- m_readRequestTable.lookup(line_addr) = request;
+ i->second = request;
m_outstanding_count++;
}
return false;
}
+void
+Sequencer::markRemoved()
+{
+ m_outstanding_count--;
+ assert(m_outstanding_count ==
+ m_writeRequestTable.size() + m_readRequestTable.size());
+}
+
void
Sequencer::removeRequest(SequencerRequest* srequest)
{
(ruby_request.type == RubyRequestType_RMW_Write) ||
(ruby_request.type == RubyRequestType_Locked_Read) ||
(ruby_request.type == RubyRequestType_Locked_Write)) {
- m_writeRequestTable.deallocate(line_addr);
+ m_writeRequestTable.erase(line_addr);
} else {
- m_readRequestTable.deallocate(line_addr);
+ m_readRequestTable.erase(line_addr);
}
- m_outstanding_count--;
- assert(m_outstanding_count == m_writeRequestTable.size() + m_readRequestTable.size());
+ markRemoved();
}
void
Sequencer::writeCallback(const Address& address, DataBlock& data)
{
assert(address == line_address(address));
- assert(m_writeRequestTable.exist(line_address(address)));
+ assert(m_writeRequestTable.count(line_address(address)));
- SequencerRequest* request = m_writeRequestTable.lookup(address);
+ RequestTable::iterator i = m_writeRequestTable.find(address);
+ assert(i != m_writeRequestTable.end());
+ SequencerRequest* request = i->second;
- removeRequest(request);
+ m_writeRequestTable.erase(i);
+ markRemoved();
assert((request->ruby_request.type == RubyRequestType_ST) ||
(request->ruby_request.type == RubyRequestType_RMW_Read) ||
Sequencer::readCallback(const Address& address, DataBlock& data)
{
assert(address == line_address(address));
- assert(m_readRequestTable.exist(line_address(address)));
+ assert(m_readRequestTable.count(line_address(address)));
- SequencerRequest* request = m_readRequestTable.lookup(address);
- removeRequest(request);
+ RequestTable::iterator i = m_readRequestTable.find(address);
+ assert(i != m_readRequestTable.end());
+ SequencerRequest* request = i->second;
+
+ m_readRequestTable.erase(i);
+ markRemoved();
assert((request->ruby_request.type == RubyRequestType_LD) ||
(request->ruby_request.type == RubyRequestType_RMW_Read) ||
Sequencer::getRequestStatus(const RubyRequest& request)
{
bool is_outstanding_store =
- m_writeRequestTable.exist(line_address(Address(request.paddr)));
+ !!m_writeRequestTable.count(line_address(Address(request.paddr)));
bool is_outstanding_load =
- m_readRequestTable.exist(line_address(Address(request.paddr)));
+ !!m_readRequestTable.count(line_address(Address(request.paddr)));
if (is_outstanding_store) {
if ((request.type == RubyRequestType_LD) ||
(request.type == RubyRequestType_IFETCH) ||
bool
Sequencer::empty() const
{
- return m_writeRequestTable.size() == 0 && m_readRequestTable.size() == 0;
+ return m_writeRequestTable.empty() && m_readRequestTable.empty();
}
RequestStatus
}
#endif
+template <class KEY, class VALUE>
+std::ostream &
+operator<<(ostream &out, const m5::hash_map<KEY, VALUE> &map)
+{
+ typename m5::hash_map<KEY, VALUE>::const_iterator i = map.begin();
+ typename m5::hash_map<KEY, VALUE>::const_iterator end = map.end();
+
+ out << "[";
+ for (; i != end; ++i)
+ out << " " << i->first << "=" << i->second;
+ out << " ]";
+
+ return out;
+}
+
void
Sequencer::print(ostream& out) const
{
#include <iostream>
-#include "mem/gems_common/Map.hh"
+#include "base/hashmap.hh"
#include "mem/protocol/AccessModeType.hh"
#include "mem/protocol/CacheRequestType.hh"
#include "mem/protocol/GenericMachineType.hh"
void printStats(std::ostream& out) const;
void checkCoherence(const Address& address);
+ void markRemoved();
void removeRequest(SequencerRequest* request);
private:
CacheMemory* m_dataCache_ptr;
CacheMemory* m_instCache_ptr;
- Map<Address, SequencerRequest*> m_writeRequestTable;
- Map<Address, SequencerRequest*> m_readRequestTable;
+ typedef m5::hash_map<Address, SequencerRequest*> RequestTable;
+ RequestTable m_writeRequestTable;
+ RequestTable m_readRequestTable;
// Global outstanding request count, across all request tables
int m_outstanding_count;
bool m_deadlock_check_scheduled;
#include <iostream>
-#include "mem/gems_common/Map.hh"
+#include "base/hashmap.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/profiler/Profiler.hh"
TBETable& operator=(const TBETable& obj);
// Data Members (m_prefix)
- Map<Address, ENTRY> m_map;
+ m5::hash_map<Address, ENTRY> m_map;
private:
int m_number_of_TBEs;
{
assert(address == line_address(address));
assert(m_map.size() <= m_number_of_TBEs);
- return m_map.exist(address);
+ return !!m_map.count(address);
}
template<class ENTRY>
inline void
TBETable<ENTRY>::allocate(const Address& address)
{
- assert(isPresent(address) == false);
+ assert(!isPresent(address));
assert(m_map.size() < m_number_of_TBEs);
- m_map.add(address, ENTRY());
+ m_map[address] = ENTRY();
}
template<class ENTRY>
inline void
TBETable<ENTRY>::deallocate(const Address& address)
{
- assert(isPresent(address) == true);
+ assert(isPresent(address));
assert(m_map.size() > 0);
m_map.erase(address);
}
inline ENTRY&
TBETable<ENTRY>::lookup(const Address& address)
{
- assert(isPresent(address) == true);
- return m_map.lookup(address);
+ assert(isPresent(address));
+ return m_map.find(address)->second;
}
// looks an address up in the cache
inline const ENTRY&
TBETable<ENTRY>::lookup(const Address& address) const
{
- assert(isPresent(address) == true);
- return m_map.lookup(address);
+ assert(isPresent(address));
+ return m_map.find(address)->second;
}
template<class ENTRY>
bool
TimerTable::isReady() const
{
- if (m_map.size() == 0) {
+ if (m_map.empty())
return false;
- }
if (!m_next_valid) {
updateNext();
{
assert(address == line_address(address));
assert(relative_latency > 0);
- assert(m_map.exist(address) == false);
+ assert(!m_map.count(address));
Time ready_time = g_eventQueue_ptr->getTime() + relative_latency;
- m_map.add(address, ready_time);
+ m_map[address] = ready_time;
assert(m_consumer_ptr != NULL);
g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, ready_time);
m_next_valid = false;
TimerTable::unset(const Address& address)
{
assert(address == line_address(address));
- assert(m_map.exist(address) == true);
- m_map.remove(address);
+ assert(m_map.count(address));
+ m_map.erase(address);
// Don't always recalculate the next ready address
if (address == m_next_address) {
void
TimerTable::updateNext() const
{
- if (m_map.size() == 0) {
- assert(m_next_valid == false);
+ if (m_map.empty()) {
+ assert(!m_next_valid);
return;
}
- std::vector<Address> addresses = m_map.keys();
- m_next_address = addresses[0];
- m_next_time = m_map.lookup(m_next_address);
-
- // Search for the minimum time
- int size = addresses.size();
- for (int i=1; i<size; i++) {
- Address maybe_next_address = addresses[i];
- Time maybe_next_time = m_map.lookup(maybe_next_address);
- if (maybe_next_time < m_next_time) {
- m_next_time = maybe_next_time;
- m_next_address= maybe_next_address;
+ AddressMap::const_iterator i = m_map.begin();
+ AddressMap::const_iterator end = m_map.end();
+
+ m_next_address = i->first;
+ m_next_time = i->second;
+ ++i;
+
+ for (; i != end; ++i) {
+ if (i->second < m_next_time) {
+ m_next_address = i->first;
+ m_next_time = i->second;
}
}
+
m_next_valid = true;
}
#include <iostream>
#include <string>
-#include "mem/gems_common/Map.hh"
+#include "base/hashmap.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
bool isReady() const;
const Address& readyAddress() const;
- bool isSet(const Address& address) const { return m_map.exist(address); }
+ bool isSet(const Address& address) const { return !!m_map.count(address); }
void set(const Address& address, Time relative_latency);
void unset(const Address& address);
void print(std::ostream& out) const;
TimerTable& operator=(const TimerTable& obj);
// Data Members (m_prefix)
- Map<Address, Time> m_map;
+ typedef m5::hash_map<Address, Time> AddressMap;
+ AddressMap m_map;
mutable bool m_next_valid;
mutable Time m_next_time; // Only valid if m_next_valid is true
mutable Address m_next_address; // Only valid if m_next_valid is true