Ruby: Ensure order-dependent iteration uses an ordered map
authorAndreas Hansson <andreas.hansson@arm.com>
Thu, 12 Apr 2012 12:35:49 +0000 (08:35 -0400)
committerAndreas Hansson <andreas.hansson@arm.com>
Thu, 12 Apr 2012 12:35:49 +0000 (08:35 -0400)
This patch fixes a bug in Ruby that caused non-deterministic
simulation when changing the underlying hash map implementation. The
reason is order-dependent behaviour in combination with iteration over
the hash map contents. The two locations where a sorted container is
assumed are now changed to make use of a std::map instead of the
unordered hash map.

With this change, the stats changes slightly and the follow-on
changeset will update the relevant statistics.

src/mem/ruby/buffers/MessageBuffer.hh
src/mem/ruby/system/TimerTable.hh
src/mem/slicc/symbols/StateMachine.py

index dc9fb1a9ec7aa5925bd938bb1b23373b2667134a..0000aef161674d2f0787e83182783965a077fa13 100644 (file)
@@ -162,7 +162,9 @@ class MessageBuffer
     Consumer* m_consumer_ptr;  // Consumer to signal a wakeup(), can be NULL
     std::vector<MessageBufferNode> m_prio_heap;
     
-    typedef m5::hash_map< Address, std::list<MsgPtr> > StallMsgMapType;
+    // use a std::map for the stalled messages as this container is
+    // sorted and ensures a well-defined iteration order
+    typedef std::map< Address, std::list<MsgPtr> > StallMsgMapType;
     typedef std::vector<MsgPtr>::iterator MsgListIter;
 
     StallMsgMapType m_stall_msg_map;
index f78d939566238a7adccba466e71b4854628b6401..41b4ea68d3ffd698a2b8f1e6ff190e65939ab780 100644 (file)
@@ -33,7 +33,6 @@
 #include <iostream>
 #include <string>
 
-#include "base/hashmap.hh"
 #include "mem/ruby/common/Address.hh"
 #include "mem/ruby/common/Global.hh"
 
@@ -74,7 +73,10 @@ class TimerTable
     TimerTable& operator=(const TimerTable& obj);
 
     // Data Members (m_prefix)
-    typedef m5::hash_map<Address, Time> AddressMap;
+
+    // use a std::map for the address map as this container is sorted
+    // and ensures a well-defined iteration order
+    typedef std::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
index 7d863e349d587f5a0d9356165f7b4dcc16656d69..a9886b229ec7905364bc2f578accb5c865e19c1d 100644 (file)
@@ -324,7 +324,7 @@ MachineID m_machineID;
 bool m_is_blocking;
 std::map<Address, MessageBuffer*> m_block_map;
 typedef std::vector<MessageBuffer*> MsgVecType;
-typedef m5::hash_map< Address, MsgVecType* > WaitingBufType;
+typedef std::map< Address, MsgVecType* > WaitingBufType;
 WaitingBufType m_waiting_buffers;
 int m_max_in_port_rank;
 int m_cur_in_port_rank;