diff options
Diffstat (limited to 'src/mem/ruby')
92 files changed, 6854 insertions, 8056 deletions
diff --git a/src/mem/ruby/buffers/MessageBuffer.cc b/src/mem/ruby/buffers/MessageBuffer.cc index d157e2a94..83bb34dad 100644 --- a/src/mem/ruby/buffers/MessageBuffer.cc +++ b/src/mem/ruby/buffers/MessageBuffer.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,318 +26,341 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - */ - #include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/system/System.hh" MessageBuffer::MessageBuffer(const string &name) { - m_msg_counter = 0; - m_consumer_ptr = NULL; - m_ordering_set = false; - m_strict_fifo = true; - m_size = 0; - m_max_size = -1; - m_last_arrival_time = 0; - m_randomization = true; - m_size_last_time_size_checked = 0; - m_time_last_time_size_checked = 0; - m_time_last_time_enqueue = 0; - m_time_last_time_pop = 0; - m_size_at_cycle_start = 0; - m_msgs_this_cycle = 0; - m_not_avail_count = 0; - m_priority_rank = 0; - m_name = name; + m_msg_counter = 0; + m_consumer_ptr = NULL; + m_ordering_set = false; + m_strict_fifo = true; + m_size = 0; + m_max_size = -1; + m_last_arrival_time = 0; + m_randomization = true; + m_size_last_time_size_checked = 0; + m_time_last_time_size_checked = 0; + m_time_last_time_enqueue = 0; + m_time_last_time_pop = 0; + m_size_at_cycle_start = 0; + m_msgs_this_cycle = 0; + m_not_avail_count = 0; + m_priority_rank = 0; + m_name = name; } -int MessageBuffer::getSize() +int +MessageBuffer::getSize() { - if(m_time_last_time_size_checked == g_eventQueue_ptr->getTime()){ - return m_size_last_time_size_checked; - } else { - m_time_last_time_size_checked = g_eventQueue_ptr->getTime(); - m_size_last_time_size_checked = m_size; - return m_size; - } + if (m_time_last_time_size_checked == g_eventQueue_ptr->getTime()) { + return m_size_last_time_size_checked; + } else { + m_time_last_time_size_checked = g_eventQueue_ptr->getTime(); + m_size_last_time_size_checked = m_size; + return m_size; + } } -bool MessageBuffer::areNSlotsAvailable(int n) +bool +MessageBuffer::areNSlotsAvailable(int n) { - // fast path when message buffers have infinite size - if(m_max_size == -1) { - return true; - } - - // determine my correct size for the current cycle - // pop operations shouldn't effect the network's visible size until next cycle, - // but enqueue operations effect the visible size immediately - int current_size = max(m_size_at_cycle_start, m_size); - if (m_time_last_time_pop < g_eventQueue_ptr->getTime()) { // no pops this cycle - m_size is correct - current_size = m_size; - } else { - if (m_time_last_time_enqueue < g_eventQueue_ptr->getTime()) { // no enqueues this cycle - m_size_at_cycle_start is correct - current_size = m_size_at_cycle_start; - } else { // both pops and enqueues occured this cycle - add new enqueued msgs to m_size_at_cycle_start - current_size = m_size_at_cycle_start+m_msgs_this_cycle; + // fast path when message buffers have infinite size + if (m_max_size == -1) { + return true; + } + + // determine my correct size for the current cycle + // pop operations shouldn't effect the network's visible size + // until next cycle, but enqueue operations effect the visible + // size immediately + int current_size = max(m_size_at_cycle_start, m_size); + if (m_time_last_time_pop < g_eventQueue_ptr->getTime()) { + // no pops this cycle - m_size is correct + current_size = m_size; + } else { + if (m_time_last_time_enqueue < g_eventQueue_ptr->getTime()) { + // no enqueues this cycle - m_size_at_cycle_start is correct + current_size = m_size_at_cycle_start; + } else { + // both pops and enqueues occured this cycle - add new + // enqueued msgs to m_size_at_cycle_start + current_size = m_size_at_cycle_start+m_msgs_this_cycle; + } + } + + // now compare the new size with our max size + if (current_size + n <= m_max_size) { + return true; + } else { + DEBUG_MSG(QUEUE_COMP, MedPrio, n); + DEBUG_MSG(QUEUE_COMP, MedPrio, current_size); + DEBUG_MSG(QUEUE_COMP, MedPrio, m_size); + DEBUG_MSG(QUEUE_COMP, MedPrio, m_max_size); + m_not_avail_count++; + return false; } - } - - // now compare the new size with our max size - if(current_size+n <= m_max_size){ - return true; - } else { - DEBUG_MSG(QUEUE_COMP,MedPrio,n); - DEBUG_MSG(QUEUE_COMP,MedPrio,current_size); - DEBUG_MSG(QUEUE_COMP,MedPrio,m_size); - DEBUG_MSG(QUEUE_COMP,MedPrio,m_max_size); - m_not_avail_count++; - return false; - } } -const MsgPtr MessageBuffer::getMsgPtrCopy() const +const MsgPtr +MessageBuffer::getMsgPtrCopy() const { - assert(isReady()); + assert(isReady()); - MsgPtr temp_msg; - temp_msg = *(m_prio_heap.peekMin().m_msgptr.ref()); - assert(temp_msg.ref() != NULL); - return temp_msg; + MsgPtr temp_msg; + temp_msg = *(m_prio_heap.peekMin().m_msgptr.ref()); + assert(temp_msg.ref() != NULL); + return temp_msg; } -const Message* MessageBuffer::peekAtHeadOfQueue() const +const Message* +MessageBuffer::peekAtHeadOfQueue() const { - const Message* msg_ptr; - DEBUG_NEWLINE(QUEUE_COMP,MedPrio); + const Message* msg_ptr; + DEBUG_NEWLINE(QUEUE_COMP, MedPrio); - DEBUG_MSG(QUEUE_COMP,MedPrio,"Peeking at head of queue " + m_name + " time: " - + int_to_string(g_eventQueue_ptr->getTime()) + "."); - assert(isReady()); + DEBUG_MSG(QUEUE_COMP, MedPrio, + "Peeking at head of queue " + m_name + " time: " + + int_to_string(g_eventQueue_ptr->getTime()) + "."); + assert(isReady()); - msg_ptr = m_prio_heap.peekMin().m_msgptr.ref(); - assert(msg_ptr != NULL); + msg_ptr = m_prio_heap.peekMin().m_msgptr.ref(); + assert(msg_ptr != NULL); - DEBUG_EXPR(QUEUE_COMP,MedPrio,*msg_ptr); - DEBUG_NEWLINE(QUEUE_COMP,MedPrio); - return msg_ptr; + DEBUG_EXPR(QUEUE_COMP, MedPrio, *msg_ptr); + DEBUG_NEWLINE(QUEUE_COMP, MedPrio); + return msg_ptr; } // FIXME - move me somewhere else -int random_time() +int +random_time() { - int time = 1; - time += random() & 0x3; // [0...3] - if ((random() & 0x7) == 0) { // 1 in 8 chance - time += 100 + (random() % 0xf); // 100 + [1...15] - } - return time; + int time = 1; + time += random() & 0x3; // [0...3] + if ((random() & 0x7) == 0) { // 1 in 8 chance + time += 100 + (random() % 0xf); // 100 + [1...15] + } + return time; } -void MessageBuffer::enqueue(const MsgPtr& message, Time delta) +void +MessageBuffer::enqueue(const MsgPtr& message, Time delta) { - DEBUG_NEWLINE(QUEUE_COMP,HighPrio); - DEBUG_MSG(QUEUE_COMP,HighPrio,"enqueue " + m_name + " time: " - + int_to_string(g_eventQueue_ptr->getTime()) + "."); - DEBUG_EXPR(QUEUE_COMP,MedPrio,message); - DEBUG_NEWLINE(QUEUE_COMP,HighPrio); - - m_msg_counter++; - m_size++; - - // record current time incase we have a pop that also adjusts my size - if (m_time_last_time_enqueue < g_eventQueue_ptr->getTime()) { - m_msgs_this_cycle = 0; // first msg this cycle - m_time_last_time_enqueue = g_eventQueue_ptr->getTime(); - } - m_msgs_this_cycle++; - - // ASSERT(m_max_size == -1 || m_size <= m_max_size + 1); - // the plus one is a kluge because of a SLICC issue - - if (!m_ordering_set) { - // WARN_EXPR(*this); - WARN_EXPR(m_name); - ERROR_MSG("Ordering property of this queue has not been set"); - } - - // Calculate the arrival time of the message, that is, the first - // cycle the message can be dequeued. -// printf ("delta %i \n", delta); - assert(delta>0); - Time current_time = g_eventQueue_ptr->getTime(); - Time arrival_time = 0; - if (!RubySystem::getRandomization() || (m_randomization == false)) { - // No randomization - arrival_time = current_time + delta; - - } else { - // Randomization - ignore delta - if (m_strict_fifo) { - if (m_last_arrival_time < current_time) { - m_last_arrival_time = current_time; - } - arrival_time = m_last_arrival_time + random_time(); - } else { - arrival_time = current_time + random_time(); + DEBUG_NEWLINE(QUEUE_COMP, HighPrio); + DEBUG_MSG(QUEUE_COMP, HighPrio, "enqueue " + m_name + " time: " + + int_to_string(g_eventQueue_ptr->getTime()) + "."); + DEBUG_EXPR(QUEUE_COMP, MedPrio, message); + DEBUG_NEWLINE(QUEUE_COMP, HighPrio); + + m_msg_counter++; + m_size++; + + // record current time incase we have a pop that also adjusts my size + if (m_time_last_time_enqueue < g_eventQueue_ptr->getTime()) { + m_msgs_this_cycle = 0; // first msg this cycle + m_time_last_time_enqueue = g_eventQueue_ptr->getTime(); } - } + m_msgs_this_cycle++; + + // ASSERT(m_max_size == -1 || m_size <= m_max_size + 1); + // the plus one is a kluge because of a SLICC issue - // Check the arrival time - assert(arrival_time > current_time); - if (m_strict_fifo) { - if (arrival_time >= m_last_arrival_time) { + if (!m_ordering_set) { + // WARN_EXPR(*this); + WARN_EXPR(m_name); + ERROR_MSG("Ordering property of this queue has not been set"); + } + // Calculate the arrival time of the message, that is, the first + // cycle the message can be dequeued. + //printf ("delta %i \n", delta); + assert(delta>0); + Time current_time = g_eventQueue_ptr->getTime(); + Time arrival_time = 0; + if (!RubySystem::getRandomization() || (m_randomization == false)) { + // No randomization + arrival_time = current_time + delta; + } else { + // Randomization - ignore delta + if (m_strict_fifo) { + if (m_last_arrival_time < current_time) { + m_last_arrival_time = current_time; + } + arrival_time = m_last_arrival_time + random_time(); + } else { + arrival_time = current_time + random_time(); + } + } + + // Check the arrival time + assert(arrival_time > current_time); + if (m_strict_fifo) { + if (arrival_time < m_last_arrival_time) { + WARN_EXPR(*this); + WARN_EXPR(m_name); + WARN_EXPR(current_time); + WARN_EXPR(delta); + WARN_EXPR(arrival_time); + WARN_EXPR(m_last_arrival_time); + ERROR_MSG("FIFO ordering violated"); + } + } + m_last_arrival_time = arrival_time; + + // compute the delay cycles and set enqueue time + Message* msg_ptr = message.mod_ref(); + assert(msg_ptr != NULL); + + assert(g_eventQueue_ptr->getTime() >= msg_ptr->getLastEnqueueTime() && + "ensure we aren't dequeued early"); + + msg_ptr->setDelayedCycles(g_eventQueue_ptr->getTime() - + msg_ptr->getLastEnqueueTime() + + msg_ptr->getDelayedCycles()); + msg_ptr->setLastEnqueueTime(arrival_time); + + // Insert the message into the priority heap + MessageBufferNode thisNode(arrival_time, m_msg_counter, message); + m_prio_heap.insert(thisNode); + + DEBUG_NEWLINE(QUEUE_COMP, HighPrio); + DEBUG_MSG(QUEUE_COMP, HighPrio, "enqueue " + m_name + + " with arrival_time " + int_to_string(arrival_time) + + " cur_time: " + int_to_string(g_eventQueue_ptr->getTime()) + + "."); + DEBUG_EXPR(QUEUE_COMP, MedPrio, message); + DEBUG_NEWLINE(QUEUE_COMP, HighPrio); + + // Schedule the wakeup + if (m_consumer_ptr != NULL) { + g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, arrival_time); } else { - WARN_EXPR(*this); - WARN_EXPR(m_name); - WARN_EXPR(current_time); - WARN_EXPR(delta); - WARN_EXPR(arrival_time); - WARN_EXPR(m_last_arrival_time); - ERROR_MSG("FIFO ordering violated"); + WARN_EXPR(*this); + WARN_EXPR(m_name); + ERROR_MSG("No consumer"); } - } - m_last_arrival_time = arrival_time; - - // compute the delay cycles and set enqueue time - Message* msg_ptr = NULL; - msg_ptr = message.mod_ref(); - assert(msg_ptr != NULL); - assert(g_eventQueue_ptr->getTime() >= msg_ptr->getLastEnqueueTime()); // ensure we aren't dequeued early - msg_ptr->setDelayedCycles((g_eventQueue_ptr->getTime() - msg_ptr->getLastEnqueueTime())+msg_ptr->getDelayedCycles()); - msg_ptr->setLastEnqueueTime(arrival_time); - - // Insert the message into the priority heap - MessageBufferNode thisNode(arrival_time, m_msg_counter, message); - m_prio_heap.insert(thisNode); - - DEBUG_NEWLINE(QUEUE_COMP,HighPrio); - DEBUG_MSG(QUEUE_COMP,HighPrio,"enqueue " + m_name - + " with arrival_time " + int_to_string(arrival_time) - + " cur_time: " + int_to_string(g_eventQueue_ptr->getTime()) + "."); - DEBUG_EXPR(QUEUE_COMP,MedPrio,message); - DEBUG_NEWLINE(QUEUE_COMP,HighPrio); - - // Schedule the wakeup - if (m_consumer_ptr != NULL) { - g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, arrival_time); - } else { - WARN_EXPR(*this); - WARN_EXPR(m_name); - ERROR_MSG("No consumer"); - } } -int MessageBuffer::dequeue_getDelayCycles(MsgPtr& message) +int +MessageBuffer::dequeue_getDelayCycles(MsgPtr& message) { - int delay_cycles = -1; // null value + int delay_cycles = -1; // null value - dequeue(message); + dequeue(message); - // get the delay cycles - delay_cycles = setAndReturnDelayCycles(message); + // get the delay cycles + delay_cycles = setAndReturnDelayCycles(message); - assert(delay_cycles >= 0); - return delay_cycles; + assert(delay_cycles >= 0); + return delay_cycles; } -void MessageBuffer::dequeue(MsgPtr& message) +void +MessageBuffer::dequeue(MsgPtr& message) { - DEBUG_MSG(QUEUE_COMP,MedPrio,"dequeue from " + m_name); - message = m_prio_heap.peekMin().m_msgptr; + DEBUG_MSG(QUEUE_COMP, MedPrio, "dequeue from " + m_name); + message = m_prio_heap.peekMin().m_msgptr; - pop(); - DEBUG_EXPR(QUEUE_COMP,MedPrio,message); + pop(); + DEBUG_EXPR(QUEUE_COMP, MedPrio, message); } -int MessageBuffer::dequeue_getDelayCycles() +int +MessageBuffer::dequeue_getDelayCycles() { - int delay_cycles = -1; // null value + int delay_cycles = -1; // null value - // get MsgPtr of the message about to be dequeued - MsgPtr message = m_prio_heap.peekMin().m_msgptr; + // get MsgPtr of the message about to be dequeued + MsgPtr message = m_prio_heap.peekMin().m_msgptr; - // get the delay cycles - delay_cycles = setAndReturnDelayCycles(message); + // get the delay cycles + delay_cycles = setAndReturnDelayCycles(message); - dequeue(); + dequeue(); - assert(delay_cycles >= 0); - return delay_cycles; + assert(delay_cycles >= 0); + return delay_cycles; } -void MessageBuffer::pop() +void +MessageBuffer::pop() { - DEBUG_MSG(QUEUE_COMP,MedPrio,"pop from " + m_name); - assert(isReady()); - m_prio_heap.extractMin(); - // record previous size and time so the current buffer size isn't adjusted until next cycle - if (m_time_last_time_pop < g_eventQueue_ptr->getTime()) { - m_size_at_cycle_start = m_size; - m_time_last_time_pop = g_eventQueue_ptr->getTime(); - } - m_size--; + DEBUG_MSG(QUEUE_COMP, MedPrio, "pop from " + m_name); + assert(isReady()); + m_prio_heap.extractMin(); + // record previous size and time so the current buffer size isn't + // adjusted until next cycle + if (m_time_last_time_pop < g_eventQueue_ptr->getTime()) { + m_size_at_cycle_start = m_size; + m_time_last_time_pop = g_eventQueue_ptr->getTime(); + } + m_size--; } -void MessageBuffer::clear() +void +MessageBuffer::clear() { - while(m_prio_heap.size() > 0){ - m_prio_heap.extractMin(); - } + while(m_prio_heap.size() > 0){ + m_prio_heap.extractMin(); + } - ASSERT(m_prio_heap.size() == 0); + ASSERT(m_prio_heap.size() == 0); - m_msg_counter = 0; - m_size = 0; - m_time_last_time_enqueue = 0; - m_time_last_time_pop = 0; - m_size_at_cycle_start = 0; - m_msgs_this_cycle = 0; + m_msg_counter = 0; + m_size = 0; + m_time_last_time_enqueue = 0; + m_time_last_time_pop = 0; + m_size_at_cycle_start = 0; + m_msgs_this_cycle = 0; } -void MessageBuffer::recycle() +void +MessageBuffer::recycle() { - DEBUG_MSG(QUEUE_COMP,MedPrio,"recycling " + m_name); - assert(isReady()); - MessageBufferNode node = m_prio_heap.extractMin(); - node.m_time = g_eventQueue_ptr->getTime() + m_recycle_latency; - m_prio_heap.insert(node); - g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, g_eventQueue_ptr->getTime() + m_recycle_latency); + DEBUG_MSG(QUEUE_COMP, MedPrio, "recycling " + m_name); + assert(isReady()); + MessageBufferNode node = m_prio_heap.extractMin(); + node.m_time = g_eventQueue_ptr->getTime() + m_recycle_latency; + m_prio_heap.insert(node); + g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, + g_eventQueue_ptr->getTime() + m_recycle_latency); } -int MessageBuffer::setAndReturnDelayCycles(MsgPtr& message) +int +MessageBuffer::setAndReturnDelayCycles(MsgPtr& message) { - int delay_cycles = -1; // null value + int delay_cycles = -1; // null value - // get the delay cycles of the message at the top of the queue - Message* msg_ptr = message.ref(); + // get the delay cycles of the message at the top of the queue + Message* msg_ptr = message.ref(); - // this function should only be called on dequeue - // ensure the msg hasn't been enqueued - assert(msg_ptr->getLastEnqueueTime() <= g_eventQueue_ptr->getTime()); - msg_ptr->setDelayedCycles((g_eventQueue_ptr->getTime() - msg_ptr->getLastEnqueueTime())+msg_ptr->getDelayedCycles()); - delay_cycles = msg_ptr->getDelayedCycles(); + // this function should only be called on dequeue + // ensure the msg hasn't been enqueued + assert(msg_ptr->getLastEnqueueTime() <= g_eventQueue_ptr->getTime()); + msg_ptr->setDelayedCycles(g_eventQueue_ptr->getTime() - + msg_ptr->getLastEnqueueTime() + + msg_ptr->getDelayedCycles()); + delay_cycles = msg_ptr->getDelayedCycles(); - assert(delay_cycles >= 0); - return delay_cycles; + assert(delay_cycles >= 0); + return delay_cycles; } -void MessageBuffer::print(ostream& out) const +void +MessageBuffer::print(ostream& out) const { - out << "[MessageBuffer: "; - if (m_consumer_ptr != NULL) { - out << " consumer-yes "; - } - out << m_prio_heap << "] " << m_name << endl; + out << "[MessageBuffer: "; + if (m_consumer_ptr != NULL) { + out << " consumer-yes "; + } + out << m_prio_heap << "] " << m_name << endl; } -void MessageBuffer::printStats(ostream& out) +void +MessageBuffer::printStats(ostream& out) { - out << "MessageBuffer: " << m_name << " stats - msgs:" << m_msg_counter << " full:" << m_not_avail_count << endl; + out << "MessageBuffer: " << m_name << " stats - msgs:" << m_msg_counter + << " full:" << m_not_avail_count << endl; } - diff --git a/src/mem/ruby/buffers/MessageBuffer.hh b/src/mem/ruby/buffers/MessageBuffer.hh index 8d5a8de25..8fc86af97 100644 --- a/src/mem/ruby/buffers/MessageBuffer.hh +++ b/src/mem/ruby/buffers/MessageBuffer.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -28,137 +27,156 @@ */ /* - * $Id$ - * - * Description: Unordered buffer of messages that can be inserted such + * Unordered buffer of messages that can be inserted such * that they can be dequeued after a given delta time has expired. - * */ -#ifndef MESSAGEBUFFER_H -#define MESSAGEBUFFER_H +#ifndef __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__ +#define __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__ #include <iostream> #include <string> -#include "mem/ruby/common/Global.hh" +#include "mem/gems_common/PrioHeap.hh" +#include "mem/gems_common/util.hh" #include "mem/ruby/buffers/MessageBufferNode.hh" #include "mem/ruby/common/Consumer.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/ruby/slicc_interface/Message.hh" -#include "mem/gems_common/PrioHeap.hh" -#include "mem/gems_common/util.hh" -class MessageBuffer { -public: - // Constructors - MessageBuffer(const std::string &name = ""); - - // ~MessageBuffer() - - // Public Methods - - static void printConfig(std::ostream& out) {} - void setRecycleLatency(int recycle_latency) { m_recycle_latency = recycle_latency; } - - // TRUE if head of queue timestamp <= SystemTime - bool isReady() const { - return ((m_prio_heap.size() > 0) && - (m_prio_heap.peekMin().m_time <= g_eventQueue_ptr->getTime())); - } - - void delayHead() { - MessageBufferNode node = m_prio_heap.extractMin(); - enqueue(node.m_msgptr, 1); - } - - bool areNSlotsAvailable(int n); - int getPriority() { return m_priority_rank; } - void setPriority(int rank) { m_priority_rank = rank; } - void setConsumer(Consumer* consumer_ptr) { ASSERT(m_consumer_ptr==NULL); m_consumer_ptr = consumer_ptr; } - void setDescription(const std::string& name) { m_name = name; } - std::string getDescription() { return m_name;} - - Consumer* getConsumer() { return m_consumer_ptr; } - - const Message* peekAtHeadOfQueue() const; - const Message* peek() const { return peekAtHeadOfQueue(); } - const MsgPtr getMsgPtrCopy() const; - const MsgPtr& peekMsgPtr() const { assert(isReady()); return m_prio_heap.peekMin().m_msgptr; } - const MsgPtr& peekMsgPtrEvenIfNotReady() const {return m_prio_heap.peekMin().m_msgptr; } - - void enqueue(const MsgPtr& message) { enqueue(message, 1); } - void enqueue(const MsgPtr& message, Time delta); - // void enqueueAbsolute(const MsgPtr& message, Time absolute_time); - int dequeue_getDelayCycles(MsgPtr& message); // returns delay cycles of the message - void dequeue(MsgPtr& message); - int dequeue_getDelayCycles(); // returns delay cycles of the message - void dequeue() { pop(); } - void pop(); - void recycle(); - bool isEmpty() const { return m_prio_heap.size() == 0; } - - void setOrdering(bool order) { m_strict_fifo = order; m_ordering_set = true; } - void setSize(int size) {m_max_size = size;} - int getSize(); - void setRandomization(bool random_flag) { m_randomization = random_flag; } - - void clear(); - - void print(std::ostream& out) const; - void printStats(std::ostream& out); - void clearStats() { m_not_avail_count = 0; m_msg_counter = 0; } - -private: - //added by SS - int m_recycle_latency; - - // Private Methods - int setAndReturnDelayCycles(MsgPtr& message); - - // Private copy constructor and assignment operator - MessageBuffer(const MessageBuffer& obj); - MessageBuffer& operator=(const MessageBuffer& obj); - - // Data Members (m_ prefix) - Consumer* m_consumer_ptr; // Consumer to signal a wakeup(), can be NULL - PrioHeap<MessageBufferNode> m_prio_heap; - std::string m_name; - - int m_max_size; - int m_size; - - Time m_time_last_time_size_checked; - int m_size_last_time_size_checked; - - // variables used so enqueues appear to happen imediately, while pop happen the next cycle - Time m_time_last_time_enqueue; - Time m_time_last_time_pop; - int m_size_at_cycle_start; - int m_msgs_this_cycle; - - int m_not_avail_count; // count the # of times I didn't have N slots available - int m_msg_counter; - int m_priority_rank; - bool m_strict_fifo; - bool m_ordering_set; - bool m_randomization; - Time m_last_arrival_time; +class MessageBuffer +{ + public: + MessageBuffer(const std::string &name = ""); + + static void printConfig(std::ostream& out) {} + void + setRecycleLatency(int recycle_latency) + { + m_recycle_latency = recycle_latency; + } + + // TRUE if head of queue timestamp <= SystemTime + bool + isReady() const + { + return ((m_prio_heap.size() > 0) && + (m_prio_heap.peekMin().m_time <= g_eventQueue_ptr->getTime())); + } + + void + delayHead() + { + MessageBufferNode node = m_prio_heap.extractMin(); + enqueue(node.m_msgptr, 1); + } + + bool areNSlotsAvailable(int n); + int getPriority() { return m_priority_rank; } + void setPriority(int rank) { m_priority_rank = rank; } + void setConsumer(Consumer* consumer_ptr) + { + ASSERT(m_consumer_ptr == NULL); + m_consumer_ptr = consumer_ptr; + } + + void setDescription(const std::string& name) { m_name = name; } + std::string getDescription() { return m_name;} + + Consumer* getConsumer() { return m_consumer_ptr; } + + const Message* peekAtHeadOfQueue() const; + const Message* peek() const { return peekAtHeadOfQueue(); } + const MsgPtr getMsgPtrCopy() const; + + const MsgPtr& + peekMsgPtr() const + { + assert(isReady()); + return m_prio_heap.peekMin().m_msgptr; + } + + const MsgPtr& + peekMsgPtrEvenIfNotReady() const + { + return m_prio_heap.peekMin().m_msgptr; + } + + void enqueue(const MsgPtr& message) { enqueue(message, 1); } + void enqueue(const MsgPtr& message, Time delta); + // void enqueueAbsolute(const MsgPtr& message, Time absolute_time); + int dequeue_getDelayCycles(MsgPtr& message); // returns delay + // cycles of the + // message + void dequeue(MsgPtr& message); + int dequeue_getDelayCycles(); // returns delay cycles of the message + void dequeue() { pop(); } + void pop(); + void recycle(); + bool isEmpty() const { return m_prio_heap.size() == 0; } + + void + setOrdering(bool order) + { + m_strict_fifo = order; + m_ordering_set = true; + } + void setSize(int size) { m_max_size = size; } + int getSize(); + void setRandomization(bool random_flag) { m_randomization = random_flag; } + + void clear(); + + void print(std::ostream& out) const; + void printStats(std::ostream& out); + void clearStats() { m_not_avail_count = 0; m_msg_counter = 0; } + + private: + //added by SS + int m_recycle_latency; + + // Private Methods + int setAndReturnDelayCycles(MsgPtr& message); + + // Private copy constructor and assignment operator + MessageBuffer(const MessageBuffer& obj); + MessageBuffer& operator=(const MessageBuffer& obj); + + // Data Members (m_ prefix) + Consumer* m_consumer_ptr; // Consumer to signal a wakeup(), can be NULL + PrioHeap<MessageBufferNode> m_prio_heap; + std::string m_name; + + int m_max_size; + int m_size; + + Time m_time_last_time_size_checked; + int m_size_last_time_size_checked; + + // variables used so enqueues appear to happen imediately, while + // pop happen the next cycle + Time m_time_last_time_enqueue; + Time m_time_last_time_pop; + int m_size_at_cycle_start; + int m_msgs_this_cycle; + + int m_not_avail_count; // count the # of times I didn't have N + // slots available + int m_msg_counter; + int m_priority_rank; + bool m_strict_fifo; + bool m_ordering_set; + bool m_randomization; + Time m_last_arrival_time; }; -// Output operator declaration -//template <class TYPE> -std::ostream& operator<<(std::ostream& out, const MessageBuffer& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -std::ostream& operator<<(std::ostream& out, const MessageBuffer& obj) +inline std::ostream& +operator<<(std::ostream& out, const MessageBuffer& obj) { - obj.print(out); - out << std::flush; - return out; + obj.print(out); + out << std::flush; + return out; } -#endif //MESSAGEBUFFER_H +#endif // __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__ diff --git a/src/mem/ruby/buffers/MessageBufferNode.cc b/src/mem/ruby/buffers/MessageBufferNode.cc index aec977acd..698eeab25 100644 --- a/src/mem/ruby/buffers/MessageBufferNode.cc +++ b/src/mem/ruby/buffers/MessageBufferNode.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -32,9 +31,9 @@ void MessageBufferNode::print(std::ostream& out) const { - out << "["; - out << m_time << ", "; - out << m_msg_counter << ", "; - out << m_msgptr << "; "; - out << "]"; + out << "["; + out << m_time << ", "; + out << m_msg_counter << ", "; + out << m_msgptr << "; "; + out << "]"; } diff --git a/src/mem/ruby/buffers/MessageBufferNode.hh b/src/mem/ruby/buffers/MessageBufferNode.hh index 747c1d889..9ead9b9aa 100644 --- a/src/mem/ruby/buffers/MessageBufferNode.hh +++ b/src/mem/ruby/buffers/MessageBufferNode.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,64 +26,55 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MESSAGEBUFFERNODE_H -#define MESSAGEBUFFERNODE_H +#ifndef __MEM_RUBY_BUFFERS_MESSAGEBUFFERNODE_HH__ +#define __MEM_RUBY_BUFFERS_MESSAGEBUFFERNODE_HH__ #include <iostream> #include "mem/ruby/common/Global.hh" #include "mem/ruby/slicc_interface/Message.hh" -class MessageBufferNode { -public: - // Constructors - MessageBufferNode() { m_time = 0; m_msg_counter = 0; } - MessageBufferNode(const Time& time, int counter, const MsgPtr& msgptr) - { m_time = time; m_msgptr = msgptr; m_msg_counter = counter; } - // Destructor - //~MessageBufferNode(); +class MessageBufferNode +{ + public: + MessageBufferNode() + { + m_time = 0; + m_msg_counter = 0; + } - // Public Methods - void print(std::ostream& out) const; -private: - // Private Methods + MessageBufferNode(const Time& time, int counter, const MsgPtr& msgptr) + { + m_time = time; + m_msgptr = msgptr; + m_msg_counter = counter; + } - // Default copy constructor and assignment operator - // MessageBufferNode(const MessageBufferNode& obj); - // MessageBufferNode& operator=(const MessageBufferNode& obj); + void print(std::ostream& out) const; - // Data Members (m_ prefix) -public: - Time m_time; - int m_msg_counter; // FIXME, should this be a 64-bit value? - MsgPtr m_msgptr; + public: + Time m_time; + int m_msg_counter; // FIXME, should this be a 64-bit value? + MsgPtr m_msgptr; }; -// Output operator declaration -std::ostream& operator<<(std::ostream& out, const MessageBufferNode& obj); - -// ******************* Definitions ******************* - -inline extern bool node_less_then_eq(const MessageBufferNode& n1, const MessageBufferNode& n2); - -inline extern -bool node_less_then_eq(const MessageBufferNode& n1, const MessageBufferNode& n2) +inline bool +node_less_then_eq(const MessageBufferNode& n1, const MessageBufferNode& n2) { - if (n1.m_time == n2.m_time) { - assert(n1.m_msg_counter != n2.m_msg_counter); - return (n1.m_msg_counter <= n2.m_msg_counter); - } else { - return (n1.m_time <= n2.m_time); - } + if (n1.m_time == n2.m_time) { + assert(n1.m_msg_counter != n2.m_msg_counter); + return (n1.m_msg_counter <= n2.m_msg_counter); + } else { + return (n1.m_time <= n2.m_time); + } } -// Output operator definition -extern inline -std::ostream& operator<<(std::ostream& out, const MessageBufferNode& obj) +inline std::ostream& +operator<<(std::ostream& out, const MessageBufferNode& obj) { - obj.print(out); - out << std::flush; - return out; + obj.print(out); + out << std::flush; + return out; } -#endif //MESSAGEBUFFERNODE_H +#endif // __MEM_RUBY_BUFFERS_MESSAGEBUFFERNODE_HH__ diff --git a/src/mem/ruby/common/Address.cc b/src/mem/ruby/common/Address.cc index b4ad39294..e74bdb47b 100644 --- a/src/mem/ruby/common/Address.cc +++ b/src/mem/ruby/common/Address.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,42 +26,41 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - */ - #include "mem/ruby/common/Address.hh" -void Address::output(ostream& out) const +void +Address::output(ostream& out) const { - // Note: this outputs addresses in the form "ffff", not "0xffff". - // This code should always be able to write out addresses in a - // format that can be read in by the below input() method. Please - // don't change this without talking to Milo first. - out << hex << m_address << dec; + // Note: this outputs addresses in the form "ffff", not "0xffff". + // This code should always be able to write out addresses in a + // format that can be read in by the below input() method. Please + // don't change this without talking to Milo first. + out << hex << m_address << dec; } -void Address::input(istream& in) +void +Address::input(istream& in) { - // Note: this only works with addresses in the form "ffff", not - // "0xffff". This code should always be able to read in addresses - // written out by the above output() method. Please don't change - // this without talking to Milo first. - in >> hex >> m_address >> dec; + // Note: this only works with addresses in the form "ffff", not + // "0xffff". This code should always be able to read in addresses + // written out by the above output() method. Please don't change + // this without talking to Milo first. + in >> hex >> m_address >> dec; } Address::Address(const Address& obj) { - m_address = obj.m_address; + m_address = obj.m_address; } -Address& Address::operator=(const Address& obj) +Address& +Address::operator=(const Address& obj) { - if (this == &obj) { - // assert(false); - } else { - m_address = obj.m_address; - } - return *this; + if (this == &obj) { + // assert(false); + } else { + m_address = obj.m_address; + } + return *this; } diff --git a/src/mem/ruby/common/Address.hh b/src/mem/ruby/common/Address.hh index 7da5ed0fe..73327e617 100644 --- a/src/mem/ruby/common/Address.hh +++ b/src/mem/ruby/common/Address.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,20 +26,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - */ - -#ifndef ADDRESS_H -#define ADDRESS_H +#ifndef __MEM_RUBY_COMMON_ADDRESS_HH__ +#define __MEM_RUBY_COMMON_ADDRESS_HH__ #include <iomanip> #include "base/hashmap.hh" #include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/System.hh" -#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/MachineID.hh" +#include "mem/ruby/system/NodeID.hh" +#include "mem/ruby/system/System.hh" const int ADDRESS_WIDTH = 64; // address width in bytes @@ -48,124 +43,131 @@ class Address; typedef Address PhysAddress; typedef Address VirtAddress; -class Address { -public: - // Constructors - Address() { m_address = 0; } - explicit Address(physical_address_t address) { m_address = address; } - - Address(const Address& obj); - Address& operator=(const Address& obj); - - // Destructor - // ~Address(); - - // Public Methods - - void setAddress(physical_address_t address) { m_address = address; } - physical_address_t getAddress() const {return m_address;} - // selects bits inclusive - physical_address_t bitSelect(int small, int big) const; - physical_address_t bitRemove(int small, int big) const; - physical_address_t maskLowOrderBits(int number) const; - physical_address_t maskHighOrderBits(int number) const; - physical_address_t shiftLowOrderBits(int number) const; - physical_address_t getLineAddress() const - { return bitSelect(RubySystem::getBlockSizeBits(), ADDRESS_WIDTH); } - physical_address_t getOffset() const - { return bitSelect(0, RubySystem::getBlockSizeBits()-1); } - - void makeLineAddress() { m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()); } - // returns the next stride address based on line address - void makeNextStrideAddress( int stride) { - m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()) - + RubySystem::getBlockSizeBytes()*stride; - } - int getBankSetNum() const; - int getBankSetDist() const; +class Address +{ + public: + Address() + : m_address(0) + { } + + explicit + Address(physical_address_t address) + : m_address(address) + { } + + Address(const Address& obj); + Address& operator=(const Address& obj); + + void setAddress(physical_address_t address) { m_address = address; } + physical_address_t getAddress() const {return m_address;} + // selects bits inclusive + physical_address_t bitSelect(int small, int big) const; + physical_address_t bitRemove(int small, int big) const; + physical_address_t maskLowOrderBits(int number) const; + physical_address_t maskHighOrderBits(int number) const; + physical_address_t shiftLowOrderBits(int number) const; + + physical_address_t + getLineAddress() const + { + return bitSelect(RubySystem::getBlockSizeBits(), ADDRESS_WIDTH); + } - Index memoryModuleIndex() const; + physical_address_t + getOffset() const + { + return bitSelect(0, RubySystem::getBlockSizeBits() - 1); + } - void print(ostream& out) const; - void output(ostream& out) const; - void input(istream& in); + void + makeLineAddress() + { + m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()); + } - void setOffset( int offset ){ - // first, zero out the offset bits - makeLineAddress(); - m_address |= (physical_address_t) offset; - } + // returns the next stride address based on line address + void + makeNextStrideAddress(int stride) + { + m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()) + + RubySystem::getBlockSizeBytes()*stride; + } -private: - // Private Methods + int getBankSetNum() const; + int getBankSetDist() const; - // Private copy constructor and assignment operator - // Address(const Address& obj); - // Address& operator=(const Address& obj); + Index memoryModuleIndex() const; - // Data Members (m_ prefix) - physical_address_t m_address; -}; + void print(ostream& out) const; + void output(ostream& out) const; + void input(istream& in); -inline -Address line_address(const Address& addr) { Address temp(addr); temp.makeLineAddress(); return temp; } + void + setOffset(int offset) + { + // first, zero out the offset bits + makeLineAddress(); + m_address |= (physical_address_t) offset; + } -// Output operator declaration -ostream& operator<<(ostream& out, const Address& obj); -// comparison operator declaration -bool operator==(const Address& obj1, const Address& obj2); -bool operator!=(const Address& obj1, const Address& obj2); -bool operator<(const Address& obj1, const Address& obj2); -/* Address& operator=(const physical_address_t address); */ + private: + physical_address_t m_address; +}; -inline -bool operator<(const Address& obj1, const Address& obj2) +inline Address +line_address(const Address& addr) { - return obj1.getAddress() < obj2.getAddress(); + Address temp(addr); + temp.makeLineAddress(); + return temp; } -// ******************* Definitions ******************* +inline bool +operator<(const Address& obj1, const Address& obj2) +{ + return obj1.getAddress() < obj2.getAddress(); +} -// Output operator definition -inline -ostream& operator<<(ostream& out, const Address& obj) +inline ostream& +operator<<(ostream& out, const Address& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -inline -bool operator==(const Address& obj1, const Address& obj2) +inline bool +operator==(const Address& obj1, const Address& obj2) { - return (obj1.getAddress() == obj2.getAddress()); + return (obj1.getAddress() == obj2.getAddress()); } -inline -bool operator!=(const Address& obj1, const Address& obj2) +inline bool +operator!=(const Address& obj1, const Address& obj2) { - return (obj1.getAddress() != obj2.getAddress()); + return (obj1.getAddress() != obj2.getAddress()); } -inline -physical_address_t Address::bitSelect(int small, int big) const // rips bits inclusive +// rips bits inclusive +inline physical_address_t +Address::bitSelect(int small, int big) const { - physical_address_t mask; - assert((unsigned)big >= (unsigned)small); + physical_address_t mask; + assert((unsigned)big >= (unsigned)small); - if (big >= ADDRESS_WIDTH - 1) { - return (m_address >> small); - } else { - mask = ~((physical_address_t)~0 << (big + 1)); - // FIXME - this is slow to manipulate a 64-bit number using 32-bits - physical_address_t partial = (m_address & mask); - return (partial >> small); - } + if (big >= ADDRESS_WIDTH - 1) { + return (m_address >> small); + } else { + mask = ~((physical_address_t)~0 << (big + 1)); + // FIXME - this is slow to manipulate a 64-bit number using 32-bits + physical_address_t partial = (m_address & mask); + return (partial >> small); + } } // removes bits inclusive -inline -physical_address_t Address::bitRemove(int small, int big) const +inline physical_address_t +Address::bitRemove(int small, int big) const { physical_address_t mask; assert((unsigned)big >= (unsigned)small); @@ -184,60 +186,64 @@ physical_address_t Address::bitRemove(int small, int big) const mask = (physical_address_t)~0 << (big + 1); physical_address_t higher_bits = m_address & mask; - // // Shift the valid high bits over the removed section - // higher_bits = higher_bits >> (big - small); return (higher_bits | lower_bits); } } -inline -physical_address_t Address::maskLowOrderBits(int number) const +inline physical_address_t +Address::maskLowOrderBits(int number) const { physical_address_t mask; if (number >= ADDRESS_WIDTH - 1) { - mask = ~0; + mask = ~0; } else { - mask = (physical_address_t)~0 << number; + mask = (physical_address_t)~0 << number; } return (m_address & mask); } -inline -physical_address_t Address::maskHighOrderBits(int number) const +inline physical_address_t +Address::maskHighOrderBits(int number) const { - physical_address_t mask; + physical_address_t mask; - if (number >= ADDRESS_WIDTH - 1) { - mask = ~0; - } else { - mask = (physical_address_t)~0 >> number; - } - return (m_address & mask); + if (number >= ADDRESS_WIDTH - 1) { + mask = ~0; + } else { + mask = (physical_address_t)~0 >> number; + } + return (m_address & mask); } -inline -physical_address_t Address::shiftLowOrderBits(int number) const +inline physical_address_t +Address::shiftLowOrderBits(int number) const { - return (m_address >> number); + return (m_address >> number); } -inline -integer_t Address::memoryModuleIndex() const +inline integer_t +Address::memoryModuleIndex() const { - integer_t index = bitSelect(RubySystem::getBlockSizeBits()+RubySystem::getMemorySizeBits(), ADDRESS_WIDTH); - assert (index >= 0); - return index; - - // Index indexHighPortion = address.bitSelect(MEMORY_SIZE_BITS-1, PAGE_SIZE_BITS+NUMBER_OF_MEMORY_MODULE_BITS); - // Index indexLowPortion = address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS-1); - - //Index index = indexLowPortion | (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS)); - - /* - Round-robin mapping of addresses, at page size granularity + integer_t index = + bitSelect(RubySystem::getBlockSizeBits() + + RubySystem::getMemorySizeBits(), ADDRESS_WIDTH); + assert (index >= 0); + return index; + + // Index indexHighPortion = + // address.bitSelect(MEMORY_SIZE_BITS - 1, + // PAGE_SIZE_BITS + NUMBER_OF_MEMORY_MODULE_BITS); + // Index indexLowPortion = + // address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS - 1); + // + // Index index = indexLowPortion | + // (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS)); + + /* + Round-robin mapping of addresses, at page size granularity ADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS | | | | @@ -249,29 +255,39 @@ ADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS indexHighPortion indexLowPortion <-------> NUMBER_OF_MEMORY_MODULE_BITS - */ + */ } -inline -void Address::print(ostream& out) const +inline void +Address::print(ostream& out) const { using namespace std; - out << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubySystem::getBlockSizeBits()) << dec << "]" << flush; + out << "[" << hex << "0x" << m_address << "," << " line 0x" + << maskLowOrderBits(RubySystem::getBlockSizeBits()) << dec << "]" + << flush; } class Address; namespace __hash_namespace { - template <> struct hash<Address> - { - size_t operator()(const Address &s) const { return (size_t) s.getAddress(); } - }; -} -namespace std { - template <> struct equal_to<Address> - { - bool operator()(const Address& s1, const Address& s2) const { return s1 == s2; } - }; -} +template <> struct hash<Address> +{ + size_t + operator()(const Address &s) const + { + return (size_t)s.getAddress(); + } +}; +/* namespace __hash_namespace */ } -#endif //ADDRESS_H +namespace std { +template <> struct equal_to<Address> +{ + bool + operator()(const Address& s1, const Address& s2) const + { + return s1 == s2; + } +}; +/* namespace std */ } +#endif // __MEM_RUBY_COMMON_ADDRESS_HH__ diff --git a/src/mem/ruby/common/Consumer.hh b/src/mem/ruby/common/Consumer.hh index e541ef615..c1f8bc42e 100644 --- a/src/mem/ruby/common/Consumer.hh +++ b/src/mem/ruby/common/Consumer.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -28,16 +27,13 @@ */ /* - * $Id$ - * - * Description: This is the virtual base class of all classes that can - * be the targets of wakeup events. There is only two methods, - * wakeup() and print() and no data members. - * + * This is the virtual base class of all classes that can be the + * targets of wakeup events. There is only two methods, wakeup() and + * print() and no data members. */ -#ifndef CONSUMER_H -#define CONSUMER_H +#ifndef __MEM_RUBY_COMMON_CONSUMER_HH__ +#define __MEM_RUBY_COMMON_CONSUMER_HH__ #include <iostream> #include <set> @@ -47,68 +43,74 @@ class MessageBuffer; -class Consumer { -public: - // Constructors - Consumer() { m_last_scheduled_wakeup = 0; m_last_wakeup = 0; } - - // Destructor - virtual ~Consumer() { } - - // Public Methods - pure virtual methods - void triggerWakeup(RubyEventQueue * eventQueue) - { - Time time = eventQueue->getTime(); - if (m_last_wakeup != time) { - wakeup(); m_last_wakeup = time; - } - } - virtual void wakeup() = 0; - virtual void print(std::ostream& out) const = 0; - const Time& getLastScheduledWakeup() const - { - return m_last_scheduled_wakeup; - } - void setLastScheduledWakeup(const Time& time) - { - m_last_scheduled_wakeup = time; - } - bool alreadyScheduled(Time time) - { - return (m_scheduled_wakeups.find(time) != m_scheduled_wakeups.end()); - } - void insertScheduledWakeupTime(Time time) - { - m_scheduled_wakeups.insert(time); - } - void removeScheduledWakeupTime(Time time) - { - assert(alreadyScheduled(time)); - m_scheduled_wakeups.erase(time); - } - -private: - // Private Methods - - // Data Members (m_ prefix) - Time m_last_scheduled_wakeup; - std::set<Time> m_scheduled_wakeups; - Time m_last_wakeup; -}; +class Consumer +{ + public: + Consumer() + : m_last_scheduled_wakeup(0), m_last_wakeup(0) + { + } + + virtual + ~Consumer() + { } + + void + triggerWakeup(RubyEventQueue *eventQueue) + { + Time time = eventQueue->getTime(); + if (m_last_wakeup != time) { + wakeup(); + m_last_wakeup = time; + } + } -// Output operator declaration -inline extern -std::ostream& operator<<(std::ostream& out, const Consumer& obj); + virtual void wakeup() = 0; + virtual void print(std::ostream& out) const = 0; -// ******************* Definitions ******************* + const Time& + getLastScheduledWakeup() const + { + return m_last_scheduled_wakeup; + } + + void + setLastScheduledWakeup(const Time& time) + { + m_last_scheduled_wakeup = time; + } + + bool + alreadyScheduled(Time time) + { + return m_scheduled_wakeups.find(time) != m_scheduled_wakeups.end(); + } + + void + insertScheduledWakeupTime(Time time) + { + m_scheduled_wakeups.insert(time); + } + + void + removeScheduledWakeupTime(Time time) + { + assert(alreadyScheduled(time)); + m_scheduled_wakeups.erase(time); + } + + private: + Time m_last_scheduled_wakeup; + std::set<Time> m_scheduled_wakeups; + Time m_last_wakeup; +}; -// Output operator definition -inline extern -std::ostream& operator<<(std::ostream& out, const Consumer& obj) +inline std::ostream& +operator<<(std::ostream& out, const Consumer& obj) { - obj.print(out); - out << std::flush; - return out; + obj.print(out); + out << std::flush; + return out; } -#endif //CONSUMER_H +#endif // __MEM_RUBY_COMMON_CONSUMER_HH__ diff --git a/src/mem/ruby/common/DataBlock.cc b/src/mem/ruby/common/DataBlock.cc index 75ede7f4f..8d3c81242 100644 --- a/src/mem/ruby/common/DataBlock.cc +++ b/src/mem/ruby/common/DataBlock.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -32,13 +31,14 @@ DataBlock & DataBlock::operator=(const DataBlock & obj) { - if (this == &obj) { - // assert(false); - } else { - if (!m_alloc) - m_data = new uint8[RubySystem::getBlockSizeBytes()]; - memcpy(m_data, obj.m_data, RubySystem::getBlockSizeBytes()); - m_alloc = true; - } - return *this; + if (this == &obj) { + // assert(false); + } else { + if (!m_alloc) + m_data = new uint8[RubySystem::getBlockSizeBytes()]; + memcpy(m_data, obj.m_data, RubySystem::getBlockSizeBytes()); + m_alloc = true; + } + + return *this; } diff --git a/src/mem/ruby/common/DataBlock.hh b/src/mem/ruby/common/DataBlock.hh index 5407033bf..edf774166 100644 --- a/src/mem/ruby/common/DataBlock.hh +++ b/src/mem/ruby/common/DataBlock.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,152 +26,144 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DATABLOCK_H -#define DATABLOCK_H +#ifndef __MEM_RUBY_COMMON_DATABLOCK_HH__ +#define __MEM_RUBY_COMMON_DATABLOCK_HH__ #include <iomanip> #include <iostream> +#include "mem/gems_common/Vector.hh" #include "mem/ruby/common/Global.hh" #include "mem/ruby/system/System.hh" -#include "mem/gems_common/Vector.hh" -class DataBlock { - public: - // Constructors - DataBlock() {alloc();} - DataBlock(const DataBlock & cp) { - m_data = new uint8[RubySystem::getBlockSizeBytes()]; - memcpy(m_data, cp.m_data, RubySystem::getBlockSizeBytes()); - m_alloc = true; - } +class DataBlock +{ + public: + DataBlock() + { + alloc(); + } - // Destructor - ~DataBlock() { - if(m_alloc) { - delete [] m_data; + DataBlock(const DataBlock &cp) + { + m_data = new uint8[RubySystem::getBlockSizeBytes()]; + memcpy(m_data, cp.m_data, RubySystem::getBlockSizeBytes()); + m_alloc = true; } - } - - DataBlock& operator=(const DataBlock& obj); - - // Public Methods - void assign(uint8* data); - - void clear(); - uint8 getByte(int whichByte) const; - const uint8* getData(int offset, int len) const; - void setByte(int whichByte, uint8 data); - void setData(uint8* data, int offset, int len); - void copyPartial(const DataBlock & dblk, int offset, int len); - bool equal(const DataBlock& obj) const; - void print(std::ostream& out) const; - -private: - void alloc(); - // Data Members (m_ prefix) - uint8* m_data; - bool m_alloc; -}; -// Output operator declaration -std::ostream& operator<<(std::ostream& out, const DataBlock& obj); + ~DataBlock() + { + if (m_alloc) + delete [] m_data; + } + + DataBlock& operator=(const DataBlock& obj); + + void assign(uint8* data); -bool operator==(const DataBlock& obj1, const DataBlock& obj2); + void clear(); + uint8 getByte(int whichByte) const; + const uint8* getData(int offset, int len) const; + void setByte(int whichByte, uint8 data); + void setData(uint8* data, int offset, int len); + void copyPartial(const DataBlock & dblk, int offset, int len); + bool equal(const DataBlock& obj) const; + void print(std::ostream& out) const; -// inline functions for speed + private: + void alloc(); + uint8* m_data; + bool m_alloc; +}; -inline -void DataBlock::assign(uint8* data) +inline void +DataBlock::assign(uint8* data) { - if (m_alloc) { - delete [] m_data; - } - m_data = data; - m_alloc = false; + if (m_alloc) { + delete [] m_data; + } + m_data = data; + m_alloc = false; } -inline -void DataBlock::alloc() +inline void +DataBlock::alloc() { - m_data = new uint8[RubySystem::getBlockSizeBytes()]; - m_alloc = true; - clear(); + m_data = new uint8[RubySystem::getBlockSizeBytes()]; + m_alloc = true; + clear(); } -inline -void DataBlock::clear() +inline void +DataBlock::clear() { - memset(m_data, 0, RubySystem::getBlockSizeBytes()); + memset(m_data, 0, RubySystem::getBlockSizeBytes()); } -inline -bool DataBlock::equal(const DataBlock& obj) const +inline bool +DataBlock::equal(const DataBlock& obj) const { - return !memcmp(m_data, obj.m_data, RubySystem::getBlockSizeBytes()); + return !memcmp(m_data, obj.m_data, RubySystem::getBlockSizeBytes()); } -inline -void DataBlock::print(std::ostream& out) const +inline void +DataBlock::print(std::ostream& out) const { - using namespace std; - - int size = RubySystem::getBlockSizeBytes(); - out << "[ "; - for (int i = 0; i < size; i++) { - out << setw(2) << setfill('0') << hex << "0x" << (int)m_data[i] << " "; - out << setfill(' '); - } - out << dec << "]" << flush; + using namespace std; + + int size = RubySystem::getBlockSizeBytes(); + out << "[ "; + for (int i = 0; i < size; i++) { + out << setw(2) << setfill('0') << hex << "0x" << (int)m_data[i] << " "; + out << setfill(' '); + } + out << dec << "]" << flush; } -inline -uint8 DataBlock::getByte(int whichByte) const +inline uint8 +DataBlock::getByte(int whichByte) const { - return m_data[whichByte]; + return m_data[whichByte]; } -inline -const uint8* DataBlock::getData(int offset, int len) const +inline const uint8* +DataBlock::getData(int offset, int len) const { - assert(offset + len <= RubySystem::getBlockSizeBytes()); - return &m_data[offset]; + assert(offset + len <= RubySystem::getBlockSizeBytes()); + return &m_data[offset]; } -inline -void DataBlock::setByte(int whichByte, uint8 data) +inline void +DataBlock::setByte(int whichByte, uint8 data) { m_data[whichByte] = data; } -inline -void DataBlock::setData(uint8* data, int offset, int len) +inline void +DataBlock::setData(uint8* data, int offset, int len) { - assert(offset + len <= RubySystem::getBlockSizeBytes()); - memcpy(&m_data[offset], data, len); + assert(offset + len <= RubySystem::getBlockSizeBytes()); + memcpy(&m_data[offset], data, len); } -inline -void DataBlock::copyPartial(const DataBlock & dblk, int offset, int len) +inline void +DataBlock::copyPartial(const DataBlock & dblk, int offset, int len) { - setData(&dblk.m_data[offset], offset, len); + setData(&dblk.m_data[offset], offset, len); } -// ******************* Definitions ******************* - -// Output operator definition -extern inline -std::ostream& operator<<(std::ostream& out, const DataBlock& obj) +inline std::ostream& +operator<<(std::ostream& out, const DataBlock& obj) { - obj.print(out); - out << std::flush; - return out; + obj.print(out); + out << std::flush; + return out; } -extern inline -bool operator==(const DataBlock& obj1,const DataBlock& obj2) +inline bool +operator==(const DataBlock& obj1,const DataBlock& obj2) { - return (obj1.equal(obj2)); + return obj1.equal(obj2); } -#endif //DATABLOCK_H +#endif // __MEM_RUBY_COMMON_DATABLOCK_HH__ diff --git a/src/mem/ruby/common/Debug.cc b/src/mem/ruby/common/Debug.cc index e67dc68ba..2c1acc4ff 100644 --- a/src/mem/ruby/common/Debug.cc +++ b/src/mem/ruby/common/Debug.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,19 +26,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - * - */ - #include <fstream> #include <stdarg.h> -#include "mem/ruby/common/Global.hh" +#include "base/misc.hh" +#include "mem/gems_common/util.hh" #include "mem/ruby/common/Debug.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" -#include "mem/gems_common/util.hh" -#include "base/misc.hh" using namespace std; @@ -79,313 +73,272 @@ DebugComponentData debugComponents[] = extern "C" void changeDebugVerbosity(VerbosityLevel vb); extern "C" void changeDebugFilter(int filter); -void changeDebugVerbosity(VerbosityLevel vb) +void +changeDebugVerbosity(VerbosityLevel vb) { - g_debug_ptr->setVerbosity(vb); + g_debug_ptr->setVerbosity(vb); } -void changeDebugFilter(int filter) +void +changeDebugFilter(int filter) { - g_debug_ptr->setFilter(filter); + g_debug_ptr->setFilter(filter); } Debug::Debug(const Params *p) : SimObject(p) { - clearFilter(); - debug_cout_ptr = &cout; - - setFilterString(p->filter_string.c_str()); - setVerbosityString(p->verbosity_string.c_str()); - setDebugOutputFile(p->output_filename.c_str()); - m_starting_cycle = p->start_time; - m_protocol_trace = p->protocol_trace; - g_debug_ptr = this; -} - + clearFilter(); + debug_cout_ptr = &cout; -Debug::~Debug() -{ + setFilterString(p->filter_string.c_str()); + setVerbosityString(p->verbosity_string.c_str()); + setDebugOutputFile(p->output_filename.c_str()); + m_starting_cycle = p->start_time; + m_protocol_trace = p->protocol_trace; + g_debug_ptr = this; } -void Debug::printVerbosity(ostream& out) const +Debug::~Debug() { - switch (getVerbosity()) { - case No_Verb: - out << "verbosity = No_Verb" << endl; - break; - case Low_Verb: - out << "verbosity = Low_Verb" << endl; - break; - case Med_Verb: - out << "verbosity = Med_Verb" << endl; - break; - case High_Verb: - out << "verbosity = High_Verb" << endl; - break; - default: - out << "verbosity = unknown" << endl; - } } -bool Debug::validDebug(int module, PriorityLevel priority) +void +Debug::printVerbosity(ostream& out) const { - int local_module = (1 << module); - if(m_filter & local_module) { - if (g_eventQueue_ptr == NULL || - g_eventQueue_ptr->getTime() >= m_starting_cycle) { - switch(m_verbosityLevel) { + switch (getVerbosity()) { case No_Verb: - return false; + out << "verbosity = No_Verb" << endl; break; case Low_Verb: - if(priority == HighPrio) { - return true; - }else{ - return false; - } + out << "verbosity = Low_Verb" << endl; break; case Med_Verb: - if(priority == HighPrio || priority == MedPrio ) { - return true; - }else{ - return false; - } + out << "verbosity = Med_Verb" << endl; break; case High_Verb: - return true; + out << "verbosity = High_Verb" << endl; break; - } + default: + out << "verbosity = unknown" << endl; } - } - return false; } -void Debug::setDebugTime(Time t) +bool +Debug::validDebug(int module, PriorityLevel priority) { - m_starting_cycle = t; + int local_module = (1 << module); + if (m_filter & local_module) { + if (g_eventQueue_ptr == NULL || + g_eventQueue_ptr->getTime() >= m_starting_cycle) { + switch (m_verbosityLevel) { + case No_Verb: + return false; + case Low_Verb: + return (priority == HighPrio); + case Med_Verb: + return (priority == HighPrio || priority == MedPrio); + case High_Verb: + return true; + } + } + } + return false; } -void Debug::setVerbosity(VerbosityLevel vb) +void +Debug::setDebugTime(Time t) { - m_verbosityLevel = vb; + m_starting_cycle = t; } -void Debug::setFilter(int filter) +void +Debug::setVerbosity(VerbosityLevel vb) { - m_filter = filter; + m_verbosityLevel = vb; } -bool Debug::checkVerbosityString(const char *verb_str) +void +Debug::setFilter(int filter) { - if (verb_str == NULL) { - cerr << "Error: unrecognized verbosity (use none, low, med, high): NULL" << endl; - return true; // error - } else if ( (string(verb_str) == "none") || - (string(verb_str) == "low") || - (string(verb_str) == "med") || - (string(verb_str) == "high") ) { - return false; - } - cerr << "Error: unrecognized verbosity (use none, low, med, high): NULL" << endl; - return true; // error + m_filter = filter; } -bool Debug::setVerbosityString(const char *verb_str) +bool +Debug::setVerbosityString(const char *verb_str) { - bool check_fails = checkVerbosityString(verb_str); - if (check_fails) { - return true; // error - } - if (string(verb_str) == "none") { - setVerbosity(No_Verb); - } else if (string(verb_str) == "low") { - setVerbosity(Low_Verb); - } else if (string(verb_str) == "med") { - setVerbosity(Med_Verb); - } else if (string(verb_str) == "high") { - setVerbosity(High_Verb); - } else { - cerr << "Error: unrecognized verbosity (use none, low, med, high): " << verb_str << endl; - return true; // error - } - return false; // no error + string verb = verb_str ? verb_str : ""; + if (verb == "none") { + setVerbosity(No_Verb); + } else if (verb == "low") { + setVerbosity(Low_Verb); + } else if (verb == "med") { + setVerbosity(Med_Verb); + } else if (verb == "high") { + setVerbosity(High_Verb); + } else { + cerr << "Error: unrecognized verbosity (use none, low, med, high): " + << verb << endl; + return true; // error + } + return false; // no error } -bool Debug::checkFilter(char ch) +bool +Debug::checkFilter(char ch) { - for (int i=0; i<NUMBER_OF_COMPS; i++) { - // Look at all components to find a character match - if (debugComponents[i].ch == ch) { - // We found a match - return no error - return false; // no error + for (int i = 0; i < NUMBER_OF_COMPS; i++) { + // Look at all components to find a character match + if (debugComponents[i].ch == ch) { + // We found a match - return no error + return false; // no error + } } - } - return true; // error + return true; // error } -bool Debug::checkFilterString(const char *filter_str) +bool +Debug::checkFilterString(const char *filter_str) { - if (filter_str == NULL) { - cerr << "Error: unrecognized component filter: NULL" << endl; - return true; // error - } + if (filter_str == NULL) { + cerr << "Error: unrecognized component filter: NULL" << endl; + return true; // error + } - // check for default filter ("none") before reporting RUBY_DEBUG error - if ( (string(filter_str) == "none") ) { - return false; // no error - } + // check for default filter ("none") before reporting RUBY_DEBUG error + if (string(filter_str) == "none") { + return false; // no error + } - if (RUBY_DEBUG == false) { - cerr << "Error: User specified set of debug components, but the RUBY_DEBUG compile-time flag is false." << endl; - cerr << "Solution: Re-compile with RUBY_DEBUG set to true." << endl; - return true; // error - } + if (RUBY_DEBUG == false) { + cerr << "Error: User specified set of debug components, but the " + << "RUBY_DEBUG compile-time flag is false." << endl + << "Solution: Re-compile with RUBY_DEBUG set to true." << endl; + return true; // error + } - if ( (string(filter_str) == "all") ) { - return false; // no error - } + if (string(filter_str) == "all") { + return false; // no error + } - // scan string checking each character - for (unsigned int i = 0; i < strlen(filter_str); i++) { - bool unrecognized = checkFilter( filter_str[i] ); - if (unrecognized == true) { - return true; // error + // scan string checking each character + for (unsigned int i = 0; i < strlen(filter_str); i++) { + bool unrecognized = checkFilter(filter_str[i]); + if (unrecognized == true) { + return true; // error + } } - } - return false; // no error + return false; // no error } -bool Debug::setFilterString(const char *filter_str) +bool +Debug::setFilterString(const char *filter_str) { - if (checkFilterString(filter_str)) { - return true; // error - } - - if (string(filter_str) == "all" ) { - allFilter(); - } else if (string(filter_str) == "none") { - clearFilter(); - } else { - // scan string adding to bit mask for each component which is present - for (unsigned int i = 0; i < strlen(filter_str); i++) { - bool error = addFilter( filter_str[i] ); - if (error) { + if (checkFilterString(filter_str)) { return true; // error - } } - } - return false; // no error + + if (string(filter_str) == "all" ) { + allFilter(); + } else if (string(filter_str) == "none") { + clearFilter(); + } else { + // scan string adding to bit mask for each component which is present + for (unsigned int i = 0; i < strlen(filter_str); i++) { + bool error = addFilter( filter_str[i] ); + if (error) { + return true; // error + } + } + } + return false; // no error } -bool Debug::addFilter(char ch) +bool +Debug::addFilter(char ch) { - for (int i=0; i<NUMBER_OF_COMPS; i++) { - // Look at all components to find a character match - if (debugComponents[i].ch == ch) { - // We found a match - update the filter bit mask - cout << " Debug: Adding to filter: '" << ch << "' (" << debugComponents[i].desc << ")" << endl; - m_filter |= (1 << i); - return false; // no error + for (int i = 0; i < NUMBER_OF_COMPS; i++) { + // Look at all components to find a character match + if (debugComponents[i].ch == ch) { + // We found a match - update the filter bit mask + cout << " Debug: Adding to filter: '" << ch << "' (" + << debugComponents[i].desc << ")" << endl; + m_filter |= (1 << i); + return false; // no error + } } - } - // We didn't find the character - cerr << "Error: unrecognized component filter: " << ch << endl; - usageInstructions(); - return true; // error + // We didn't find the character + cerr << "Error: unrecognized component filter: " << ch << endl; + usageInstructions(); + return true; // error } -void Debug::clearFilter() +void +Debug::clearFilter() { - m_filter = 0; + m_filter = 0; } void Debug::allFilter() { - m_filter = ~0; + m_filter = ~0; } -void Debug::usageInstructions(void) +void +Debug::usageInstructions(void) { - cerr << "Debug components: " << endl; - for (int i=0; i<NUMBER_OF_COMPS; i++) { - cerr << " " << debugComponents[i].ch << ": " << debugComponents[i].desc << endl; - } + cerr << "Debug components: " << endl; + for (int i = 0; i < NUMBER_OF_COMPS; i++) { + cerr << " " << debugComponents[i].ch << ": " + << debugComponents[i].desc << endl; + } } -void Debug::print(ostream& out) const +void +Debug::print(ostream& out) const { - out << "[Debug]" << endl; + out << "[Debug]" << endl; } -void Debug::setDebugOutputFile (const char * filename) +void +Debug::setDebugOutputFile (const char *filename) { - if ( (filename == NULL) || - (!strcmp(filename, "none")) ) { - debug_cout_ptr = &cout; - return; - } - - if (m_fout.is_open() ) { - m_fout.close (); - } - m_fout.open (filename, ios::out); - if (! m_fout.is_open() ) { - cerr << "setDebugOutputFile: can't open file " << filename << endl; - } - else { - debug_cout_ptr = &m_fout; - } -} + if (filename == NULL || !strcmp(filename, "none")) { + debug_cout_ptr = &cout; + return; + } -void Debug::closeDebugOutputFile () -{ - if (m_fout.is_open() ) { - m_fout.close (); - debug_cout_ptr = &cout; - } + if (m_fout.is_open()) { + m_fout.close(); + } + m_fout.open(filename, ios::out); + if (!m_fout.is_open()) { + cerr << "setDebugOutputFile: can't open file " << filename << endl; + } else { + debug_cout_ptr = &m_fout; + } } -void Debug::debugMsg( const char *fmt, ... ) +void +Debug::closeDebugOutputFile () { - va_list args; - - // you could check validDebug() here before printing the message - va_start(args, fmt); - vfprintf(stdout, fmt, args); - va_end(args); + if (m_fout.is_open()) { + m_fout.close (); + debug_cout_ptr = &cout; + } } -/* -void DEBUG_OUT( const char* fmt, ...) { - if (RUBY_DEBUG) { - cout << "Debug: in fn " - << __PRETTY_FUNCTION__ - << " in " << __FILE__ << ":" - << __LINE__ << ": "; +void +Debug::debugMsg( const char *fmt, ...) +{ va_list args; - va_start(args, fmt); - vfprintf(stdout, fmt, args); - va_end(args); - } -} -void ERROR_OUT( const char* fmt, ... ) { - if (ERROR_MESSAGE_FLAG) { - cout << "error: in fn " - << __PRETTY_FUNCTION__ << " in " - << __FILE__ << ":" - << __LINE__ << ": "; - va_list args; + // you could check validDebug() here before printing the message va_start(args, fmt); vfprintf(stdout, fmt, args); va_end(args); - } - assert(0); } -*/ - Debug * RubyDebugParams::create() diff --git a/src/mem/ruby/common/Debug.hh b/src/mem/ruby/common/Debug.hh index a7b1a15d1..a2344e82d 100644 --- a/src/mem/ruby/common/Debug.hh +++ b/src/mem/ruby/common/Debug.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,12 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - */ - -#ifndef __MEM_RUBY_DEBUG_HH__ -#define __MEM_RUBY_DEBUG_HH__ +#ifndef __MEM_RUBY_COMMON_DEBUG_HH__ +#define __MEM_RUBY_COMMON_DEBUG_HH__ #include <unistd.h> @@ -75,68 +70,55 @@ enum DebugComponents enum PriorityLevel {HighPrio, MedPrio, LowPrio}; enum VerbosityLevel {No_Verb, Low_Verb, Med_Verb, High_Verb}; -class Debug : public SimObject { -public: - // Constructors +class Debug : public SimObject +{ + public: typedef RubyDebugParams Params; - Debug(const Params *p); - - // Destructor - ~Debug(); - - // Public Methods - static bool getProtocolTrace() { return m_protocol_trace; } - bool validDebug(int module, PriorityLevel priority); - void printVerbosity(std::ostream& out) const; - void setVerbosity(VerbosityLevel vb); - static bool checkVerbosityString(const char *verb_str); - bool setVerbosityString(const char *); - VerbosityLevel getVerbosity() const { return m_verbosityLevel; } - void setFilter(int); - static bool checkFilter( char); - static bool checkFilterString(const char *); - bool setFilterString(const char *); - void setDebugTime(Time); - Time getDebugTime() const { return m_starting_cycle; } - bool addFilter(char); - void clearFilter(); - void allFilter(); - void print(std::ostream& out) const; - /* old school debugging "vararg": sends messages to screen and log */ - void debugMsg( const char *fmt, ... ); - - void setDebugOutputFile (const char * filename); - void closeDebugOutputFile (); - static void usageInstructions(void); - -private: - // Private Methods - - // Private copy constructor and assignment operator - Debug(const Debug& obj); - Debug& operator=(const Debug& obj); - - // Data Members (m_ prefix) - static bool m_protocol_trace; - VerbosityLevel m_verbosityLevel; - int m_filter; - Time m_starting_cycle; - - std::fstream m_fout; + Debug(const Params *p); + ~Debug(); + + static bool getProtocolTrace() { return m_protocol_trace; } + bool validDebug(int module, PriorityLevel priority); + void printVerbosity(std::ostream& out) const; + void setVerbosity(VerbosityLevel vb); + bool setVerbosityString(const char *); + VerbosityLevel getVerbosity() const { return m_verbosityLevel; } + void setFilter(int); + static bool checkFilter( char); + static bool checkFilterString(const char *); + bool setFilterString(const char *); + void setDebugTime(Time); + Time getDebugTime() const { return m_starting_cycle; } + bool addFilter(char); + void clearFilter(); + void allFilter(); + void print(std::ostream& out) const; + /* old school debugging "vararg": sends messages to screen and log */ + void debugMsg(const char *fmt, ...); + + void setDebugOutputFile (const char * filename); + void closeDebugOutputFile (); + static void usageInstructions(void); + + private: + // Private copy constructor and assignment operator + Debug(const Debug& obj); + Debug& operator=(const Debug& obj); + + static bool m_protocol_trace; + VerbosityLevel m_verbosityLevel; + int m_filter; + Time m_starting_cycle; + + std::fstream m_fout; }; -// Output operator declaration -std::ostream& operator<<(std::ostream& out, const Debug& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -std::ostream& operator<<(std::ostream& out, const Debug& obj) +inline std::ostream& +operator<<(std::ostream& out, const Debug& obj) { - obj.print(out); - out << std::flush; - return out; + obj.print(out); + out << std::flush; + return out; } const bool ERROR_MESSAGE_FLAG = true; @@ -151,178 +133,168 @@ const bool ASSERT_FLAG = true; #undef assert #define assert(EXPR) ASSERT(EXPR) #undef ASSERT -#define ASSERT(EXPR)\ -{\ - using namespace std;\ - if (ASSERT_FLAG) {\ - if (!(EXPR)) {\ - cerr << "failed assertion '"\ - << #EXPR << "' at fn "\ - << __PRETTY_FUNCTION__ << " in "\ - << __FILE__ << ":"\ - << __LINE__ << endl << flush;\ - (* debug_cout_ptr) << "failed assertion '"\ - << #EXPR << "' at fn "\ - << __PRETTY_FUNCTION__ << " in "\ - << __FILE__ << ":"\ - << __LINE__ << endl << flush;\ - if(isatty(STDIN_FILENO)) {\ - cerr << "At this point you might want to attach a debug to ";\ - cerr << "the running and get to the" << endl;\ - cerr << "crash site; otherwise press enter to continue" << endl;\ - cerr << "PID: " << getpid();\ - cerr << endl << flush; \ - char c; \ - cin.get(c); \ - }\ - abort();\ - }\ - }\ -} - -#define BREAK(X)\ -{\ - using namespace std;\ - cerr << "breakpoint '"\ - << #X << "' reached at fn "\ - << __PRETTY_FUNCTION__ << " in "\ - << __FILE__ << ":"\ - << __LINE__ << endl << flush;\ - if(isatty(STDIN_FILENO)) {\ - cerr << "press enter to continue" << endl;\ - cerr << "PID: " << getpid();\ - cerr << endl << flush; \ - char c; \ - cin.get(c); \ - }\ -} - -#define ERROR_MSG(MESSAGE)\ -{\ - using namespace std;\ - if (ERROR_MESSAGE_FLAG) {\ - cerr << "Fatal Error: in fn "\ - << __PRETTY_FUNCTION__ << " in "\ - << __FILE__ << ":"\ - << __LINE__ << ": "\ - << (MESSAGE) << endl << flush;\ - (* debug_cout_ptr) << "Fatal Error: in fn "\ - << __PRETTY_FUNCTION__ << " in "\ - << __FILE__ << ":"\ - << __LINE__ << ": "\ - << (MESSAGE) << endl << flush;\ - abort();\ - }\ -} - -#define WARN_MSG(MESSAGE)\ -{\ - using namespace std;\ - if (WARNING_MESSAGE_FLAG) {\ - cerr << "Warning: in fn "\ - << __PRETTY_FUNCTION__ << " in "\ - << __FILE__ << ":"\ - << __LINE__ << ": "\ - << (MESSAGE) << endl << flush;\ - (* debug_cout_ptr) << "Warning: in fn "\ - << __PRETTY_FUNCTION__ << " in "\ - << __FILE__ << ":"\ - << __LINE__ << ": "\ - << (MESSAGE) << endl << flush;\ - }\ -} - -#define WARN_EXPR(EXPR)\ -{\ - using namespace std;\ - if (WARNING_MESSAGE_FLAG) {\ - cerr << "Warning: in fn "\ - << __PRETTY_FUNCTION__ << " in "\ - << __FILE__ << ":"\ - << __LINE__ << ": "\ - << #EXPR << " is "\ - << (EXPR) << endl << flush;\ - (* debug_cout_ptr) << "Warning: in fn "\ - << __PRETTY_FUNCTION__ << " in "\ - << __FILE__ << ":"\ - << __LINE__ << ": "\ - << #EXPR << " is "\ - << (EXPR) << endl << flush;\ - }\ -} - -#define DEBUG_MSG(module, priority, MESSAGE)\ -{\ - using namespace std;\ - if (RUBY_DEBUG) {\ - if (g_debug_ptr->validDebug(module, priority)) {\ - (* debug_cout_ptr) << "Debug: in fn "\ - << __PRETTY_FUNCTION__\ - << " in " << __FILE__ << ":"\ - << __LINE__ << ": "\ - << (MESSAGE) << endl << flush;\ - }\ - }\ -} - -#define DEBUG_EXPR(module, priority, EXPR)\ -{\ - using namespace std;\ - if (RUBY_DEBUG) {\ - if (g_debug_ptr->validDebug(module, priority)) {\ - (* debug_cout_ptr) << "Debug: in fn "\ - << __PRETTY_FUNCTION__\ - << " in " << __FILE__ << ":"\ - << __LINE__ << ": "\ - << #EXPR << " is "\ - << (EXPR) << endl << flush;\ - }\ - }\ -} - -#define DEBUG_NEWLINE(module, priority)\ -{\ - using namespace std;\ - if (RUBY_DEBUG) {\ - if (g_debug_ptr->validDebug(module, priority)) {\ - (* debug_cout_ptr) << endl << flush;\ - }\ - }\ -} - -#define DEBUG_SLICC(priority, LINE, MESSAGE)\ -{\ - using namespace std;\ - if (RUBY_DEBUG) {\ - if (g_debug_ptr->validDebug(SLICC_COMP, priority)) {\ - (* debug_cout_ptr) << (LINE) << (MESSAGE) << endl << flush;\ - }\ - }\ -} - -#define DEBUG_OUT( rest... ) \ -{\ - using namespace std;\ - if (RUBY_DEBUG) {\ - cout << "Debug: in fn "\ - << __PRETTY_FUNCTION__\ - << " in " << __FILE__ << ":"\ - << __LINE__ << ": "; \ - g_debug_ptr->debugMsg(rest); \ - }\ -} - -#define ERROR_OUT( rest... ) \ -{\ - using namespace std;\ - if (ERROR_MESSAGE_FLAG) {\ - cout << "error: in fn "\ - << __PRETTY_FUNCTION__ << " in "\ - << __FILE__ << ":"\ - << __LINE__ << ": ";\ - g_debug_ptr->debugMsg(rest); \ - }\ -} - -#endif //DEBUG_H +#define ASSERT(EXPR) do { \ + using namespace std; \ + if (ASSERT_FLAG) { \ + if (!(EXPR)) { \ + cerr << "failed assertion '" \ + << #EXPR << "' at fn " \ + << __PRETTY_FUNCTION__ << " in " \ + << __FILE__ << ":" \ + << __LINE__ << endl << flush; \ + (*debug_cout_ptr) << "failed assertion '" \ + << #EXPR << "' at fn " \ + << __PRETTY_FUNCTION__ << " in " \ + << __FILE__ << ":" \ + << __LINE__ << endl << flush; \ + if (isatty(STDIN_FILENO)) { \ + cerr << "At this point you might want to attach a debug to " \ + << "the running and get to the" << endl \ + << "crash site; otherwise press enter to continue" \ + << endl \ + << "PID: " << getpid() \ + << endl << flush; \ + char c; \ + cin.get(c); \ + } \ + abort(); \ + } \ + } \ +} while (0) + +#define BREAK(X) do { \ + using namespace std; \ + cerr << "breakpoint '" \ + << #X << "' reached at fn " \ + << __PRETTY_FUNCTION__ << " in " \ + << __FILE__ << ":" \ + << __LINE__ << endl << flush; \ + if(isatty(STDIN_FILENO)) { \ + cerr << "press enter to continue" << endl; \ + cerr << "PID: " << getpid(); \ + cerr << endl << flush; \ + char c; \ + cin.get(c); \ + } \ +} while (0) + +#define ERROR_MSG(MESSAGE) do { \ + using namespace std; \ + if (ERROR_MESSAGE_FLAG) { \ + cerr << "Fatal Error: in fn " \ + << __PRETTY_FUNCTION__ << " in " \ + << __FILE__ << ":" \ + << __LINE__ << ": " \ + << (MESSAGE) << endl << flush; \ + (* debug_cout_ptr) << "Fatal Error: in fn " \ + << __PRETTY_FUNCTION__ << " in " \ + << __FILE__ << ":" \ + << __LINE__ << ": " \ + << (MESSAGE) << endl << flush; \ + abort(); \ + } \ +} while(0) + +#define WARN_MSG(MESSAGE) do { \ + using namespace std; \ + if (WARNING_MESSAGE_FLAG) { \ + cerr << "Warning: in fn " \ + << __PRETTY_FUNCTION__ << " in " \ + << __FILE__ << ":" \ + << __LINE__ << ": " \ + << (MESSAGE) << endl << flush; \ + (* debug_cout_ptr) << "Warning: in fn " \ + << __PRETTY_FUNCTION__ << " in " \ + << __FILE__ << ":" \ + << __LINE__ << ": " \ + << (MESSAGE) << endl << flush; \ + } \ +} while (0) + +#define WARN_EXPR(EXPR) do { \ + using namespace std; \ + if (WARNING_MESSAGE_FLAG) { \ + cerr << "Warning: in fn " \ + << __PRETTY_FUNCTION__ << " in " \ + << __FILE__ << ":" \ + << __LINE__ << ": " \ + << #EXPR << " is " \ + << (EXPR) << endl << flush; \ + (* debug_cout_ptr) << "Warning: in fn " \ + << __PRETTY_FUNCTION__ << " in " \ + << __FILE__ << ":" \ + << __LINE__ << ": " \ + << #EXPR << " is " \ + << (EXPR) << endl << flush; \ + } \ +} while (0) + +#define DEBUG_MSG(module, priority, MESSAGE) do { \ + using namespace std; \ + if (RUBY_DEBUG) { \ + if (g_debug_ptr->validDebug(module, priority)) { \ + (* debug_cout_ptr) << "Debug: in fn " \ + << __PRETTY_FUNCTION__ \ + << " in " << __FILE__ << ":" \ + << __LINE__ << ": " \ + << (MESSAGE) << endl << flush; \ + } \ + } \ +} while (0) + +#define DEBUG_EXPR(module, priority, EXPR) do { \ + using namespace std; \ + if (RUBY_DEBUG) { \ + if (g_debug_ptr->validDebug(module, priority)) { \ + (* debug_cout_ptr) << "Debug: in fn " \ + << __PRETTY_FUNCTION__ \ + << " in " << __FILE__ << ":" \ + << __LINE__ << ": " \ + << #EXPR << " is " \ + << (EXPR) << endl << flush; \ + } \ + } \ +} while (0) + +#define DEBUG_NEWLINE(module, priority) do { \ + using namespace std; \ + if (RUBY_DEBUG) { \ + if (g_debug_ptr->validDebug(module, priority)) { \ + (* debug_cout_ptr) << endl << flush; \ + } \ + } \ +} while (0) + +#define DEBUG_SLICC(priority, LINE, MESSAGE) do { \ + using namespace std; \ + if (RUBY_DEBUG) { \ + if (g_debug_ptr->validDebug(SLICC_COMP, priority)) { \ + (* debug_cout_ptr) << (LINE) << (MESSAGE) << endl << flush; \ + } \ + } \ +} while (0) + +#define DEBUG_OUT(rest... ) do { \ + using namespace std; \ + if (RUBY_DEBUG) { \ + cout << "Debug: in fn " \ + << __PRETTY_FUNCTION__ \ + << " in " << __FILE__ << ":" \ + << __LINE__ << ": "; \ + g_debug_ptr->debugMsg(rest); \ + } \ +} while (0) + +#define ERROR_OUT( rest... ) do { \ + using namespace std; \ + if (ERROR_MESSAGE_FLAG) { \ + cout << "error: in fn " \ + << __PRETTY_FUNCTION__ << " in " \ + << __FILE__ << ":" \ + << __LINE__ << ": "; \ + g_debug_ptr->debugMsg(rest); \ + } \ +} while (0) + +#endif // __MEM_RUBY_COMMON_DEBUG_HH__ diff --git a/src/mem/ruby/common/Driver.cc b/src/mem/ruby/common/Driver.cc index 2d6034b02..085044c7d 100644 --- a/src/mem/ruby/common/Driver.cc +++ b/src/mem/ruby/common/Driver.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,6 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <cassert> + #include "mem/ruby/common/Driver.hh" Driver::Driver() @@ -37,3 +38,40 @@ Driver::Driver() Driver::~Driver() { } + +integer_t +Driver::getInstructionCount(int procID) const +{ + return 1; +} + +integer_t +Driver::getCycleCount(int procID) const +{ + return 1; +} + +void +Driver::addThreadDependency(int procID, int requestor_thread, + int conflict_thread) const +{ + assert(0); +} + +void +Driver::printDebug() +{} + +integer_t +Driver::readPhysicalMemory(int procID, physical_address_t address, int len) +{ + assert(0); + return 0; +} + +void +Driver::writePhysicalMemory(int procID, physical_address_t address, + integer_t value, int len) +{ + assert(0); +} diff --git a/src/mem/ruby/common/Driver.hh b/src/mem/ruby/common/Driver.hh index 9d17fcadb..f5f2f9c58 100644 --- a/src/mem/ruby/common/Driver.hh +++ b/src/mem/ruby/common/Driver.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,58 +26,40 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - * - * Description: - * - */ - -#ifndef DRIVER_H -#define DRIVER_H +#ifndef __MEM_RUBY_COMMON_DRIVER_HH__ +#define __MEM_RUBY_COMMON_DRIVER_HH__ -#include "mem/ruby/common/Global.hh" +#include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Consumer.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/system/NodeID.hh" -#include "mem/ruby/common/Address.hh" - - -class Driver { -public: - // Constructors - Driver(); - - // Destructor - virtual ~Driver() = 0; - - // Public Methods - virtual void get_network_config() {} - virtual void dmaHitCallback() {}; - virtual void hitCallback(int64_t id) = 0; // Called by sequencer - virtual void go() = 0; - virtual integer_t getInstructionCount(int procID) const { return 1; } - virtual integer_t getCycleCount(int procID) const { return 1; } - virtual void addThreadDependency(int procID, int requestor_thread, int conflict_thread) const { assert(0);} - virtual void printDebug(){} //called by Sequencer - - virtual void printStats(ostream& out) const = 0; - virtual void clearStats() = 0; - - virtual void printConfig(ostream& out) const = 0; - - - virtual integer_t readPhysicalMemory(int procID, physical_address_t address, - int len ){ ASSERT(0); return 0; } - - virtual void writePhysicalMemory( int procID, physical_address_t address, - integer_t value, int len ){ ASSERT(0); } - -protected: - // accessible by subclasses - -private: - // inaccessible by subclasses +class Driver +{ + public: + Driver(); + virtual ~Driver() = 0; + + // Public Methods + virtual void get_network_config() {} + virtual void dmaHitCallback() {}; + virtual void hitCallback(int64_t id) = 0; // Called by sequencer + virtual void go() = 0; + virtual integer_t getInstructionCount(int procID) const; + virtual integer_t getCycleCount(int procID) const; + virtual void addThreadDependency(int procID, int requestor_thread, + int conflict_thread) const; + virtual void printDebug(); //called by Sequencer + + virtual void printStats(ostream& out) const = 0; + virtual void clearStats() = 0; + + virtual void printConfig(ostream& out) const = 0; + + virtual integer_t readPhysicalMemory(int procID, physical_address_t addr, + int len); + virtual void writePhysicalMemory(int procID, physical_address_t addr, + integer_t value, int len); }; -#endif //DRIVER_H +#endif //__MEM_RUBY_COMMON_DRIVER_HH__ diff --git a/src/mem/ruby/common/Global.cc b/src/mem/ruby/common/Global.cc index 7c7cab1e8..f780707e2 100644 --- a/src/mem/ruby/common/Global.cc +++ b/src/mem/ruby/common/Global.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. diff --git a/src/mem/ruby/common/Global.hh b/src/mem/ruby/common/Global.hh index 16465656d..de96c5a6b 100644 --- a/src/mem/ruby/common/Global.hh +++ b/src/mem/ruby/common/Global.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,42 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - * - * */ - -#ifndef GLOBAL_H -#define GLOBAL_H - -/* -#ifdef SINGLE_LEVEL_CACHE -const bool TWO_LEVEL_CACHE = false; -#define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // currently all protocols require L1s == nodes -#define L1D_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // " -#define L2_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // " -#define L2_CACHE_VARIABLE m_L1Cache_cacheMemory_vec -#else -const bool TWO_LEVEL_CACHE = true; -#ifdef IS_CMP -#define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_L1IcacheMemory_vec[m_version] -#define L1D_CACHE_MEMBER_VARIABLE m_L1Cache_L1DcacheMemory_vec[m_version] -#define L2_CACHE_MEMBER_VARIABLE m_L2Cache_L2cacheMemory_vec[m_version] -#define L2_CACHE_VARIABLE m_L2Cache_L2cacheMemory_vec -#else // not IS_CMP -#define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_L1IcacheMemory_vec[m_version] // currently all protocols require L1s == nodes -#define L1D_CACHE_MEMBER_VARIABLE m_L1Cache_L1DcacheMemory_vec[m_version] // " -// #define L2_CACHE_MEMBER_VARIABLE m_L1Cache_L2cacheMemory_vec[m_version] // old exclusive caches don't support L2s != nodes -#define L2_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // old exclusive caches don't support L2s != nodes -#define L2_CACHE_VARIABLE m_L1Cache_L2cacheMemory_vec -#endif // IS_CMP -#endif //SINGLE_LEVEL_CACHE - -#define DIRECTORY_MEMBER_VARIABLE m_Directory_directory_vec[m_version] -#define TBE_TABLE_MEMBER_VARIABLE m_L1Cache_TBEs_vec[m_version] - -*/ - +#ifndef __MEM_RUBY_COMMON_GLOBAL_HH__ +#define __MEM_RUBY_COMMON_GLOBAL_HH__ // external includes for all classes #include "mem/ruby/common/TypeDefines.hh" @@ -85,13 +50,12 @@ extern RubySystem* g_system_ptr; class Debug; extern Debug* g_debug_ptr; -// FIXME: this is required by the contructor of Directory_Entry.hh. It can't go -// into slicc_util.hh because it opens a can of ugly worms +// FIXME: this is required by the contructor of Directory_Entry.hh. +// It can't go into slicc_util.hh because it opens a can of ugly worms extern inline int max_tokens() { return 1024; } - -#endif //GLOBAL_H +#endif // __MEM_RUBY_COMMON_GLOBAL_HH__ diff --git a/src/mem/ruby/common/Histogram.cc b/src/mem/ruby/common/Histogram.cc index 2a25cfeb1..c57b55997 100644 --- a/src/mem/ruby/common/Histogram.cc +++ b/src/mem/ruby/common/Histogram.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,164 +26,169 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - * - */ - #include <cmath> #include <iomanip> +#include "base/intmath.hh" #include "mem/ruby/common/Histogram.hh" using namespace std; Histogram::Histogram(int binsize, int bins) { - m_binsize = binsize; - m_bins = bins; - clear(); + m_binsize = binsize; + m_bins = bins; + clear(); } Histogram::~Histogram() { } -void Histogram::clear(int binsize, int bins) +void +Histogram::clear(int binsize, int bins) { - m_binsize = binsize; - clear(bins); + m_binsize = binsize; + clear(bins); } -void Histogram::clear(int bins) +void +Histogram::clear(int bins) { - m_bins = bins; - m_largest_bin = 0; - m_max = 0; - m_data.setSize(m_bins); - for (int i = 0; i < m_bins; i++) { - m_data[i] = 0; - } - m_count = 0; - m_max = 0; - - m_sumSamples = 0; - m_sumSquaredSamples = 0; + m_bins = bins; + m_largest_bin = 0; + m_max = 0; + m_data.setSize(m_bins); + for (int i = 0; i < m_bins; i++) { + m_data[i] = 0; + } + m_count = 0; + m_max = 0; + + m_sumSamples = 0; + m_sumSquaredSamples = 0; } -void Histogram::add(int64 value) +void +Histogram::add(int64 value) { - assert(value >= 0); - m_max = max(m_max, value); - m_count++; - - m_sumSamples += value; - m_sumSquaredSamples += (value*value); - - int index; - if (m_binsize == -1) { - // This is a log base 2 histogram - if (value == 0) { - index = 0; + assert(value >= 0); + m_max = max(m_max, value); + m_count++; + + m_sumSamples += value; + m_sumSquaredSamples += (value*value); + + int index; + if (m_binsize == -1) { + // This is a log base 2 histogram + if (value == 0) { + index = 0; + } else { + index = floorLog2(value) + 1; + if (index >= m_data.size()) { + index = m_data.size() - 1; + } + } } else { - index = int(log(double(value))/log(2.0))+1; - if (index >= m_data.size()) { - index = m_data.size()-1; - } - } - } else { - // This is a linear histogram - while (m_max >= (m_bins * m_binsize)) { - for (int i = 0; i < m_bins/2; i++) { - m_data[i] = m_data[i*2] + m_data[i*2 + 1]; - } - for (int i = m_bins/2; i < m_bins; i++) { - m_data[i] = 0; - } - m_binsize *= 2; + // This is a linear histogram + while (m_max >= (m_bins * m_binsize)) { + for (int i = 0; i < m_bins/2; i++) { + m_data[i] = m_data[i*2] + m_data[i*2 + 1]; + } + for (int i = m_bins/2; i < m_bins; i++) { + m_data[i] = 0; + } + m_binsize *= 2; + } + index = value/m_binsize; } - index = value/m_binsize; - } - assert(index >= 0); - m_data[index]++; - m_largest_bin = max(m_largest_bin, index); + assert(index >= 0); + m_data[index]++; + m_largest_bin = max(m_largest_bin, index); } -void Histogram::add(const Histogram& hist) +void +Histogram::add(const Histogram& hist) { - assert(hist.getBins() == m_bins); - assert(hist.getBinSize() == -1); // assume log histogram - assert(m_binsize == -1); - - for (int j = 0; j < hist.getData(0); j++) { - add(0); - } + assert(hist.getBins() == m_bins); + assert(hist.getBinSize() == -1); // assume log histogram + assert(m_binsize == -1); - for (int i = 1; i < m_bins; i++) { - for (int j = 0; j < hist.getData(i); j++) { - add(1<<(i-1)); // account for the + 1 index + for (int j = 0; j < hist.getData(0); j++) { + add(0); } - } + for (int i = 1; i < m_bins; i++) { + for (int j = 0; j < hist.getData(i); j++) { + add(1<<(i-1)); // account for the + 1 index + } + } } // Computation of standard deviation of samples a1, a2, ... aN // variance = [SUM {ai^2} - (SUM {ai})^2/N]/(N-1) // std deviation equals square root of variance -double Histogram::getStandardDeviation() const +double +Histogram::getStandardDeviation() const { - double variance; - if(m_count > 1){ - variance = (double)(m_sumSquaredSamples - m_sumSamples*m_sumSamples/m_count)/(m_count - 1); - } else { - return 0; - } - return sqrt(variance); + if (m_count <= 1) + return 0.0; + + double variance = + (double)(m_sumSquaredSamples - m_sumSamples * m_sumSamples / m_count) + / (m_count - 1); + return sqrt(variance); } -void Histogram::print(ostream& out) const +void +Histogram::print(ostream& out) const { - printWithMultiplier(out, 1.0); + printWithMultiplier(out, 1.0); } -void Histogram::printPercent(ostream& out) const +void +Histogram::printPercent(ostream& out) const { - if (m_count == 0) { - printWithMultiplier(out, 0.0); - } else { - printWithMultiplier(out, 100.0/double(m_count)); - } + if (m_count == 0) { + printWithMultiplier(out, 0.0); + } else { + printWithMultiplier(out, 100.0 / double(m_count)); + } } -void Histogram::printWithMultiplier(ostream& out, double multiplier) const +void +Histogram::printWithMultiplier(ostream& out, double multiplier) const { - if (m_binsize == -1) { - out << "[binsize: log2 "; - } else { - out << "[binsize: " << m_binsize << " "; - } - out << "max: " << m_max << " "; - out << "count: " << m_count << " "; - // out << "total: " << m_sumSamples << " "; - if (m_count == 0) { - out << "average: NaN |"; - out << "standard deviation: NaN |"; - } else { - out << "average: " << setw(5) << ((double) m_sumSamples)/m_count << " | "; - out << "standard deviation: " << getStandardDeviation() << " |"; - } - for (int i = 0; i < m_bins && i <= m_largest_bin; i++) { - if (multiplier == 1.0) { - out << " " << m_data[i]; + if (m_binsize == -1) { + out << "[binsize: log2 "; + } else { + out << "[binsize: " << m_binsize << " "; + } + out << "max: " << m_max << " "; + out << "count: " << m_count << " "; + // out << "total: " << m_sumSamples << " "; + if (m_count == 0) { + out << "average: NaN |"; + out << "standard deviation: NaN |"; } else { - out << " " << double(m_data[i]) * multiplier; + out << "average: " << setw(5) << ((double) m_sumSamples)/m_count + << " | "; + out << "standard deviation: " << getStandardDeviation() << " |"; + } + for (int i = 0; i < m_bins && i <= m_largest_bin; i++) { + if (multiplier == 1.0) { + out << " " << m_data[i]; + } else { + out << " " << double(m_data[i]) * multiplier; + } } - } - out << " ]"; + out << " ]"; } -bool node_less_then_eq(const Histogram* n1, const Histogram* n2) +bool +node_less_then_eq(const Histogram* n1, const Histogram* n2) { - return (n1->size() > n2->size()); + return (n1->size() > n2->size()); } diff --git a/src/mem/ruby/common/Histogram.hh b/src/mem/ruby/common/Histogram.hh index 64247d64a..e5cd211d6 100644 --- a/src/mem/ruby/common/Histogram.hh +++ b/src/mem/ruby/common/Histogram.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,80 +26,57 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - * - * Description: The histogram class implements a simple histogram - * - */ - -#ifndef HISTOGRAM_H -#define HISTOGRAM_H +#ifndef __MEM_RUBY_COMMON_HISTOGRAM_HH__ +#define __MEM_RUBY_COMMON_HISTOGRAM_HH__ #include <iostream> #include "mem/ruby/common/Global.hh" #include "mem/gems_common/Vector.hh" -class Histogram { -public: - // Constructors - Histogram(int binsize = 1, int bins = 50); - - // Destructor - ~Histogram(); - - // Public Methods - - void add(int64 value); - void add(const Histogram& hist); - void clear() { clear(m_bins); } - void clear(int bins); - void clear(int binsize, int bins); - int64 size() const { return m_count; } - int getBins() const { return m_bins; } - int getBinSize() const { return m_binsize; } - int64 getTotal() const { return m_sumSamples; } - int64 getData(int index) const { return m_data[index]; } +class Histogram +{ + public: + Histogram(int binsize = 1, int bins = 50); + ~Histogram(); + + void add(int64 value); + void add(const Histogram& hist); + void clear() { clear(m_bins); } + void clear(int bins); + void clear(int binsize, int bins); + int64 size() const { return m_count; } + int getBins() const { return m_bins; } + int getBinSize() const { return m_binsize; } + int64 getTotal() const { return m_sumSamples; } + int64 getData(int index) const { return m_data[index]; } + + void printWithMultiplier(std::ostream& out, double multiplier) const; + void printPercent(std::ostream& out) const; + void print(std::ostream& out) const; - void printWithMultiplier(std::ostream& out, double multiplier) const; - void printPercent(std::ostream& out) const; - void print(std::ostream& out) const; private: - // Private Methods - - // Private copy constructor and assignment operator - // Histogram(const Histogram& obj); - // Histogram& operator=(const Histogram& obj); + Vector<int64> m_data; + int64 m_max; // the maximum value seen so far + int64 m_count; // the number of elements added + int m_binsize; // the size of each bucket + int m_bins; // the number of buckets + int m_largest_bin; // the largest bin used - // Data Members (m_ prefix) - Vector<int64> m_data; - int64 m_max; // the maximum value seen so far - int64 m_count; // the number of elements added - int m_binsize; // the size of each bucket - int m_bins; // the number of buckets - int m_largest_bin; // the largest bin used + int64 m_sumSamples; // the sum of all samples + int64 m_sumSquaredSamples; // the sum of the square of all samples - int64 m_sumSamples; // the sum of all samples - int64 m_sumSquaredSamples; // the sum of the square of all samples - - double getStandardDeviation() const; + double getStandardDeviation() const; }; bool node_less_then_eq(const Histogram* n1, const Histogram* n2); -// Output operator declaration -std::ostream& operator<<(std::ostream& out, const Histogram& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -std::ostream& operator<<(std::ostream& out, const Histogram& obj) +inline std::ostream& +operator<<(std::ostream& out, const Histogram& obj) { - obj.print(out); - out << std::flush; - return out; + obj.print(out); + out << std::flush; + return out; } -#endif //HISTOGRAM_H +#endif // __MEM_RUBY_COMMON_HISTOGRAM_HH__ diff --git a/src/mem/ruby/common/Message.cc b/src/mem/ruby/common/Message.cc deleted file mode 100644 index bf3307687..000000000 --- a/src/mem/ruby/common/Message.cc +++ /dev/null @@ -1,34 +0,0 @@ - -/* - * Copyright (c) 1999-2008 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$ - */ - -#include "mem/ruby/slicc_interface/Message.hh" diff --git a/src/mem/ruby/common/NetDest.cc b/src/mem/ruby/common/NetDest.cc index 35bb4ec43..1edf6d1a6 100644 --- a/src/mem/ruby/common/NetDest.cc +++ b/src/mem/ruby/common/NetDest.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,15 +26,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * NetDest.C - * - * Description: See NetDest.hh - * - * $Id$ - * - */ - #include "mem/ruby/common/NetDest.hh" #include "mem/protocol/Protocol.hh" @@ -44,216 +34,242 @@ NetDest::NetDest() setSize(); } -void NetDest::add(MachineID newElement) +void +NetDest::add(MachineID newElement) { - m_bits[vecIndex(newElement)].add(bitIndex(newElement.num)); + m_bits[vecIndex(newElement)].add(bitIndex(newElement.num)); } -void NetDest::addNetDest(const NetDest& netDest) +void +NetDest::addNetDest(const NetDest& netDest) { - assert(m_bits.size() == netDest.getSize()); - for (int i = 0; i < m_bits.size(); i++) { - m_bits[i].addSet(netDest.m_bits[i]); - } + assert(m_bits.size() == netDest.getSize()); + for (int i = 0; i < m_bits.size(); i++) { + m_bits[i].addSet(netDest.m_bits[i]); + } } -void NetDest::addRandom() +void +NetDest::addRandom() { - int i = random()%m_bits.size(); - m_bits[i].addRandom(); + int i = random()%m_bits.size(); + m_bits[i].addRandom(); } -void NetDest::setNetDest(MachineType machine, const Set& set) +void +NetDest::setNetDest(MachineType machine, const Set& set) { - // assure that there is only one set of destinations for this machine - assert(MachineType_base_level((MachineType)(machine+1)) - MachineType_base_level(machine) == 1); - m_bits[MachineType_base_level(machine)] = set; + // assure that there is only one set of destinations for this machine + assert(MachineType_base_level((MachineType)(machine + 1)) - + MachineType_base_level(machine) == 1); + m_bits[MachineType_base_level(machine)] = set; } -void NetDest::remove(MachineID oldElement) +void +NetDest::remove(MachineID oldElement) { - m_bits[vecIndex(oldElement)].remove(bitIndex(oldElement.num)); + m_bits[vecIndex(oldElement)].remove(bitIndex(oldElement.num)); } -void NetDest::removeNetDest(const NetDest& netDest) +void +NetDest::removeNetDest(const NetDest& netDest) { - assert(m_bits.size() == netDest.getSize()); - for (int i = 0; i < m_bits.size(); i++) { - m_bits[i].removeSet(netDest.m_bits[i]); - - } + assert(m_bits.size() == netDest.getSize()); + for (int i = 0; i < m_bits.size(); i++) { + m_bits[i].removeSet(netDest.m_bits[i]); + } } -void NetDest::clear() +void +NetDest::clear() { - for (int i = 0; i < m_bits.size(); i++) { - m_bits[i].clear(); - } + for (int i = 0; i < m_bits.size(); i++) { + m_bits[i].clear(); + } } -void NetDest::broadcast() +void +NetDest::broadcast() { - for (MachineType machine = MachineType_FIRST; machine < MachineType_NUM; ++machine) { - broadcast(machine); - } + for (MachineType machine = MachineType_FIRST; + machine < MachineType_NUM; ++machine) { + broadcast(machine); + } } -void NetDest::broadcast(MachineType machineType) { - - for (int i = 0; i < MachineType_base_count(machineType); i++) { - MachineID mach = {machineType, i}; - add(mach); - } +void +NetDest::broadcast(MachineType machineType) +{ + for (int i = 0; i < MachineType_base_count(machineType); i++) { + MachineID mach = {machineType, i}; + add(mach); + } } //For Princeton Network -Vector<NodeID> NetDest::getAllDest() { - Vector<NodeID> dest; - dest.clear(); - for (int i=0; i<m_bits.size(); i++) { - for (int j=0; j<m_bits[i].getSize(); j++) { - if (m_bits[i].isElement(j)) { - dest.insertAtBottom((NodeID) (MachineType_base_number((MachineType) i) + j)); - } - } +Vector<NodeID> +NetDest::getAllDest() +{ + Vector<NodeID> dest; + dest.clear(); + for (int i = 0; i < m_bits.size(); i++) { + for (int j = 0; j < m_bits[i].getSize(); j++) { + if (m_bits[i].isElement(j)) { + int id = MachineType_base_number((MachineType)i) + j; + dest.insertAtBottom((NodeID)id); + } } - return dest; + } + return dest; } -int NetDest::count() const +int +NetDest::count() const { - int counter = 0; - for (int i=0; i<m_bits.size(); i++) { - counter += m_bits[i].count(); - } - return counter; + int counter = 0; + for (int i = 0; i < m_bits.size(); i++) { + counter += m_bits[i].count(); + } + return counter; } -NodeID NetDest::elementAt(MachineID index) { - return m_bits[vecIndex(index)].elementAt(bitIndex(index.num)); +NodeID +NetDest::elementAt(MachineID index) +{ + return m_bits[vecIndex(index)].elementAt(bitIndex(index.num)); } -MachineID NetDest::smallestElement() const +MachineID +NetDest::smallestElement() const { - assert(count() > 0); - for (int i=0; i<m_bits.size(); i++) { - for (int j=0; j<m_bits[i].getSize(); j++) { - if (m_bits[i].isElement(j)) { - MachineID mach = {MachineType_from_base_level(i), j}; - return mach; - } + assert(count() > 0); + for (int i = 0; i < m_bits.size(); i++) { + for (int j = 0; j < m_bits[i].getSize(); j++) { + if (m_bits[i].isElement(j)) { + MachineID mach = {MachineType_from_base_level(i), j}; + return mach; + } + } } - } - ERROR_MSG("No smallest element of an empty set."); + ERROR_MSG("No smallest element of an empty set."); } -MachineID NetDest::smallestElement(MachineType machine) const +MachineID +NetDest::smallestElement(MachineType machine) const { - for (int j = 0; j < m_bits[MachineType_base_level(machine)].getSize(); j++) { - if (m_bits[MachineType_base_level(machine)].isElement(j)) { - MachineID mach = {machine, j}; - return mach; + int size = m_bits[MachineType_base_level(machine)].getSize(); + for (int j = 0; j < size; j++) { + if (m_bits[MachineType_base_level(machine)].isElement(j)) { + MachineID mach = {machine, j}; + return mach; + } } - } - ERROR_MSG("No smallest element of given MachineType."); + ERROR_MSG("No smallest element of given MachineType."); } - // Returns true iff all bits are set -bool NetDest::isBroadcast() const +bool +NetDest::isBroadcast() const { - for (int i=0; i<m_bits.size(); i++) { - if (!m_bits[i].isBroadcast()) { - return false; + for (int i = 0; i < m_bits.size(); i++) { + if (!m_bits[i].isBroadcast()) { + return false; + } } - } - return true; + return true; } // Returns true iff no bits are set -bool NetDest::isEmpty() const +bool +NetDest::isEmpty() const { - for (int i=0; i<m_bits.size(); i++) { - if (!m_bits[i].isEmpty()) { - return false; + for (int i = 0; i < m_bits.size(); i++) { + if (!m_bits[i].isEmpty()) { + return false; + } } - } - return true; + return true; } // returns the logical OR of "this" set and orNetDest -NetDest NetDest::OR(const NetDest& orNetDest) const +NetDest +NetDest::OR(const NetDest& orNetDest) const { - assert(m_bits.size() == orNetDest.getSize()); - NetDest result; - for (int i=0; i<m_bits.size(); i++) { - result.m_bits[i] = m_bits[i].OR(orNetDest.m_bits[i]); - } - return result; + assert(m_bits.size() == orNetDest.getSize()); + NetDest result; + for (int i = 0; i < m_bits.size(); i++) { + result.m_bits[i] = m_bits[i].OR(orNetDest.m_bits[i]); + } + return result; } - // returns the logical AND of "this" set and andNetDest -NetDest NetDest::AND(const NetDest& andNetDest) const +NetDest +NetDest::AND(const NetDest& andNetDest) const { - assert(m_bits.size() == andNetDest.getSize()); - NetDest result; - for (int i=0; i<m_bits.size(); i++) { - result.m_bits[i] = m_bits[i].AND(andNetDest.m_bits[i]); - } - return result; + assert(m_bits.size() == andNetDest.getSize()); + NetDest result; + for (int i = 0; i < m_bits.size(); i++) { + result.m_bits[i] = m_bits[i].AND(andNetDest.m_bits[i]); + } + return result; } // Returns true if the intersection of the two sets is non-empty -bool NetDest::intersectionIsNotEmpty(const NetDest& other_netDest) const +bool +NetDest::intersectionIsNotEmpty(const NetDest& other_netDest) const { - assert(m_bits.size() == other_netDest.getSize()); - for (int i=0; i<m_bits.size(); i++) { - if (m_bits[i].intersectionIsNotEmpty(other_netDest.m_bits[i])) { - return true; + assert(m_bits.size() == other_netDest.getSize()); + for (int i = 0; i < m_bits.size(); i++) { + if (m_bits[i].intersectionIsNotEmpty(other_netDest.m_bits[i])) { + return true; + } } - } - return false; + return false; } -bool NetDest::isSuperset(const NetDest& test) const +bool +NetDest::isSuperset(const NetDest& test) const { - assert(m_bits.size() == test.getSize()); + assert(m_bits.size() == test.getSize()); - for (int i=0; i<m_bits.size(); i++) { - if (!m_bits[i].isSuperset(test.m_bits[i])) { - return false; + for (int i = 0; i < m_bits.size(); i++) { + if (!m_bits[i].isSuperset(test.m_bits[i])) { + return false; + } } - } - return true; + return true; } -bool NetDest::isElement(MachineID element) const +bool +NetDest::isElement(MachineID element) const { - return ((m_bits[vecIndex(element)])).isElement(bitIndex(element.num)); + return ((m_bits[vecIndex(element)])).isElement(bitIndex(element.num)); } -void NetDest::setSize() +void +NetDest::setSize() { - m_bits.setSize(MachineType_base_level(MachineType_NUM)); - assert(m_bits.size() == MachineType_NUM); + m_bits.setSize(MachineType_base_level(MachineType_NUM)); + assert(m_bits.size() == MachineType_NUM); - for (int i = 0; i < m_bits.size(); i++) { - m_bits[i].setSize(MachineType_base_count((MachineType)i)); - } + for (int i = 0; i < m_bits.size(); i++) { + m_bits[i].setSize(MachineType_base_count((MachineType)i)); + } } -void NetDest::print(ostream& out) const +void +NetDest::print(ostream& out) const { - out << "[NetDest (" << m_bits.size() << ") "; + out << "[NetDest (" << m_bits.size() << ") "; - for (int i=0; i<m_bits.size(); i++) { - for (int j=0; j<m_bits[i].getSize(); j++) { - out << (bool) m_bits[i].isElement(j) << " "; + for (int i = 0; i < m_bits.size(); i++) { + for (int j = 0; j < m_bits[i].getSize(); j++) { + out << (bool) m_bits[i].isElement(j) << " "; + } + out << " - "; } - out << " - "; - } - out << "]"; + out << "]"; } diff --git a/src/mem/ruby/common/NetDest.hh b/src/mem/ruby/common/NetDest.hh index 071106623..7592ad9b5 100644 --- a/src/mem/ruby/common/NetDest.hh +++ b/src/mem/ruby/common/NetDest.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,22 +26,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * Set.hh - * - * Description: - * - * $Id$ - * - */ - // NetDest specifies the network destination of a NetworkMessage // This is backward compatible with the Set class that was previously // used to specify network destinations. // NetDest supports both node networks and component networks -#ifndef NETDEST_H -#define NETDEST_H +#ifndef __MEM_RUBY_COMMON_NETDEST_HH__ +#define __MEM_RUBY_COMMON_NETDEST_HH__ #include "mem/ruby/common/Global.hh" #include "mem/gems_common/Vector.hh" @@ -51,94 +41,92 @@ #include "mem/ruby/common/Set.hh" #include "mem/protocol/MachineType.hh" -class Set; - -class NetDest { -public: - // Constructors - // creates and empty set - NetDest(); - explicit NetDest(int bit_size); - - NetDest& operator=(const Set& obj); - - // Destructor - ~NetDest() { DEBUG_MSG(MEMORY_COMP, LowPrio, "NetDest Destructor"); } - - // Public Methods - void add(MachineID newElement); - void addNetDest(const NetDest& netDest); - void addRandom(); - void setNetDest(MachineType machine, const Set& set); - void remove(MachineID oldElement); - void removeNetDest(const NetDest& netDest); - void clear(); - void broadcast(); - void broadcast(MachineType machine); - int count() const; - bool isEqual(const NetDest& netDest); - - NetDest OR(const NetDest& orNetDest) const; // return the logical OR of this netDest and orNetDest - NetDest AND(const NetDest& andNetDest) const; // return the logical AND of this netDest and andNetDest - - // Returns true if the intersection of the two netDests is non-empty - bool intersectionIsNotEmpty(const NetDest& other_netDest) const; - - // Returns true if the intersection of the two netDests is empty - bool intersectionIsEmpty(const NetDest& other_netDest) const; - - bool isSuperset(const NetDest& test) const; - bool isSubset(const NetDest& test) const { return test.isSuperset(*this); } - bool isElement(MachineID element) const; - bool isBroadcast() const; - bool isEmpty() const; - - //For Princeton Network - Vector<NodeID> getAllDest(); - - MachineID smallestElement() const; - MachineID smallestElement(MachineType machine) const; - - void setSize(); - int getSize() const { return m_bits.size(); } - - // get element for a index - NodeID elementAt(MachineID index); - - void print(ostream& out) const; - -private: - - // Private Methods - // returns a value >= MachineType_base_level("this machine") and < MachineType_base_level("next highest machine") - int vecIndex(MachineID m) const { - int vec_index = MachineType_base_level(m.type); - assert(vec_index < m_bits.size()); - return vec_index; - } - - NodeID bitIndex(NodeID index) const { - return index; - } - - // Data Members (m_ prefix) - Vector < Set > m_bits; // a Vector of bit vectors - i.e. Sets - +class NetDest +{ + public: + // Constructors + // creates and empty set + NetDest(); + explicit NetDest(int bit_size); + + NetDest& operator=(const Set& obj); + + ~NetDest() + { + DEBUG_MSG(MEMORY_COMP, LowPrio, "NetDest Destructor"); + } + + void add(MachineID newElement); + void addNetDest(const NetDest& netDest); + void addRandom(); + void setNetDest(MachineType machine, const Set& set); + void remove(MachineID oldElement); + void removeNetDest(const NetDest& netDest); + void clear(); + void broadcast(); + void broadcast(MachineType machine); + int count() const; + bool isEqual(const NetDest& netDest); + + // return the logical OR of this netDest and orNetDest + NetDest OR(const NetDest& orNetDest) const; + + // return the logical AND of this netDest and andNetDest + NetDest AND(const NetDest& andNetDest) const; + + // Returns true if the intersection of the two netDests is non-empty + bool intersectionIsNotEmpty(const NetDest& other_netDest) const; + + // Returns true if the intersection of the two netDests is empty + bool intersectionIsEmpty(const NetDest& other_netDest) const; + + bool isSuperset(const NetDest& test) const; + bool isSubset(const NetDest& test) const { return test.isSuperset(*this); } + bool isElement(MachineID element) const; + bool isBroadcast() const; + bool isEmpty() const; + + // For Princeton Network + Vector<NodeID> getAllDest(); + + MachineID smallestElement() const; + MachineID smallestElement(MachineType machine) const; + + void setSize(); + int getSize() const { return m_bits.size(); } + + // get element for a index + NodeID elementAt(MachineID index); + + void print(ostream& out) const; + + private: + // returns a value >= MachineType_base_level("this machine") + // and < MachineType_base_level("next highest machine") + int + vecIndex(MachineID m) const + { + int vec_index = MachineType_base_level(m.type); + assert(vec_index < m_bits.size()); + return vec_index; + } + + NodeID + bitIndex(NodeID index) const + { + return index; + } + + Vector <Set> m_bits; // a Vector of bit vectors - i.e. Sets }; -// Output operator declaration -ostream& operator<<(ostream& out, const NetDest& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const NetDest& obj) +inline ostream& +operator<<(ostream& out, const NetDest& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -#endif //NETDEST_H +#endif // __MEM_RUBY_COMMON_NETDEST_HH__ diff --git a/src/mem/ruby/common/SConscript b/src/mem/ruby/common/SConscript index 56f5d7556..2197faae8 100644 --- a/src/mem/ruby/common/SConscript +++ b/src/mem/ruby/common/SConscript @@ -41,7 +41,6 @@ Source('Debug.cc') Source('Driver.cc') Source('Global.cc') Source('Histogram.cc') -Source('Message.cc') Source('NetDest.cc') Source('Set.cc', Werror=False) Source('SubBlock.cc') diff --git a/src/mem/ruby/common/SubBlock.cc b/src/mem/ruby/common/SubBlock.cc index de40e3f7d..533aefbe7 100644 --- a/src/mem/ruby/common/SubBlock.cc +++ b/src/mem/ruby/common/SubBlock.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,44 +26,44 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - */ - #include "mem/ruby/common/SubBlock.hh" SubBlock::SubBlock(const Address& addr, int size) { - m_address = addr; - setSize(size); - for(int i=0; i<size; i++) { - setByte(i, 0); - } + m_address = addr; + setSize(size); + for (int i = 0; i < size; i++) { + setByte(i, 0); + } } -void SubBlock::internalMergeFrom(const DataBlock& data) +void +SubBlock::internalMergeFrom(const DataBlock& data) { - int size = getSize(); - assert(size > 0); - int offset = m_address.getOffset(); - for(int i=0; i<size; i++) { - this->setByte(i, data.getByte(offset+i)); - } + int size = getSize(); + assert(size > 0); + int offset = m_address.getOffset(); + for (int i = 0; i < size; i++) { + this->setByte(i, data.getByte(offset + i)); + } } -void SubBlock::internalMergeTo(DataBlock& data) const +void +SubBlock::internalMergeTo(DataBlock& data) const { - int size = getSize(); - assert(size > 0); - int offset = m_address.getOffset(); - for(int i=0; i<size; i++) { - data.setByte(offset+i, this->getByte(i)); // This will detect crossing a cache line boundary - } + int size = getSize(); + assert(size > 0); + int offset = m_address.getOffset(); + for (int i = 0; i < size; i++) { + // This will detect crossing a cache line boundary + data.setByte(offset + i, this->getByte(i)); + } } -void SubBlock::print(ostream& out) const +void +SubBlock::print(ostream& out) const { - out << "[" << m_address << ", " << getSize() << ", " << m_data << "]"; + out << "[" << m_address << ", " << getSize() << ", " << m_data << "]"; } diff --git a/src/mem/ruby/common/SubBlock.hh b/src/mem/ruby/common/SubBlock.hh index 8acdd9f4d..ab286dd0e 100644 --- a/src/mem/ruby/common/SubBlock.hh +++ b/src/mem/ruby/common/SubBlock.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,69 +26,55 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - * - */ +#ifndef __MEM_RUBY_COMMON_SUBBLOCK_HH__ +#define __MEM_RUBY_COMMON_SUBBLOCK_HH__ -#ifndef SubBlock_H -#define SubBlock_H - -#include "mem/ruby/common/Global.hh" +#include "mem/gems_common/Vector.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/DataBlock.hh" -#include "mem/gems_common/Vector.hh" - -class SubBlock { -public: - // Constructors - SubBlock() { } - SubBlock(const Address& addr, int size); +#include "mem/ruby/common/Global.hh" - // Destructor - ~SubBlock() { } +class SubBlock +{ + public: + SubBlock() { } + SubBlock(const Address& addr, int size); + ~SubBlock() { } - // Public Methods - const Address& getAddress() const { return m_address; } - void setAddress(const Address& addr) { m_address = addr; } + const Address& getAddress() const { return m_address; } + void setAddress(const Address& addr) { m_address = addr; } - int getSize() const { return m_data.size(); } - void setSize(int size) { m_data.setSize(size); } - uint8 getByte(int offset) const { return m_data[offset]; } - void setByte(int offset, uint8 data) { m_data[offset] = data; } + int getSize() const { return m_data.size(); } + void setSize(int size) { m_data.setSize(size); } + uint8 getByte(int offset) const { return m_data[offset]; } + void setByte(int offset, uint8 data) { m_data[offset] = data; } - // Shorthands - uint8 readByte() const { return getByte(0); } - void writeByte(uint8 data) { setByte(0, data); } + // Shorthands + uint8 readByte() const { return getByte(0); } + void writeByte(uint8 data) { setByte(0, data); } - // Merging to and from DataBlocks - We only need to worry about - // updates when we are using DataBlocks - void mergeTo(DataBlock& data) const { internalMergeTo(data); } - void mergeFrom(const DataBlock& data) { internalMergeFrom(data); } + // Merging to and from DataBlocks - We only need to worry about + // updates when we are using DataBlocks + void mergeTo(DataBlock& data) const { internalMergeTo(data); } + void mergeFrom(const DataBlock& data) { internalMergeFrom(data); } - void print(ostream& out) const; -private: + void print(ostream& out) const; - void internalMergeTo(DataBlock& data) const; - void internalMergeFrom(const DataBlock& data); + private: + void internalMergeTo(DataBlock& data) const; + void internalMergeFrom(const DataBlock& data); - // Data Members (m_ prefix) - Address m_address; - Vector<uint8_t> m_data; + // Data Members (m_ prefix) + Address m_address; + Vector<uint8_t> m_data; }; -// Output operator declaration -ostream& operator<<(ostream& out, const SubBlock& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const SubBlock& obj) +inline ostream& +operator<<(ostream& out, const SubBlock& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -#endif //SubBlock_H +#endif // __MEM_RUBY_COMMON_SUBBLOCK_HH__ diff --git a/src/mem/ruby/eventqueue/RubyEventQueue.cc b/src/mem/ruby/eventqueue/RubyEventQueue.cc index 3cfb52ff1..eaa22ff1e 100644 --- a/src/mem/ruby/eventqueue/RubyEventQueue.cc +++ b/src/mem/ruby/eventqueue/RubyEventQueue.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,16 +26,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - */ - -#include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/ruby/common/Consumer.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/ruby/eventqueue/RubyEventQueueNode.hh" - -// Class public method definitions +#include "mem/ruby/system/System.hh" RubyEventQueue::RubyEventQueue(EventQueue* eventq, Tick _clock) : EventManager(eventq), m_clock(_clock) @@ -47,28 +40,28 @@ RubyEventQueue::~RubyEventQueue() { } -void RubyEventQueue::scheduleEvent(Consumer* consumer, Time timeDelta) -{ - scheduleEventAbsolute(consumer, timeDelta + getTime()); +void +RubyEventQueue::scheduleEvent(Consumer* consumer, Time timeDelta) +{ + scheduleEventAbsolute(consumer, timeDelta + getTime()); } -void RubyEventQueue::scheduleEventAbsolute(Consumer* consumer, Time timeAbs) +void +RubyEventQueue::scheduleEventAbsolute(Consumer* consumer, Time timeAbs) { - // Check to see if this is a redundant wakeup - ASSERT(consumer != NULL); - if (!consumer->alreadyScheduled(timeAbs)) { - // This wakeup is not redundant - RubyEventQueueNode *thisNode = new RubyEventQueueNode(consumer, this); - assert(timeAbs > getTime()); - schedule(thisNode, (timeAbs * m_clock)); - consumer->insertScheduledWakeupTime(timeAbs); - } + // Check to see if this is a redundant wakeup + ASSERT(consumer != NULL); + if (!consumer->alreadyScheduled(timeAbs)) { + // This wakeup is not redundant + RubyEventQueueNode *thisNode = new RubyEventQueueNode(consumer, this); + assert(timeAbs > getTime()); + schedule(thisNode, (timeAbs * m_clock)); + consumer->insertScheduledWakeupTime(timeAbs); + } } -// Class private method definitions - void RubyEventQueue::print(ostream& out) const { - out << "[Event Queue:]"; + out << "[Event Queue:]"; } diff --git a/src/mem/ruby/eventqueue/RubyEventQueue.hh b/src/mem/ruby/eventqueue/RubyEventQueue.hh index 468b21edb..d2ebc42c2 100644 --- a/src/mem/ruby/eventqueue/RubyEventQueue.hh +++ b/src/mem/ruby/eventqueue/RubyEventQueue.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -28,9 +27,7 @@ */ /* - * $Id$ - * - * Description: The RubyEventQueue class implements an event queue which + * The RubyEventQueue class implements an event queue which * can be trigger events, allowing our simulation to be event driven. * * Currently, the only event we support is a Consumer being signaled @@ -56,8 +53,8 @@ * */ -#ifndef RUBYEVENTQUEUE_H -#define RUBYEVENTQUEUE_H +#ifndef __MEM_RUBY_EVENTQUEUE_RUBYEVENTQUEUE_HH__ +#define __MEM_RUBY_EVENTQUEUE_RUBYEVENTQUEUE_HH__ #include <iostream> @@ -70,48 +67,36 @@ class Consumer; template <class TYPE> class PrioHeap; class RubyEventQueueNode; -class RubyEventQueue : public EventManager { -public: - // Constructors - RubyEventQueue(EventQueue* eventq, Tick _clock); - - // Destructor - ~RubyEventQueue(); - - // Public Methods - - Time getTime() const { return curTick/m_clock; } - Tick getClock() const { return m_clock; } - void scheduleEvent(Consumer* consumer, Time timeDelta); - void scheduleEventAbsolute(Consumer* consumer, Time timeAbs); - void print(std::ostream& out) const; - - void triggerEvents(Time t) { assert(0); } - void triggerAllEvents() { assert(0); } - - // Private Methods -private: - // Private copy constructor and assignment operator - RubyEventQueue(const RubyEventQueue& obj); - RubyEventQueue& operator=(const RubyEventQueue& obj); - - // Data Members (m_ prefix) - Tick m_clock; +class RubyEventQueue : public EventManager +{ + public: + RubyEventQueue(EventQueue* eventq, Tick _clock); + ~RubyEventQueue(); + + Time getTime() const { return curTick/m_clock; } + Tick getClock() const { return m_clock; } + void scheduleEvent(Consumer* consumer, Time timeDelta); + void scheduleEventAbsolute(Consumer* consumer, Time timeAbs); + void print(std::ostream& out) const; + + void triggerEvents(Time t) { assert(0); } + void triggerAllEvents() { assert(0); } + + private: + // Private copy constructor and assignment operator + RubyEventQueue(const RubyEventQueue& obj); + RubyEventQueue& operator=(const RubyEventQueue& obj); + + // Data Members (m_ prefix) + Tick m_clock; }; -// Output operator declaration -inline extern -std::ostream& operator<<(std::ostream& out, const RubyEventQueue& obj); - -// ******************* Definitions ******************* - -// Output operator definition -inline extern -std::ostream& operator<<(std::ostream& out, const RubyEventQueue& obj) +inline std::ostream& +operator<<(std::ostream& out, const RubyEventQueue& obj) { - obj.print(out); - out << std::flush; - return out; + obj.print(out); + out << std::flush; + return out; } -#endif //EVENTQUEUE_H +#endif // __MEM_RUBY_EVENTQUEUE_RUBYEVENTQUEUE_HH__ diff --git a/src/mem/ruby/eventqueue/RubyEventQueueNode.cc b/src/mem/ruby/eventqueue/RubyEventQueueNode.cc index 31aa2088a..c15452dd9 100644 --- a/src/mem/ruby/eventqueue/RubyEventQueueNode.cc +++ b/src/mem/ruby/eventqueue/RubyEventQueueNode.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,20 +26,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - * - */ - #include "mem/ruby/eventqueue/RubyEventQueueNode.hh" -void RubyEventQueueNode::print(std::ostream& out) const +void +RubyEventQueueNode::print(std::ostream& out) const { - out << "["; - if (m_consumer_ptr != NULL) { - out << " Consumer=" << m_consumer_ptr; - } else { - out << " Consumer=NULL"; - } - out << "]"; + out << "["; + if (m_consumer_ptr != NULL) { + out << " Consumer=" << m_consumer_ptr; + } else { + out << " Consumer=NULL"; + } + out << "]"; } diff --git a/src/mem/ruby/eventqueue/RubyEventQueueNode.hh b/src/mem/ruby/eventqueue/RubyEventQueueNode.hh index 46d8b317c..c759e7f57 100644 --- a/src/mem/ruby/eventqueue/RubyEventQueueNode.hh +++ b/src/mem/ruby/eventqueue/RubyEventQueueNode.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,65 +26,44 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - * - */ - -#ifndef RUBYEVENTQUEUENODE_H -#define RUBYEVENTQUEUENODE_H +#ifndef __MEM_RUBY_EVENTQUEUE_RUBYEVENTQUEUENODE_HH__ +#define __MEM_RUBY_EVENTQUEUE_RUBYEVENTQUEUENODE_HH__ #include <iostream> +#include "mem/ruby/common/Consumer.hh" #include "mem/ruby/common/Global.hh" #include "sim/eventq.hh" -#include "mem/ruby/common/Consumer.hh" -//class Consumer; -class RubyEventQueueNode : public Event { -public: - // Constructors - RubyEventQueueNode(Consumer* _consumer, RubyEventQueue* _eventq) - : m_consumer_ptr(_consumer), m_eventq_ptr(_eventq) - { - setFlags(AutoDelete); - } - - // Destructor - //~RubyEventQueueNode(); - - // Public Methods - void print(std::ostream& out) const; - virtual void process() - { - m_consumer_ptr->wakeup(); - m_consumer_ptr->removeScheduledWakeupTime(m_eventq_ptr->getTime()); - } - virtual const char *description() const { return "Ruby Event"; } - -private: - // Private Methods +class RubyEventQueueNode : public Event +{ + public: + RubyEventQueueNode(Consumer* _consumer, RubyEventQueue* _eventq) + : m_consumer_ptr(_consumer), m_eventq_ptr(_eventq) + { + setFlags(AutoDelete); + } - // Default copy constructor and assignment operator - // RubyEventQueueNode(const RubyEventQueueNode& obj); + void print(std::ostream& out) const; + virtual void + process() + { + m_consumer_ptr->wakeup(); + m_consumer_ptr->removeScheduledWakeupTime(m_eventq_ptr->getTime()); + } + virtual const char *description() const { return "Ruby Event"; } - // Data Members (m_ prefix) - Consumer* m_consumer_ptr; - RubyEventQueue* m_eventq_ptr; + private: + Consumer* m_consumer_ptr; + RubyEventQueue* m_eventq_ptr; }; -// Output operator declaration -std::ostream& operator<<(std::ostream& out, const RubyEventQueueNode& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -std::ostream& operator<<(std::ostream& out, const RubyEventQueueNode& obj) +inline std::ostream& +operator<<(std::ostream& out, const RubyEventQueueNode& obj) { - obj.print(out); - out << std::flush; - return out; + obj.print(out); + out << std::flush; + return out; } -#endif //EVENTQUEUENODE_H +#endif // __MEM_RUBY_EVENTQUEUE_EVENTQUEUENODE_HH__ diff --git a/src/mem/ruby/filters/AbstractBloomFilter.hh b/src/mem/ruby/filters/AbstractBloomFilter.hh index 89aeb25a6..de11b4499 100644 --- a/src/mem/ruby/filters/AbstractBloomFilter.hh +++ b/src/mem/ruby/filters/AbstractBloomFilter.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,44 +26,32 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * AbstractBloomFilter.hh - * - * Description: - * - * - */ - -#ifndef ABSTRACT_BLOOM_FILTER_H -#define ABSTRACT_BLOOM_FILTER_H +#ifndef __MEM_RUBY_FILTERS_ABSTRACTBLOOMFILTER_HH__ +#define __MEM_RUBY_FILTERS_ABSTRACTBLOOMFILTER_HH__ -#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" -class AbstractBloomFilter { -public: - - virtual ~AbstractBloomFilter() {}; - virtual void clear() = 0; - virtual void increment(const Address& addr) = 0; - virtual void decrement(const Address& addr) = 0; - virtual void merge(AbstractBloomFilter * other_filter) = 0; - virtual void set(const Address& addr) = 0; - virtual void unset(const Address& addr) = 0; - - virtual bool isSet(const Address& addr) = 0; - virtual int getCount(const Address& addr) = 0; - virtual int getTotalCount() = 0; - - virtual void print(ostream& out) const = 0; - - virtual int getIndex(const Address& addr) = 0; - virtual int readBit(const int index) = 0; - virtual void writeBit(const int index, const int value) = 0; - -private: - +class AbstractBloomFilter +{ + public: + virtual ~AbstractBloomFilter() {}; + virtual void clear() = 0; + virtual void increment(const Address& addr) = 0; + virtual void decrement(const Address& addr) = 0; + virtual void merge(AbstractBloomFilter * other_filter) = 0; + virtual void set(const Address& addr) = 0; + virtual void unset(const Address& addr) = 0; + + virtual bool isSet(const Address& addr) = 0; + virtual int getCount(const Address& addr) = 0; + virtual int getTotalCount() = 0; + + virtual void print(ostream& out) const = 0; + + virtual int getIndex(const Address& addr) = 0; + virtual int readBit(const int index) = 0; + virtual void writeBit(const int index, const int value) = 0; }; - -#endif +#endif // __MEM_RUBY_FILTERS_ABSTRACTBLOOMFILTER_HH__ diff --git a/src/mem/ruby/filters/BlockBloomFilter.cc b/src/mem/ruby/filters/BlockBloomFilter.cc index 9bf5b41c5..74b14593e 100644 --- a/src/mem/ruby/filters/BlockBloomFilter.cc +++ b/src/mem/ruby/filters/BlockBloomFilter.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,121 +26,133 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * BlockBloomFilter.cc - * - * Description: - * - * - */ - -#include "mem/ruby/filters/BlockBloomFilter.hh" #include "mem/gems_common/Map.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/filters/BlockBloomFilter.hh" BlockBloomFilter::BlockBloomFilter(string str) { - string tail(str); - string head = string_split(tail, '_'); + string tail(str); + string head = string_split(tail, '_'); - m_filter_size = atoi(head.c_str()); - m_filter_size_bits = log_int(m_filter_size); + m_filter_size = atoi(head.c_str()); + m_filter_size_bits = log_int(m_filter_size); - m_filter.setSize(m_filter_size); + m_filter.setSize(m_filter_size); - clear(); + clear(); } -BlockBloomFilter::~BlockBloomFilter(){ +BlockBloomFilter::~BlockBloomFilter() +{ } -void BlockBloomFilter::clear() +void +BlockBloomFilter::clear() { - for (int i = 0; i < m_filter_size; i++) { - m_filter[i] = 0; - } + for (int i = 0; i < m_filter_size; i++) { + m_filter[i] = 0; + } } -void BlockBloomFilter::increment(const Address& addr) +void +BlockBloomFilter::increment(const Address& addr) { - // Not used + // Not used } - -void BlockBloomFilter::decrement(const Address& addr) +void +BlockBloomFilter::decrement(const Address& addr) { - // Not used + // Not used } -void BlockBloomFilter::merge(AbstractBloomFilter * other_filter) +void +BlockBloomFilter::merge(AbstractBloomFilter * other_filter) { - // TODO + // TODO } -void BlockBloomFilter::set(const Address& addr) +void +BlockBloomFilter::set(const Address& addr) { - int i = get_index(addr); - m_filter[i] = 1; + int i = get_index(addr); + m_filter[i] = 1; } -void BlockBloomFilter::unset(const Address& addr) +void +BlockBloomFilter::unset(const Address& addr) { - int i = get_index(addr); - m_filter[i] = 0; + int i = get_index(addr); + m_filter[i] = 0; } -bool BlockBloomFilter::isSet(const Address& addr) +bool +BlockBloomFilter::isSet(const Address& addr) { - int i = get_index(addr); - return (m_filter[i]); + int i = get_index(addr); + return (m_filter[i]); } - -int BlockBloomFilter::getCount(const Address& addr) +int +BlockBloomFilter::getCount(const Address& addr) { - return m_filter[get_index(addr)]; + return m_filter[get_index(addr)]; } -int BlockBloomFilter::getTotalCount() +int +BlockBloomFilter::getTotalCount() { - int count = 0; + int count = 0; - for (int i = 0; i < m_filter_size; i++) { - if (m_filter[i]) { - count++; + for (int i = 0; i < m_filter_size; i++) { + if (m_filter[i]) { + count++; + } } - } - return count; + return count; } -int BlockBloomFilter::getIndex(const Address& addr) +int +BlockBloomFilter::getIndex(const Address& addr) { - return get_index(addr); + return get_index(addr); } -void BlockBloomFilter::print(ostream& out) const +void +BlockBloomFilter::print(ostream& out) const { } -int BlockBloomFilter::readBit(const int index) { - return m_filter[index]; +int +BlockBloomFilter::readBit(const int index) +{ + return m_filter[index]; } -void BlockBloomFilter::writeBit(const int index, const int value) { - m_filter[index] = value; +void +BlockBloomFilter::writeBit(const int index, const int value) +{ + m_filter[index] = value; } -int BlockBloomFilter::get_index(const Address& addr) +int +BlockBloomFilter::get_index(const Address& addr) { - // Pull out some bit field ==> B1 - // Pull out additional bits, not the same as B1 ==> B2 - // XOR B1 and B2 to get hash index - physical_address_t block_bits = addr.bitSelect( RubySystem::getBlockSizeBits(), 2*RubySystem::getBlockSizeBits() - 1); - int offset = 5; - physical_address_t other_bits = addr.bitSelect( 2*RubySystem::getBlockSizeBits() + offset, 2*RubySystem::getBlockSizeBits() + offset + m_filter_size_bits - 1); - int index = block_bits ^ other_bits; - assert(index < m_filter_size); - return index; + // Pull out some bit field ==> B1 + // Pull out additional bits, not the same as B1 ==> B2 + // XOR B1 and B2 to get hash index + physical_address_t block_bits = + addr.bitSelect(RubySystem::getBlockSizeBits(), + 2 * RubySystem::getBlockSizeBits() - 1); + int offset = 5; + physical_address_t other_bits = + addr.bitSelect(2 * RubySystem::getBlockSizeBits() + offset, + 2 * RubySystem::getBlockSizeBits() + offset + + m_filter_size_bits - 1); + int index = block_bits ^ other_bits; + assert(index < m_filter_size); + return index; } diff --git a/src/mem/ruby/filters/BlockBloomFilter.hh b/src/mem/ruby/filters/BlockBloomFilter.hh index be9faa443..14f064975 100644 --- a/src/mem/ruby/filters/BlockBloomFilter.hh +++ b/src/mem/ruby/filters/BlockBloomFilter.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,55 +26,45 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * BlockBloomFilter.hh - * - * Description: - * - * - */ - -#ifndef BLOCK_BLOOM_FILTER_H -#define BLOCK_BLOOM_FILTER_H +#ifndef __MEM_RUBY_FILTERS_BLOCKBLOOMFILTER_HH__ +#define __MEM_RUBY_FILTERS_BLOCKBLOOMFILTER_HH__ #include "mem/gems_common/Map.hh" -#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/filters/AbstractBloomFilter.hh" -class BlockBloomFilter : public AbstractBloomFilter { -public: +class BlockBloomFilter : public AbstractBloomFilter +{ + public: + BlockBloomFilter(string config); + ~BlockBloomFilter(); - ~BlockBloomFilter(); - BlockBloomFilter(string config); + void clear(); + void increment(const Address& addr); + void decrement(const Address& addr); + void merge(AbstractBloomFilter * other_filter); + void set(const Address& addr); + void unset(const Address& addr); - void clear(); - void increment(const Address& addr); - void decrement(const Address& addr); - void merge(AbstractBloomFilter * other_filter); - void set(const Address& addr); - void unset(const Address& addr); + bool isSet(const Address& addr); + int getCount(const Address& addr); + int getTotalCount(); + int getIndex(const Address& addr); + int readBit(const int index); + void writeBit(const int index, const int value); - bool isSet(const Address& addr); - int getCount(const Address& addr); - int getTotalCount(); - int getIndex(const Address& addr); - int readBit(const int index); - void writeBit(const int index, const int value); + void print(ostream& out) const; - void print(ostream& out) const; + private: + int get_index(const Address& addr); -private: + Vector<int> m_filter; + int m_filter_size; + int m_filter_size_bits; - int get_index(const Address& addr); - - Vector<int> m_filter; - int m_filter_size; - int m_filter_size_bits; - - int m_count_bits; - int m_count; + int m_count_bits; + int m_count; }; - -#endif +#endif // __MEM_RUBY_FILTERS_BLOCKBLOOMFILTER_HH__ diff --git a/src/mem/ruby/filters/BulkBloomFilter.cc b/src/mem/ruby/filters/BulkBloomFilter.cc index 264b4201c..1788c0391 100644 --- a/src/mem/ruby/filters/BulkBloomFilter.cc +++ b/src/mem/ruby/filters/BulkBloomFilter.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,206 +26,220 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * BulkBloomFilter.cc - * - * Description: - * - * - */ - -#include "mem/ruby/filters/BulkBloomFilter.hh" #include "mem/gems_common/Map.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/filters/BulkBloomFilter.hh" BulkBloomFilter::BulkBloomFilter(string str) { - string tail(str); - string head = string_split(tail, '_'); + string tail(str); + string head = string_split(tail, '_'); - m_filter_size = atoi(head.c_str()); - m_filter_size_bits = log_int(m_filter_size); - // split the filter bits in half, c0 and c1 - m_sector_bits = m_filter_size_bits - 1; + m_filter_size = atoi(head.c_str()); + m_filter_size_bits = log_int(m_filter_size); + // split the filter bits in half, c0 and c1 + m_sector_bits = m_filter_size_bits - 1; - m_temp_filter.setSize(m_filter_size); - m_filter.setSize(m_filter_size); - clear(); - - // clear temp filter - for(int i=0; i < m_filter_size; ++i){ - m_temp_filter[i] = 0; - } -} - -BulkBloomFilter::~BulkBloomFilter(){ + m_temp_filter.setSize(m_filter_size); + m_filter.setSize(m_filter_size); + clear(); + // clear temp filter + for (int i = 0; i < m_filter_size; ++i) { + m_temp_filter[i] = 0; + } } -void BulkBloomFilter::clear() +BulkBloomFilter::~BulkBloomFilter() { - for (int i = 0; i < m_filter_size; i++) { - m_filter[i] = 0; - } } -void BulkBloomFilter::increment(const Address& addr) +void +BulkBloomFilter::clear() { - // Not used + for (int i = 0; i < m_filter_size; i++) { + m_filter[i] = 0; + } } - -void BulkBloomFilter::decrement(const Address& addr) +void +BulkBloomFilter::increment(const Address& addr) { - // Not used + // Not used } -void BulkBloomFilter::merge(AbstractBloomFilter * other_filter) +void +BulkBloomFilter::decrement(const Address& addr) { - // TODO + // Not used } -void BulkBloomFilter::set(const Address& addr) +void +BulkBloomFilter::merge(AbstractBloomFilter * other_filter) { - // c0 contains the cache index bits - int set_bits = m_sector_bits; - int block_bits = RubySystem::getBlockSizeBits(); - int c0 = addr.bitSelect( block_bits, block_bits + set_bits - 1); - // c1 contains the lower m_sector_bits permuted bits - //Address permuted_bits = permute(addr); - //int c1 = permuted_bits.bitSelect(0, set_bits-1); - int c1 = addr.bitSelect( block_bits+set_bits, (block_bits+2*set_bits) - 1); - //ASSERT(c0 < (m_filter_size/2)); - //ASSERT(c0 + (m_filter_size/2) < m_filter_size); - //ASSERT(c1 < (m_filter_size/2)); - // set v0 bit - m_filter[c0 + (m_filter_size/2)] = 1; - // set v1 bit - m_filter[c1] = 1; + // TODO } -void BulkBloomFilter::unset(const Address& addr) +void +BulkBloomFilter::set(const Address& addr) +{ + // c0 contains the cache index bits + int set_bits = m_sector_bits; + int block_bits = RubySystem::getBlockSizeBits(); + int c0 = addr.bitSelect( block_bits, block_bits + set_bits - 1); + // c1 contains the lower m_sector_bits permuted bits + //Address permuted_bits = permute(addr); + //int c1 = permuted_bits.bitSelect(0, set_bits-1); + int c1 = addr.bitSelect( block_bits+set_bits, (block_bits+2*set_bits) - 1); + //ASSERT(c0 < (m_filter_size/2)); + //ASSERT(c0 + (m_filter_size/2) < m_filter_size); + //ASSERT(c1 < (m_filter_size/2)); + // set v0 bit + m_filter[c0 + (m_filter_size/2)] = 1; + // set v1 bit + m_filter[c1] = 1; +} + +void +BulkBloomFilter::unset(const Address& addr) { - // not used + // not used } -bool BulkBloomFilter::isSet(const Address& addr) +bool +BulkBloomFilter::isSet(const Address& addr) { - // c0 contains the cache index bits - int set_bits = m_sector_bits; - int block_bits = RubySystem::getBlockSizeBits(); - int c0 = addr.bitSelect( block_bits, block_bits + set_bits - 1); - // c1 contains the lower 10 permuted bits - //Address permuted_bits = permute(addr); - //int c1 = permuted_bits.bitSelect(0, set_bits-1); - int c1 = addr.bitSelect( block_bits+set_bits, (block_bits+2*set_bits) - 1); - //ASSERT(c0 < (m_filter_size/2)); - //ASSERT(c0 + (m_filter_size/2) < m_filter_size); - //ASSERT(c1 < (m_filter_size/2)); - // set v0 bit - m_temp_filter[c0 + (m_filter_size/2)] = 1; - // set v1 bit - m_temp_filter[c1] = 1; + // c0 contains the cache index bits + int set_bits = m_sector_bits; + int block_bits = RubySystem::getBlockSizeBits(); + int c0 = addr.bitSelect( block_bits, block_bits + set_bits - 1); + // c1 contains the lower 10 permuted bits + //Address permuted_bits = permute(addr); + //int c1 = permuted_bits.bitSelect(0, set_bits-1); + int c1 = addr.bitSelect( block_bits+set_bits, (block_bits+2*set_bits) - 1); + //ASSERT(c0 < (m_filter_size/2)); + //ASSERT(c0 + (m_filter_size/2) < m_filter_size); + //ASSERT(c1 < (m_filter_size/2)); + // set v0 bit + m_temp_filter[c0 + (m_filter_size/2)] = 1; + // set v1 bit + m_temp_filter[c1] = 1; + + // perform filter intersection. If any c part is 0, no possibility + // of address being in signature. get first c intersection part + bool zero = false; + for (int i = 0; i < m_filter_size/2; ++i){ + // get intersection of signatures + m_temp_filter[i] = m_temp_filter[i] && m_filter[i]; + zero = zero || m_temp_filter[i]; + } + zero = !zero; + if (zero) { + // one section is zero, no possiblility of address in signature + // reset bits we just set + m_temp_filter[c0 + (m_filter_size / 2)] = 0; + m_temp_filter[c1] = 0; + return false; + } - // perform filter intersection. If any c part is 0, no possibility of address being in signature. - // get first c intersection part - bool zero = false; - for(int i=0; i < m_filter_size/2; ++i){ - // get intersection of signatures - m_temp_filter[i] = m_temp_filter[i] && m_filter[i]; - zero = zero || m_temp_filter[i]; - } - zero = !zero; - if(zero){ - // one section is zero, no possiblility of address in signature - // reset bits we just set - m_temp_filter[c0 + (m_filter_size/2)] = 0; - m_temp_filter[c1] = 0; - return false; - } - - // check second section - zero = false; - for(int i=m_filter_size/2; i < m_filter_size; ++i){ - // get intersection of signatures - m_temp_filter[i] = m_temp_filter[i] && m_filter[i]; - zero = zero || m_temp_filter[i]; - } - zero = !zero; - if(zero){ - // one section is zero, no possiblility of address in signature - m_temp_filter[c0 + (m_filter_size/2)] = 0; + // check second section + zero = false; + for(int i = m_filter_size / 2; i < m_filter_size; ++i) { + // get intersection of signatures + m_temp_filter[i] = m_temp_filter[i] && m_filter[i]; + zero = zero || m_temp_filter[i]; + } + zero = !zero; + if (zero) { + // one section is zero, no possiblility of address in signature + m_temp_filter[c0 + (m_filter_size / 2)] = 0; + m_temp_filter[c1] = 0; + return false; + } + // one section has at least one bit set + m_temp_filter[c0 + (m_filter_size / 2)] = 0; m_temp_filter[c1] = 0; - return false; - } - // one section has at least one bit set - m_temp_filter[c0 + (m_filter_size/2)] = 0; - m_temp_filter[c1] = 0; - return true; + return true; } - -int BulkBloomFilter::getCount(const Address& addr) +int +BulkBloomFilter::getCount(const Address& addr) { - // not used - return 0; + // not used + return 0; } -int BulkBloomFilter::getTotalCount() +int +BulkBloomFilter::getTotalCount() { - int count = 0; - for (int i = 0; i < m_filter_size; i++) { - if (m_filter[i]) { - count++; + int count = 0; + for (int i = 0; i < m_filter_size; i++) { + if (m_filter[i]) { + count++; + } } - } - return count; + return count; } -int BulkBloomFilter::getIndex(const Address& addr) +int +BulkBloomFilter::getIndex(const Address& addr) { - return get_index(addr); + return get_index(addr); } -int BulkBloomFilter::readBit(const int index) { - return 0; - // TODO +int +BulkBloomFilter::readBit(const int index) +{ + return 0; + // TODO } -void BulkBloomFilter::writeBit(const int index, const int value) { - // TODO +void +BulkBloomFilter::writeBit(const int index, const int value) +{ + // TODO } -void BulkBloomFilter::print(ostream& out) const +void +BulkBloomFilter::print(ostream& out) const { } -int BulkBloomFilter::get_index(const Address& addr) +int +BulkBloomFilter::get_index(const Address& addr) { - return addr.bitSelect( RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_filter_size_bits - 1); + return addr.bitSelect(RubySystem::getBlockSizeBits(), + RubySystem::getBlockSizeBits() + + m_filter_size_bits - 1); } -Address BulkBloomFilter::permute(const Address & addr){ - // permutes the original address bits according to Table 5 - int block_offset = RubySystem::getBlockSizeBits(); - physical_address_t part1 = addr.bitSelect( block_offset, block_offset + 6 ); - physical_address_t part2 = addr.bitSelect( block_offset + 9, block_offset + 9 ); - physical_address_t part3 = addr.bitSelect( block_offset + 11, block_offset + 11 ); - physical_address_t part4 = addr.bitSelect( block_offset + 17, block_offset + 17 ); - physical_address_t part5 = addr.bitSelect( block_offset + 7, block_offset + 8 ); - physical_address_t part6 = addr.bitSelect( block_offset + 10, block_offset + 10 ); - physical_address_t part7 = addr.bitSelect( block_offset + 12, block_offset + 12 ); - physical_address_t part8 = addr.bitSelect( block_offset + 13, block_offset + 13 ); - physical_address_t part9 = addr.bitSelect( block_offset + 15, block_offset + 16 ); - physical_address_t part10 = addr.bitSelect( block_offset + 18, block_offset + 20 ); - physical_address_t part11 = addr.bitSelect( block_offset + 14, block_offset + 14 ); - - physical_address_t result = (part1 << 14 ) | (part2 << 13 ) | (part3 << 12 ) | (part4 << 11 ) | (part5 << 9) | (part6 << 8) - | (part7 << 7) | (part8 << 6) | (part9 << 4) | (part10 << 1) | (part11); - // assume 32 bit addresses (both virtual and physical) - // select the remaining high-order 11 bits - physical_address_t remaining_bits = (addr.bitSelect( block_offset + 21, 31 )) << 21; - result = result | remaining_bits; - - return Address(result); +Address +BulkBloomFilter::permute(const Address & addr) +{ + // permutes the original address bits according to Table 5 + int block_offset = RubySystem::getBlockSizeBits(); + physical_address_t part1 = addr.bitSelect(block_offset, block_offset + 6), + part2 = addr.bitSelect(block_offset + 9, block_offset + 9), + part3 = addr.bitSelect(block_offset + 11, block_offset + 11), + part4 = addr.bitSelect(block_offset + 17, block_offset + 17), + part5 = addr.bitSelect(block_offset + 7, block_offset + 8), + part6 = addr.bitSelect(block_offset + 10, block_offset + 10), + part7 = addr.bitSelect(block_offset + 12, block_offset + 12), + part8 = addr.bitSelect(block_offset + 13, block_offset + 13), + part9 = addr.bitSelect(block_offset + 15, block_offset + 16), + part10 = addr.bitSelect(block_offset + 18, block_offset + 20), + part11 = addr.bitSelect(block_offset + 14, block_offset + 14); + + physical_address_t result = + (part1 << 14) | (part2 << 13) | (part3 << 12) | (part4 << 11) | + (part5 << 9) | (part6 << 8) | (part7 << 7) | (part8 << 6) | + (part9 << 4) | (part10 << 1) | (part11); + + // assume 32 bit addresses (both virtual and physical) + // select the remaining high-order 11 bits + physical_address_t remaining_bits = + addr.bitSelect(block_offset + 21, 31) << 21; + result = result | remaining_bits; + + return Address(result); } diff --git a/src/mem/ruby/filters/BulkBloomFilter.hh b/src/mem/ruby/filters/BulkBloomFilter.hh index 089531791..53a913dc3 100644 --- a/src/mem/ruby/filters/BulkBloomFilter.hh +++ b/src/mem/ruby/filters/BulkBloomFilter.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,60 +26,50 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * BulkBloomFilter.hh - * - * Description: - * - * - */ - -#ifndef BULK_BLOOM_FILTER_H -#define BULK_BLOOM_FILTER_H +#ifndef __MEM_RUBY_FILTERS_BULKBLOOMFILTER_HH__ +#define __MEM_RUBY_FILTERS_BULKBLOOMFILTER_HH__ #include "mem/gems_common/Map.hh" -#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/filters/AbstractBloomFilter.hh" -class BulkBloomFilter : public AbstractBloomFilter { -public: +class BulkBloomFilter : public AbstractBloomFilter +{ + public: + BulkBloomFilter(string config); + ~BulkBloomFilter(); - ~BulkBloomFilter(); - BulkBloomFilter(string config); + void clear(); + void increment(const Address& addr); + void decrement(const Address& addr); + void merge(AbstractBloomFilter * other_filter); + void set(const Address& addr); + void unset(const Address& addr); - void clear(); - void increment(const Address& addr); - void decrement(const Address& addr); - void merge(AbstractBloomFilter * other_filter); - void set(const Address& addr); - void unset(const Address& addr); + bool isSet(const Address& addr); + int getCount(const Address& addr); + int getTotalCount(); + int getIndex(const Address& addr); + int readBit(const int index); + void writeBit(const int index, const int value); - bool isSet(const Address& addr); - int getCount(const Address& addr); - int getTotalCount(); - int getIndex(const Address& addr); - int readBit(const int index); - void writeBit(const int index, const int value); + void print(ostream& out) const; - void print(ostream& out) const; + private: + int get_index(const Address& addr); + Address permute(const Address & addr); -private: + Vector<int> m_filter; + Vector<int> m_temp_filter; - int get_index(const Address& addr); - Address permute(const Address & addr); + int m_filter_size; + int m_filter_size_bits; - Vector<int> m_filter; - Vector<int> m_temp_filter; + int m_sector_bits; - int m_filter_size; - int m_filter_size_bits; - - int m_sector_bits; - - int m_count_bits; - int m_count; + int m_count_bits; + int m_count; }; - -#endif +#endif // __MEM_RUBY_FILTERS_BULKBLOOMFILTER_HH__ diff --git a/src/mem/ruby/filters/GenericBloomFilter.cc b/src/mem/ruby/filters/GenericBloomFilter.cc index 22c75d64c..a31e97f1f 100644 --- a/src/mem/ruby/filters/GenericBloomFilter.cc +++ b/src/mem/ruby/filters/GenericBloomFilter.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,123 +26,122 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * GenericBloomFilter.hh - * - * Description: - * - * - */ - -#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Address.hh" - +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/filters/BlockBloomFilter.hh" +#include "mem/ruby/filters/BulkBloomFilter.hh" #include "mem/ruby/filters/GenericBloomFilter.hh" +#include "mem/ruby/filters/H3BloomFilter.hh" #include "mem/ruby/filters/LSB_CountingBloomFilter.hh" -#include "mem/ruby/filters/NonCountingBloomFilter.hh" -#include "mem/ruby/filters/BulkBloomFilter.hh" -#include "mem/ruby/filters/BlockBloomFilter.hh" -#include "mem/ruby/filters/MultiGrainBloomFilter.hh" #include "mem/ruby/filters/MultiBitSelBloomFilter.hh" -#include "mem/ruby/filters/H3BloomFilter.hh" +#include "mem/ruby/filters/MultiGrainBloomFilter.hh" +#include "mem/ruby/filters/NonCountingBloomFilter.hh" GenericBloomFilter::GenericBloomFilter(string config) { - string tail(config); - string head = string_split(tail,'_'); - - if (head == "LSB_Counting" ) { - m_filter = new LSB_CountingBloomFilter(tail); - } - else if(head == "NonCounting" ) { - m_filter = new NonCountingBloomFilter(tail); - } - else if(head == "Bulk" ) { - m_filter = new BulkBloomFilter(tail); - } - else if(head == "Block") { - m_filter = new BlockBloomFilter(tail); - } - else if(head == "Multigrain"){ - m_filter = new MultiGrainBloomFilter(tail); - } - else if(head == "MultiBitSel"){ - m_filter = new MultiBitSelBloomFilter(tail); - } - else if(head == "H3"){ - m_filter = new H3BloomFilter(tail); - } - else { - assert(0); - } + string tail(config); + string head = string_split(tail,'_'); + + if (head == "LSB_Counting" ) { + m_filter = new LSB_CountingBloomFilter(tail); + } else if(head == "NonCounting" ) { + m_filter = new NonCountingBloomFilter(tail); + } else if(head == "Bulk" ) { + m_filter = new BulkBloomFilter(tail); + } else if(head == "Block") { + m_filter = new BlockBloomFilter(tail); + } else if(head == "Multigrain"){ + m_filter = new MultiGrainBloomFilter(tail); + } else if(head == "MultiBitSel"){ + m_filter = new MultiBitSelBloomFilter(tail); + } else if(head == "H3"){ + m_filter = new H3BloomFilter(tail); + } else { + assert(0); + } } GenericBloomFilter::~GenericBloomFilter() { - delete m_filter; + delete m_filter; } -void GenericBloomFilter::clear() +void +GenericBloomFilter::clear() { - m_filter->clear(); + m_filter->clear(); } -void GenericBloomFilter::increment(const Address& addr) +void +GenericBloomFilter::increment(const Address& addr) { - m_filter->increment(addr); + m_filter->increment(addr); } -void GenericBloomFilter::decrement(const Address& addr) +void +GenericBloomFilter::decrement(const Address& addr) { - m_filter->decrement(addr); + m_filter->decrement(addr); } -void GenericBloomFilter::merge(GenericBloomFilter * other_filter) +void +GenericBloomFilter::merge(GenericBloomFilter * other_filter) { - m_filter->merge(other_filter->getFilter()); + m_filter->merge(other_filter->getFilter()); } -void GenericBloomFilter::set(const Address& addr) +void +GenericBloomFilter::set(const Address& addr) { - m_filter->set(addr); + m_filter->set(addr); } -void GenericBloomFilter::unset(const Address& addr) +void +GenericBloomFilter::unset(const Address& addr) { - m_filter->unset(addr); + m_filter->unset(addr); } -bool GenericBloomFilter::isSet(const Address& addr) +bool +GenericBloomFilter::isSet(const Address& addr) { - return m_filter->isSet(addr); + return m_filter->isSet(addr); } -int GenericBloomFilter::getCount(const Address& addr) +int +GenericBloomFilter::getCount(const Address& addr) { - return m_filter->getCount(addr); + return m_filter->getCount(addr); } -int GenericBloomFilter::getTotalCount() +int +GenericBloomFilter::getTotalCount() { - return m_filter->getTotalCount(); + return m_filter->getTotalCount(); } -int GenericBloomFilter::getIndex(const Address& addr) +int +GenericBloomFilter::getIndex(const Address& addr) { - return m_filter->getIndex(addr); + return m_filter->getIndex(addr); } -int GenericBloomFilter::readBit(const int index) { - return m_filter->readBit(index); +int +GenericBloomFilter::readBit(const int index) +{ + return m_filter->readBit(index); } -void GenericBloomFilter::writeBit(const int index, const int value) { - m_filter->writeBit(index, value); +void +GenericBloomFilter::writeBit(const int index, const int value) +{ + m_filter->writeBit(index, value); } -void GenericBloomFilter::print(ostream& out) const +void +GenericBloomFilter::print(ostream& out) const { - return m_filter->print(out); + return m_filter->print(out); } diff --git a/src/mem/ruby/filters/GenericBloomFilter.hh b/src/mem/ruby/filters/GenericBloomFilter.hh index edee22f84..b7bd56d04 100644 --- a/src/mem/ruby/filters/GenericBloomFilter.hh +++ b/src/mem/ruby/filters/GenericBloomFilter.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,67 +26,54 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * GenericBloomFilter.hh - * - * Description: - * - * - */ - -#ifndef GENERIC_BLOOM_FILTER_H -#define GENERIC_BLOOM_FILTER_H +#ifndef __MEM_RUBY_FILTERS_GENERICBLOOMFILTER_HH__ +#define __MEM_RUBY_FILTERS_GENERICBLOOMFILTER_HH__ #include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/filters/AbstractBloomFilter.hh" -class GenericBloomFilter { -public: - - // Constructors - GenericBloomFilter(string config); - - void clear(); - void increment(const Address& addr); - void decrement(const Address& addr); - void merge(GenericBloomFilter * other_filter); - void set(const Address& addr); - void unset(const Address& addr); - AbstractBloomFilter * getFilter(){ - return m_filter; - } - - bool isSet(const Address& addr); - - int getCount(const Address& addr); +class GenericBloomFilter +{ + public: + GenericBloomFilter(string config); + ~GenericBloomFilter(); - int getTotalCount(); + void clear(); + void increment(const Address& addr); + void decrement(const Address& addr); + void merge(GenericBloomFilter * other_filter); + void set(const Address& addr); + void unset(const Address& addr); + AbstractBloomFilter * + getFilter() + { + return m_filter; + } - int getIndex(const Address& addr); - int readBit(const int index); - void writeBit(const int index, const int value); + bool isSet(const Address& addr); - void print(ostream& out) const; - void printConfig(ostream& out) { out << "GenericBloomFilter" << endl; } + int getCount(const Address& addr); - // Destructor - ~GenericBloomFilter(); + int getTotalCount(); + int getIndex(const Address& addr); + int readBit(const int index); + void writeBit(const int index, const int value); -private: + void print(ostream& out) const; + void printConfig(ostream& out) { out << "GenericBloomFilter" << endl; } - AbstractBloomFilter* m_filter; + private: + AbstractBloomFilter* m_filter; }; -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const GenericBloomFilter& obj) +inline ostream& +operator<<(ostream& out, const GenericBloomFilter& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } - -#endif +#endif // __MEM_RUBY_FILTERS_GENERICBLOOMFILTER_HH__ diff --git a/src/mem/ruby/filters/H3BloomFilter.cc b/src/mem/ruby/filters/H3BloomFilter.cc index 6fd8ae1a0..c73a29a84 100644 --- a/src/mem/ruby/filters/H3BloomFilter.cc +++ b/src/mem/ruby/filters/H3BloomFilter.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,1338 +26,510 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * NonCountingBloomFilter.cc - * - * Description: - * - * - */ - -#include "mem/ruby/filters/H3BloomFilter.hh" #include "mem/gems_common/Map.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/filters/H3BloomFilter.hh" static int H3[64][16] = { -{ -33268410, -395488709, -311024285, -456111753, -181495008, -119997521, -220697869, -433891432, -755927921, -515226970, -719448198, -349842774, -269183649, -463275672, -429800228, -521598937 -}, -{ -628677802, -820947732, -809435975, -1024657192, -887631270, -412050215, -391365090, -324227279, -318338329, -1038393087, -489807930, -387366128, -518096428, -324184340, -429376066, -447109279 -}, -{ -599747653, -404960623, -103933604, -946416030, -656460913, -925957005, -1047665689, -163552053, -88359290, -841315415, -899833584, -1067336680, -348549994, -464045876, -270252128, -829897652 -}, -{ -215495230, -966696438, -82589012, -750102795, -909780866, -920285789, -769759214, -331966823, -939936006, -439950703, -883794828, -1009277508, -61634610, -741444350, -98689608, -524144422 -}, -{ -93868534, -196958667, -774076619, -327921978, -122538783, -879785030, -690748527, -3498564, -83163077, -1027963025, -582088444, -466152216, -312424878, -550064499, -646612667, -561099434 -}, -{ -1002047931, -395477707, -821317480, -890482112, -697094476, -263813044, -840275189, -469664185, -795625845, -211504898, -99204277, -1004491153, -725930417, -1064479221, -893834767, -839719181 -}, -{ -278507126, -985111995, -706462983, -1042178726, -123281719, -963778122, -500881056, -726291104, -134293026, -568379664, -317050609, -533470307, -1022365922, -197645211, -315125721, -634827678 -}, -{ -219227366, -553960647, -870169525, -322232839, -508322497, -648672696, -249405795, -883596102, -476433133, -541372919, -646647793, -1042679515, -43242483, -600187508, -499866821, -135713210 -}, -{ -52837162, -96966684, -401840460, -1071661176, -733560065, -150035417, -341319946, -811582750, -636173904, -519054065, -196321433, -1028294565, -882204070, -522965093, -48884074, -117810166 -}, -{ -650860353, -789534698, -328813544, -473250022, -143128306, -173196006, -846958825, -174632187, -683273509, -405459497, -787235556, -773873501, -240110267, -426797736, -92043842, -711789240 -}, -{ -586637493, -5059646, -398035664, -6686087, -498300175, -948278148, -681227731, -592751744, -572019677, -558044722, -589368271, -695745538, -1073416749, -529192035, -550984939, -1070620580 -}, -{ -102904663, -647598516, -758863940, -313426443, -76504114, -1050747783, -708436441, -563815069, -224107668, -875925186, -167675944, -926209739, -279737287, -1040288182, -768184312, -371708956 -}, -{ -683968868, -1027427757, -180781926, -742898864, -624078545, -645659833, -577225838, -987150210, -723410002, -224013421, -993286634, -33188488, -247264323, -888018697, -38048664, -189037096 -}, -{ -475612146, -426739285, -873726278, -529192871, -607715202, -388486246, -987001312, -474493980, -259747270, -417465536, -217062395, -392858482, -563810075, -137852805, -1051814153, -72895217 -}, -{ -71277086, -785496675, -500608842, -89633426, -274085706, -248467935, -838061983, -48106147, -773662506, -49545328, -9071573, -100739031, -602018002, -904371654, -534132064, -332211304 -}, -{ -401893602, -735125342, -775548339, -210224843, -256081130, -482894412, -350801633, -1035713633, -429458128, -327281409, -739927752, -359327650, -886942880, -847691759, -752417993, -359445596 -}, -{ -267472014, -1050659620, -1068232362, -1049684368, -17130239, -690524969, -793224378, -14455158, -423092885, -873853424, -430535778, -7867877, -309731959, -370260786, -862353083, -403906850 -}, -{ -993077283, -218812656, -389234651, -393202875, -413116501, -263300295, -470013158, -592730725, -441847172, -732392823, -407574059, -875664777, -271347307, -792954404, -554774761, -1022424300 -}, -{ -675919719, -637054073, -784720745, -149714381, -813144874, -502525801, -635436670, -1003196587, -160786091, -947509775, -969788637, -26854073, -257964369, -63898568, -539767732, -772364518 -}, -{ -943076868, -1021732472, -697575075, -15843624, -617573396, -534113303, -122953324, -964873912, -942995378, -87830944, -1012914818, -455484661, -592160054, -599844284, -810394353, -836812568 -}, -{ -688992674, -279465370, -731582262, -687883235, -438178468, -80493001, -342701501, -663561405, -23360106, -531315007, -508931618, -36294623, -231216223, -840438413, -255665680, -663205938 -}, -{ -857265418, -552630887, -8173237, -792122963, -210140052, -823124938, -667709953, -751538219, -991957789, -462064153, -19070176, -726604748, -714567823, -151147895, -1012619677, -697114353 -}, -{ -467105652, -683256174, -702387467, -28730434, -549942998, -48712701, -960519696, -1008345587, -679267717, -370932249, -880419471, -352141567, -331640403, -598772468, -95160685, -812053015 -}, -{ -1053491323, -430526562, -1014938507, -109685515, -765949103, -177288303, -1034642653, -485421658, -71850281, -981034542, -61620389, -601367920, -504420930, -220599168, -583051998, -158735752 -}, -{ -103033901, -522494916, -658494760, -959206022, -931348143, -834510661, -21542994, -189699884, -679327018, -171983002, -96774168, -456133168, -543103352, -923945936, -970074188, -643658485 -}, -{ -566379913, -805798263, -840662512, -820206124, -796507494, -223712542, -118811519, -662246595, -809326534, -416471323, -748027186, -161169753, -739149488, -276330378, -924837051, -964873733 -}, -{ -585882743, -135502711, -3386031, -625631285, -1068193307, -270342640, -432739484, -556606453, -826419155, -1038540977, -158000202, -69109538, -207087256, -298111218, -678046259, -184611498 -}, -{ -305310710, -46237988, -855726974, -735975153, -930663798, -425764232, -104362407, -391371443, -867622101, -71645091, -61824734, -661902640, -293738633, -309416189, -281710675, -879317360 -}, -{ -398146324, -398293087, -689145387, -1038451703, -521637478, -516134620, -314658937, -830334981, -583400300, -340083705, -68029852, -675389876, -994635780, -788959180, -406967042, -74403607 -}, -{ -69463153, -744427484, -191639960, -590927798, -969916795, -546846769, -728756758, -889355646, -520855076, -136068426, -776132410, -189663815, -252051082, -533662856, -362198652, -1026161384 -}, -{ -584984279, -1004834381, -568439705, -834508761, -21812513, -670870173, -1052043300, -341868768, -473755574, -124339439, -36193947, -437997647, -137419489, -58705193, -337793711, -340738909 -}, -{ -898051466, -512792906, -234874060, -655358775, -683745319, -671676404, -428888546, -639928192, -672697722, -176477579, -747020991, -758211282, -443045009, -205395173, -1016944273, -5584717 -}, -{ -156038300, -138620174, -588466825, -1061494056, -1013672100, -1064257198, -881417791, -839470738, -83519030, -100875683, -237486447, -461483733, -681527127, -777996147, -574635362, -815974538 -}, -{ -184168473, -519509808, -62531892, -51821173, -43787358, -385711644, -141325169, -36069511, -584183031, -571372909, -671503175, -226486781, -194932686, -1045460970, -753718579, -331442433 -}, -{ -73065106, -1015327221, -630916840, -1058053470, -306737587, -296343219, -907194989, -920172546, -224516225, -818625553, -551143849, -634570650, -432966225, -756438259, -939564853, -767999933 -}, -{ -884775648, -394862257, -446787794, -219833788, -727195727, -728122304, -249888353, -732947974, -289908868, -448282580, -618161877, -898939716, -739554163, -860631799, -1058977530, -86916736 -}, -{ -143850006, -352708694, -200194048, -979764914, -629404175, -546279766, -72106714, -860980514, -313190585, -897143111, -308425797, -953791785, -349924906, -221457005, -950588925, -908254505 -}, -{ -950032043, -829868728, -68623614, -714624605, -69760597, -297275854, -355894016, -985369737, -882852618, -864071289, -958512902, -950910111, -991368991, -829645051, -434698210, -771350575 -}, -{ -552695074, -319195551, -80297396, -496413831, -944046531, -621525571, -617653363, -416729825, -441842808, -9847464, -99420657, -1033914550, -812966458, -937053011, -673390195, -934577365 -}, -{ -1034695843, -190969665, -332900185, -51897434, -523888639, -883512843, -146908572, -506785674, -565814307, -692255649, -314052926, -826386588, -430691325, -866927620, -413880214, -936474339 -}, -{ -129380164, -741739952, -1013703462, -494392795, -957214600, -1010879043, -931790677, -94551922, -988065869, -120637871, -882506912, -395075379, -210570485, -812422692, -910383687, -817722285 -}, -{ -51850866, -283408630, -1053047202, -858940389, -818507731, -477082181, -353546901, -993324368, -407093779, -231608253, -1067319867, -73159811, -429792535, -971320614, -565699344, -718823399 -}, -{ -408185106, -491493570, -596050720, -310776444, -703628192, -454438809, -523988035, -728512200, -686012353, -976339656, -72816924, -116926720, -165866591, -452043792, -866943072, -968545481 -}, -{ -443231195, -905907843, -1061421320, -746360489, -1043120338, -1069659155, -463359031, -688303227, -186550710, -155347339, -1044842421, -1005904570, -69332909, -706951903, -422513657, -882038450 -}, -{ -430990623, -946501980, -742556791, -278398643, -183759217, -659404315, -279754382, -1069347846, -843746517, -222777670, -990835599, -548741637, -129220580, -1392170, -1032654091, -894058935 -}, -{ -452042227, -751640705, -259481376, -765824585, -145991469, -1013683228, -1055491225, -536379588, -392593350, -913368594, -1029429776, -226857786, -31505342, -1054416381, -32341741, -687106649 -}, -{ -404750944, -811417027, -869530820, -773491060, -810901282, -979340397, -1036910290, -461764404, -834235095, -765695033, -604692390, -452158120, -928988098, -442719218, -1024059719, -167723114 -}, -{ -974245177, -1046377300, -1003424287, -787349855, -336314155, -875074696, -1018462718, -890313003, -367376809, -86355556, -1020618772, -890710345, -444741481, -373230261, -767064947, -840920177 -}, -{ -719581124, -431808156, -138301690, -668222575, -497413494, -740492013, -485033226, -125301442, -831265111, -879071459, -341690480, -152975256, -850330086, -717444507, -694225877, -785340566 -}, -{ -1032766252, -140959364, -737474726, -1062767538, -364464647, -331414723, -356152634, -642832379, -158733632, -374691640, -285504811, -345349905, -876599880, -476392727, -479589210, -606376325 -}, -{ -174997730, -778177086, -319164313, -163614456, -10331364, -599358958, -8331663, -237538058, -159173957, -174533880, -65588684, -878222844, -424467599, -901803515, -187504218, -776690353 -}, -{ -803856182, -965850321, -694948067, -218315960, -358416571, -683713254, -178069303, -428076035, -686176454, -579553217, -357306738, -315018080, -886852373, -568563910, -896839725, -257416821 -}, -{ -401650013, -183289141, -497957228, -879734476, -265024455, -825794561, -889237440, -323359863, -100258491, -991414783, -313986632, -85847250, -362520248, -276103512, -1041630342, -525981595 -}, -{ -487732740, -46201705, -990837834, -62744493, -1067364756, -58015363, -690846283, -680262648, -997278956, -469357861, -432164624, -996763915, -211907847, -167824295, -144928194, -454839915 -}, -{ -41404232, -514493300, -259546924, -578217256, -972345130, -123299213, -346040332, -1014668104, -520910639, -579955198, -36627803, -179072921, -547684341, -598950511, -269497394, -854352266 -}, -{ -603906768, -100863318, -708837659, -204175569, -375560904, -908375384, -28314106, -6303733, -175283124, -749851198, -308667367, -415293931, -225365403, -1032188331, -977112710, -819705229 -}, -{ -399767123, -697985692, -356790426, -643687584, -298624218, -185095167, -381653926, -876816342, -296720023, -2205879, -235816616, -521850105, -622753786, -1021421218, -726349744, -256504902 -}, -{ -851245024, -1022500222, -511909628, -313809625, -99776025, -39710175, -798739932, -741832408, -140631966, -898295927, -607660421, -870669312, -1051422478, -789055529, -669113756, -681943450 -}, -{ -853872755, -491465269, -503341472, -98019440, -258267420, -335602837, -320687824, -1053324395, -24932389, -955011453, -934255131, -435625663, -501568768, -238967025, -549987406, -248619780 -}, -{ -411151284, -576471205, -757985419, -544137226, -968135693, -877548443, -194586894, -74882373, -248353663, -21207540, -273789651, -853653916, -861267970, -533253322, -3739570, -661358586 -}, -{ -271430986, -71390029, -257643671, -949329860, -348156406, -251939238, -445808698, -48269799, -907589462, -105677619, -635451508, -20805932, -464874661, -7542147, -243619464, -288304568 -}, -{ -368215982, -530288964, -770090421, -660961164, -614935537, -630760399, -931299233, -794519275, -779918979, -401746493, -561237006, -1027202224, -258968003, -339508073, -1050610516, -1064307013 -}, -{ -1039172162, -448331205, -928997884, -49813151, -198712120, -992335354, -671024050, -879525220, -745915336, -1038822580, -138669665, -917958819, -681422342, -792868818, -924762727, -816386174 -}, -{ -515190336, -313808618, -441296783, -1022120897, -792325033, -354387581, -59273006, -280075434, -411357221, -665274694, -4054464, -1059046246, -394261773, -848616745, -15446017, -517723271 -}}; + { 33268410, 395488709, 311024285, 456111753, + 181495008, 119997521, 220697869, 433891432, + 755927921, 515226970, 719448198, 349842774, + 269183649, 463275672, 429800228, 521598937, }, + + { 628677802, 820947732, 809435975, 1024657192, + 887631270, 412050215, 391365090, 324227279, + 318338329, 1038393087, 489807930, 387366128, + 518096428, 324184340, 429376066, 447109279, }, + + { 599747653, 404960623, 103933604, 946416030, + 656460913, 925957005, 1047665689, 163552053, + 88359290, 841315415, 899833584, 1067336680, + 348549994, 464045876, 270252128, 829897652, }, + + { 215495230, 966696438, 82589012, 750102795, + 909780866, 920285789, 769759214, 331966823, + 939936006, 439950703, 883794828, 1009277508, + 61634610, 741444350, 98689608, 524144422, }, + + { 93868534, 196958667, 774076619, 327921978, + 122538783, 879785030, 690748527, 3498564, + 83163077, 1027963025, 582088444, 466152216, + 312424878, 550064499, 646612667, 561099434, }, + + { 1002047931, 395477707, 821317480, 890482112, + 697094476, 263813044, 840275189, 469664185, + 795625845, 211504898, 99204277, 1004491153, + 725930417, 1064479221, 893834767, 839719181, }, + + { 278507126, 985111995, 706462983, 1042178726, + 123281719, 963778122, 500881056, 726291104, + 134293026, 568379664, 317050609, 533470307, + 1022365922, 197645211, 315125721, 634827678, }, + + { 219227366, 553960647, 870169525, 322232839, + 508322497, 648672696, 249405795, 883596102, + 476433133, 541372919, 646647793, 1042679515, + 43242483, 600187508, 499866821, 135713210, }, + + { 52837162, 96966684, 401840460, 1071661176, + 733560065, 150035417, 341319946, 811582750, + 636173904, 519054065, 196321433, 1028294565, + 882204070, 522965093, 48884074, 117810166, }, + + { 650860353, 789534698, 328813544, 473250022, + 143128306, 173196006, 846958825, 174632187, + 683273509, 405459497, 787235556, 773873501, + 240110267, 426797736, 92043842, 711789240, }, + + { 586637493, 5059646, 398035664, 6686087, + 498300175, 948278148, 681227731, 592751744, + 572019677, 558044722, 589368271, 695745538, + 1073416749, 529192035, 550984939, 1070620580, }, + + { 102904663, 647598516, 758863940, 313426443, + 76504114, 1050747783, 708436441, 563815069, + 224107668, 875925186, 167675944, 926209739, + 279737287, 1040288182, 768184312, 371708956, }, + + { 683968868, 1027427757, 180781926, 742898864, + 624078545, 645659833, 577225838, 987150210, + 723410002, 224013421, 993286634, 33188488, + 247264323, 888018697, 38048664, 189037096, }, + + { 475612146, 426739285, 873726278, 529192871, + 607715202, 388486246, 987001312, 474493980, + 259747270, 417465536, 217062395, 392858482, + 563810075, 137852805, 1051814153, 72895217, }, + + { 71277086, 785496675, 500608842, 89633426, + 274085706, 248467935, 838061983, 48106147, + 773662506, 49545328, 9071573, 100739031, + 602018002, 904371654, 534132064, 332211304, }, + + { 401893602, 735125342, 775548339, 210224843, + 256081130, 482894412, 350801633, 1035713633, + 429458128, 327281409, 739927752, 359327650, + 886942880, 847691759, 752417993, 359445596, }, + + { 267472014, 1050659620, 1068232362, 1049684368, + 17130239, 690524969, 793224378, 14455158, + 423092885, 873853424, 430535778, 7867877, + 309731959, 370260786, 862353083, 403906850, }, + + { 993077283, 218812656, 389234651, 393202875, + 413116501, 263300295, 470013158, 592730725, + 441847172, 732392823, 407574059, 875664777, + 271347307, 792954404, 554774761, 1022424300, }, + + { 675919719, 637054073, 784720745, 149714381, + 813144874, 502525801, 635436670, 1003196587, + 160786091, 947509775, 969788637, 26854073, + 257964369, 63898568, 539767732, 772364518, }, + + { 943076868, 1021732472, 697575075, 15843624, + 617573396, 534113303, 122953324, 964873912, + 942995378, 87830944, 1012914818, 455484661, + 592160054, 599844284, 810394353, 836812568, }, + + { 688992674, 279465370, 731582262, 687883235, + 438178468, 80493001, 342701501, 663561405, + 23360106, 531315007, 508931618, 36294623, + 231216223, 840438413, 255665680, 663205938, }, + + { 857265418, 552630887, 8173237, 792122963, + 210140052, 823124938, 667709953, 751538219, + 991957789, 462064153, 19070176, 726604748, + 714567823, 151147895, 1012619677, 697114353, }, + + { 467105652, 683256174, 702387467, 28730434, + 549942998, 48712701, 960519696, 1008345587, + 679267717, 370932249, 880419471, 352141567, + 331640403, 598772468, 95160685, 812053015, }, + + { 1053491323, 430526562, 1014938507, 109685515, + 765949103, 177288303, 1034642653, 485421658, + 71850281, 981034542, 61620389, 601367920, + 504420930, 220599168, 583051998, 158735752, }, + + { 103033901, 522494916, 658494760, 959206022, + 931348143, 834510661, 21542994, 189699884, + 679327018, 171983002, 96774168, 456133168, + 543103352, 923945936, 970074188, 643658485, }, + + { 566379913, 805798263, 840662512, 820206124, + 796507494, 223712542, 118811519, 662246595, + 809326534, 416471323, 748027186, 161169753, + 739149488, 276330378, 924837051, 964873733, }, + + { 585882743, 135502711, 3386031, 625631285, + 1068193307, 270342640, 432739484, 556606453, + 826419155, 1038540977, 158000202, 69109538, + 207087256, 298111218, 678046259, 184611498, }, + + { 305310710, 46237988, 855726974, 735975153, + 930663798, 425764232, 104362407, 391371443, + 867622101, 71645091, 61824734, 661902640, + 293738633, 309416189, 281710675, 879317360, }, + + { 398146324, 398293087, 689145387, 1038451703, + 521637478, 516134620, 314658937, 830334981, + 583400300, 340083705, 68029852, 675389876, + 994635780, 788959180, 406967042, 74403607, }, + + { 69463153, 744427484, 191639960, 590927798, + 969916795, 546846769, 728756758, 889355646, + 520855076, 136068426, 776132410, 189663815, + 252051082, 533662856, 362198652, 1026161384, }, + + { 584984279, 1004834381, 568439705, 834508761, + 21812513, 670870173, 1052043300, 341868768, + 473755574, 124339439, 36193947, 437997647, + 137419489, 58705193, 337793711, 340738909, }, + + { 898051466, 512792906, 234874060, 655358775, + 683745319, 671676404, 428888546, 639928192, + 672697722, 176477579, 747020991, 758211282, + 443045009, 205395173, 1016944273, 5584717, }, + + { 156038300, 138620174, 588466825, 1061494056, + 1013672100, 1064257198, 881417791, 839470738, + 83519030, 100875683, 237486447, 461483733, + 681527127, 777996147, 574635362, 815974538, }, + + { 184168473, 519509808, 62531892, 51821173, + 43787358, 385711644, 141325169, 36069511, + 584183031, 571372909, 671503175, 226486781, + 194932686, 1045460970, 753718579, 331442433, }, + + { 73065106, 1015327221, 630916840, 1058053470, + 306737587, 296343219, 907194989, 920172546, + 224516225, 818625553, 551143849, 634570650, + 432966225, 756438259, 939564853, 767999933, }, + + { 884775648, 394862257, 446787794, 219833788, + 727195727, 728122304, 249888353, 732947974, + 289908868, 448282580, 618161877, 898939716, + 739554163, 860631799, 1058977530, 86916736, }, + + { 143850006, 352708694, 200194048, 979764914, + 629404175, 546279766, 72106714, 860980514, + 313190585, 897143111, 308425797, 953791785, + 349924906, 221457005, 950588925, 908254505, }, + + { 950032043, 829868728, 68623614, 714624605, + 69760597, 297275854, 355894016, 985369737, + 882852618, 864071289, 958512902, 950910111, + 991368991, 829645051, 434698210, 771350575, }, + + { 552695074, 319195551, 80297396, 496413831, + 944046531, 621525571, 617653363, 416729825, + 441842808, 9847464, 99420657, 1033914550, + 812966458, 937053011, 673390195, 934577365, }, + + { 1034695843, 190969665, 332900185, 51897434, + 523888639, 883512843, 146908572, 506785674, + 565814307, 692255649, 314052926, 826386588, + 430691325, 866927620, 413880214, 936474339, }, + + { 129380164, 741739952, 1013703462, 494392795, + 957214600, 1010879043, 931790677, 94551922, + 988065869, 120637871, 882506912, 395075379, + 210570485, 812422692, 910383687, 817722285, }, + + { 51850866, 283408630, 1053047202, 858940389, + 818507731, 477082181, 353546901, 993324368, + 407093779, 231608253, 1067319867, 73159811, + 429792535, 971320614, 565699344, 718823399, }, + + { 408185106, 491493570, 596050720, 310776444, + 703628192, 454438809, 523988035, 728512200, + 686012353, 976339656, 72816924, 116926720, + 165866591, 452043792, 866943072, 968545481, }, + + { 443231195, 905907843, 1061421320, 746360489, + 1043120338, 1069659155, 463359031, 688303227, + 186550710, 155347339, 1044842421, 1005904570, + 69332909, 706951903, 422513657, 882038450, }, + + { 430990623, 946501980, 742556791, 278398643, + 183759217, 659404315, 279754382, 1069347846, + 843746517, 222777670, 990835599, 548741637, + 129220580, 1392170, 1032654091, 894058935, }, + + { 452042227, 751640705, 259481376, 765824585, + 145991469, 1013683228, 1055491225, 536379588, + 392593350, 913368594, 1029429776, 226857786, + 31505342, 1054416381, 32341741, 687106649, }, + + { 404750944, 811417027, 869530820, 773491060, + 810901282, 979340397, 1036910290, 461764404, + 834235095, 765695033, 604692390, 452158120, + 928988098, 442719218, 1024059719, 167723114, }, + + { 974245177, 1046377300, 1003424287, 787349855, + 336314155, 875074696, 1018462718, 890313003, + 367376809, 86355556, 1020618772, 890710345, + 444741481, 373230261, 767064947, 840920177, }, + + { 719581124, 431808156, 138301690, 668222575, + 497413494, 740492013, 485033226, 125301442, + 831265111, 879071459, 341690480, 152975256, + 850330086, 717444507, 694225877, 785340566, }, + + { 1032766252, 140959364, 737474726, 1062767538, + 364464647, 331414723, 356152634, 642832379, + 158733632, 374691640, 285504811, 345349905, + 876599880, 476392727, 479589210, 606376325, }, + + { 174997730, 778177086, 319164313, 163614456, + 10331364, 599358958, 8331663, 237538058, + 159173957, 174533880, 65588684, 878222844, + 424467599, 901803515, 187504218, 776690353, }, + + { 803856182, 965850321, 694948067, 218315960, + 358416571, 683713254, 178069303, 428076035, + 686176454, 579553217, 357306738, 315018080, + 886852373, 568563910, 896839725, 257416821, }, + + { 401650013, 183289141, 497957228, 879734476, + 265024455, 825794561, 889237440, 323359863, + 100258491, 991414783, 313986632, 85847250, + 362520248, 276103512, 1041630342, 525981595, }, + + { 487732740, 46201705, 990837834, 62744493, + 1067364756, 58015363, 690846283, 680262648, + 997278956, 469357861, 432164624, 996763915, + 211907847, 167824295, 144928194, 454839915, }, + + { 41404232, 514493300, 259546924, 578217256, + 972345130, 123299213, 346040332, 1014668104, + 520910639, 579955198, 36627803, 179072921, + 547684341, 598950511, 269497394, 854352266, }, + + { 603906768, 100863318, 708837659, 204175569, + 375560904, 908375384, 28314106, 6303733, + 175283124, 749851198, 308667367, 415293931, + 225365403, 1032188331, 977112710, 819705229, }, + + { 399767123, 697985692, 356790426, 643687584, + 298624218, 185095167, 381653926, 876816342, + 296720023, 2205879, 235816616, 521850105, + 622753786, 1021421218, 726349744, 256504902, }, + + { 851245024, 1022500222, 511909628, 313809625, + 99776025, 39710175, 798739932, 741832408, + 140631966, 898295927, 607660421, 870669312, + 1051422478, 789055529, 669113756, 681943450, }, + + { 853872755, 491465269, 503341472, 98019440, + 258267420, 335602837, 320687824, 1053324395, + 24932389, 955011453, 934255131, 435625663, + 501568768, 238967025, 549987406, 248619780, }, + + { 411151284, 576471205, 757985419, 544137226, + 968135693, 877548443, 194586894, 74882373, + 248353663, 21207540, 273789651, 853653916, + 861267970, 533253322, 3739570, 661358586, }, + + { 271430986, 71390029, 257643671, 949329860, + 348156406, 251939238, 445808698, 48269799, + 907589462, 105677619, 635451508, 20805932, + 464874661, 7542147, 243619464, 288304568, }, + + { 368215982, 530288964, 770090421, 660961164, + 614935537, 630760399, 931299233, 794519275, + 779918979, 401746493, 561237006, 1027202224, + 258968003, 339508073, 1050610516, 1064307013, }, + + { 1039172162, 448331205, 928997884, 49813151, + 198712120, 992335354, 671024050, 879525220, + 745915336, 1038822580, 138669665, 917958819, + 681422342, 792868818, 924762727, 816386174, }, + + { 515190336, 313808618, 441296783, 1022120897, + 792325033, 354387581, 59273006, 280075434, + 411357221, 665274694, 4054464, 1059046246, + 394261773, 848616745, 15446017, 517723271, }, +}; H3BloomFilter::H3BloomFilter(string str) { - //TODO: change this ugly init code... - primes_list[0] = 9323; - primes_list[1] = 11279; - primes_list[2] = 10247; - primes_list[3] = 30637; - primes_list[4] = 25717; - primes_list[5] = 43711; - - mults_list[0] = 255; - mults_list[1] = 29; - mults_list[2] = 51; - mults_list[3] = 3; - mults_list[4] = 77; - mults_list[5] = 43; - - adds_list[0] = 841; - adds_list[1] = 627; - adds_list[2] = 1555; - adds_list[3] = 241; - adds_list[4] = 7777; - adds_list[5] = 65931; - - - - string tail(str); - string head = string_split(tail, '_'); - - // head contains filter size, tail contains bit offset from block number - m_filter_size = atoi(head.c_str()); - - head = string_split(tail, '_'); - m_num_hashes = atoi(head.c_str()); - - if(tail == "Regular") { - isParallel = false; - } else if (tail == "Parallel") { - isParallel = true; - } else { - cout << "ERROR: Incorrect config string for MultiHash Bloom! :" << str << endl; - assert(0); - } - - m_filter_size_bits = log_int(m_filter_size); - - m_par_filter_size = m_filter_size/m_num_hashes; - m_par_filter_size_bits = log_int(m_par_filter_size); - - m_filter.setSize(m_filter_size); - clear(); + //TODO: change this ugly init code... + primes_list[0] = 9323; + primes_list[1] = 11279; + primes_list[2] = 10247; + primes_list[3] = 30637; + primes_list[4] = 25717; + primes_list[5] = 43711; + + mults_list[0] = 255; + mults_list[1] = 29; + mults_list[2] = 51; + mults_list[3] = 3; + mults_list[4] = 77; + mults_list[5] = 43; + + adds_list[0] = 841; + adds_list[1] = 627; + adds_list[2] = 1555; + adds_list[3] = 241; + adds_list[4] = 7777; + adds_list[5] = 65931; + + string tail(str); + string head = string_split(tail, '_'); + + // head contains filter size, tail contains bit offset from block number + m_filter_size = atoi(head.c_str()); + + head = string_split(tail, '_'); + m_num_hashes = atoi(head.c_str()); + + if(tail == "Regular") { + isParallel = false; + } else if (tail == "Parallel") { + isParallel = true; + } else { + cout << "ERROR: Incorrect config string for MultiHash Bloom! :" + << str << endl; + assert(0); + } + + m_filter_size_bits = log_int(m_filter_size); + + m_par_filter_size = m_filter_size/m_num_hashes; + m_par_filter_size_bits = log_int(m_par_filter_size); + + m_filter.setSize(m_filter_size); + clear(); } -H3BloomFilter::~H3BloomFilter(){ +H3BloomFilter::~H3BloomFilter() +{ } -void H3BloomFilter::clear() +void +H3BloomFilter::clear() { - for (int i = 0; i < m_filter_size; i++) { - m_filter[i] = 0; - } + for (int i = 0; i < m_filter_size; i++) { + m_filter[i] = 0; + } } -void H3BloomFilter::increment(const Address& addr) +void +H3BloomFilter::increment(const Address& addr) { - // Not used + // Not used } - -void H3BloomFilter::decrement(const Address& addr) +void +H3BloomFilter::decrement(const Address& addr) { - // Not used + // Not used } -void H3BloomFilter::merge(AbstractBloomFilter * other_filter){ - // assumes both filters are the same size! - H3BloomFilter * temp = (H3BloomFilter*) other_filter; - for(int i=0; i < m_filter_size; ++i){ - m_filter[i] |= (*temp)[i]; - } - +void +H3BloomFilter::merge(AbstractBloomFilter *other_filter) +{ + // assumes both filters are the same size! + H3BloomFilter * temp = (H3BloomFilter*) other_filter; + for(int i = 0; i < m_filter_size; ++i){ + m_filter[i] |= (*temp)[i]; + } } -void H3BloomFilter::set(const Address& addr) +void +H3BloomFilter::set(const Address& addr) { - for (int i = 0; i < m_num_hashes; i++) { - int idx = get_index(addr, i); - m_filter[idx] = 1; - - //Profile hash value distribution - //g_system_ptr->getProfiler()->getXactProfiler()->profileHashValue(i, idx); // gem5:Arka decomissiong of log_tm - } + for (int i = 0; i < m_num_hashes; i++) { + int idx = get_index(addr, i); + m_filter[idx] = 1; + } } -void H3BloomFilter::unset(const Address& addr) +void +H3BloomFilter::unset(const Address& addr) { - cout << "ERROR: Unset should never be called in a Bloom filter"; - assert(0); + cout << "ERROR: Unset should never be called in a Bloom filter"; + assert(0); } -bool H3BloomFilter::isSet(const Address& addr) +bool +H3BloomFilter::isSet(const Address& addr) { - bool res = true; + bool res = true; - for (int i=0; i < m_num_hashes; i++) { - int idx = get_index(addr, i); - res = res && m_filter[idx]; - } - return res; + for (int i = 0; i < m_num_hashes; i++) { + int idx = get_index(addr, i); + res = res && m_filter[idx]; + } + return res; } - -int H3BloomFilter::getCount(const Address& addr) +int +H3BloomFilter::getCount(const Address& addr) { - return isSet(addr)? 1: 0; + return isSet(addr)? 1: 0; } -int H3BloomFilter::getIndex(const Address& addr) +int +H3BloomFilter::getIndex(const Address& addr) { - return 0; + return 0; } -int H3BloomFilter::readBit(const int index) { - return 0; +int +H3BloomFilter::readBit(const int index) +{ + return 0; } -void H3BloomFilter::writeBit(const int index, const int value) { - +void +H3BloomFilter::writeBit(const int index, const int value) +{ } -int H3BloomFilter::getTotalCount() +int +H3BloomFilter::getTotalCount() { - int count = 0; + int count = 0; - for (int i = 0; i < m_filter_size; i++) { - count += m_filter[i]; - } - return count; + for (int i = 0; i < m_filter_size; i++) { + count += m_filter[i]; + } + return count; } -void H3BloomFilter::print(ostream& out) const +void +H3BloomFilter::print(ostream& out) const { } -int H3BloomFilter::get_index(const Address& addr, int i) +int +H3BloomFilter::get_index(const Address& addr, int i) { - uint64 x = addr.getLineAddress(); - //uint64 y = (x*mults_list[i] + adds_list[i]) % primes_list[i]; - int y = hash_H3(x,i); - - if(isParallel) { - return (y % m_par_filter_size) + i*m_par_filter_size; - } else { - return y % m_filter_size; - } + uint64 x = addr.getLineAddress(); + // uint64 y = (x*mults_list[i] + adds_list[i]) % primes_list[i]; + int y = hash_H3(x,i); + + if (isParallel) { + return (y % m_par_filter_size) + i*m_par_filter_size; + } else { + return y % m_filter_size; + } } -int H3BloomFilter::hash_H3(uint64 value, int index) { - uint64 mask = 1; - uint64 val = value; - int result = 0; - - for(int i = 0; i < 64; i++) { - if(val&mask) result ^= H3[i][index]; - val = val >> 1; - } - return result; - } +int +H3BloomFilter::hash_H3(uint64 value, int index) +{ + uint64 mask = 1; + uint64 val = value; + int result = 0; + + for (int i = 0; i < 64; i++) { + if(val&mask) result ^= H3[i][index]; + val = val >> 1; + } + return result; +} diff --git a/src/mem/ruby/filters/H3BloomFilter.hh b/src/mem/ruby/filters/H3BloomFilter.hh index 360000540..6c18508eb 100644 --- a/src/mem/ruby/filters/H3BloomFilter.hh +++ b/src/mem/ruby/filters/H3BloomFilter.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,76 +26,65 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * H3BloomFilter.hh - * - * Description: - * - * - */ - -#ifndef H3_BLOOM_FILTER_H -#define H3_BLOOM_FILTER_H +#ifndef __MEM_RUBY_FILTERS_H3BLOOMFILTER_HH__ +#define __MEM_RUBY_FILTERS_H3BLOOMFILTER_HH__ #include "mem/gems_common/Map.hh" -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/System.hh" -#include "mem/ruby/profiler/Profiler.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/filters/AbstractBloomFilter.hh" +#include "mem/ruby/profiler/Profiler.hh" +#include "mem/ruby/system/System.hh" -class H3BloomFilter : public AbstractBloomFilter { -public: - - ~H3BloomFilter(); - H3BloomFilter(string config); - - void clear(); - void increment(const Address& addr); - void decrement(const Address& addr); - void merge(AbstractBloomFilter * other_filter); - void set(const Address& addr); - void unset(const Address& addr); - - bool isSet(const Address& addr); - int getCount(const Address& addr); - int getTotalCount(); - void print(ostream& out) const; - - int getIndex(const Address& addr); - int readBit(const int index); - void writeBit(const int index, const int value); - - int operator[](const int index) const{ - return this->m_filter[index]; - } +class H3BloomFilter : public AbstractBloomFilter +{ + public: + H3BloomFilter(string config); + ~H3BloomFilter(); -private: + void clear(); + void increment(const Address& addr); + void decrement(const Address& addr); + void merge(AbstractBloomFilter * other_filter); + void set(const Address& addr); + void unset(const Address& addr); - int get_index(const Address& addr, int hashNumber); + bool isSet(const Address& addr); + int getCount(const Address& addr); + int getTotalCount(); + void print(ostream& out) const; - int hash_H3(uint64 value, int index); + int getIndex(const Address& addr); + int readBit(const int index); + void writeBit(const int index, const int value); - Vector<int> m_filter; - int m_filter_size; - int m_num_hashes; - int m_filter_size_bits; + int + operator[](const int index) const + { + return this->m_filter[index]; + } - int m_par_filter_size; - int m_par_filter_size_bits; + private: + int get_index(const Address& addr, int hashNumber); - int m_count_bits; - int m_count; + int hash_H3(uint64 value, int index); + Vector<int> m_filter; + int m_filter_size; + int m_num_hashes; + int m_filter_size_bits; + int m_par_filter_size; + int m_par_filter_size_bits; - int primes_list[6];// = {9323,11279,10247,30637,25717,43711}; - int mults_list[6]; //= {255,29,51,3,77,43}; - int adds_list[6]; //= {841,627,1555,241,7777,65391}; + int m_count_bits; + int m_count; - bool isParallel; + int primes_list[6];// = {9323,11279,10247,30637,25717,43711}; + int mults_list[6]; //= {255,29,51,3,77,43}; + int adds_list[6]; //= {841,627,1555,241,7777,65391}; + bool isParallel; }; - -#endif +#endif // __MEM_RUBY_FILTERS_H3BLOOMFILTER_HH__ diff --git a/src/mem/ruby/filters/LSB_CountingBloomFilter.cc b/src/mem/ruby/filters/LSB_CountingBloomFilter.cc index a79201ad4..b64c3e75a 100644 --- a/src/mem/ruby/filters/LSB_CountingBloomFilter.cc +++ b/src/mem/ruby/filters/LSB_CountingBloomFilter.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,116 +26,126 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * LSB_CountingBloomFilter.cc - * - * Description: - * - * - */ - -#include "mem/ruby/filters/LSB_CountingBloomFilter.hh" #include "mem/gems_common/Map.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/filters/LSB_CountingBloomFilter.hh" LSB_CountingBloomFilter::LSB_CountingBloomFilter(string str) { - string tail(str); - string head = string_split(tail, ':'); + string tail(str); + string head = string_split(tail, ':'); - m_filter_size = atoi(head.c_str()); - m_filter_size_bits = log_int(m_filter_size); + m_filter_size = atoi(head.c_str()); + m_filter_size_bits = log_int(m_filter_size); - m_count = atoi(tail.c_str()); - m_count_bits = log_int(m_count); + m_count = atoi(tail.c_str()); + m_count_bits = log_int(m_count); - m_filter.setSize(m_filter_size); - clear(); + m_filter.setSize(m_filter_size); + clear(); } -LSB_CountingBloomFilter::~LSB_CountingBloomFilter(){ +LSB_CountingBloomFilter::~LSB_CountingBloomFilter() +{ } -void LSB_CountingBloomFilter::clear() +void +LSB_CountingBloomFilter::clear() { - for (int i = 0; i < m_filter_size; i++) { - m_filter[i] = 0; - } + for (int i = 0; i < m_filter_size; i++) { + m_filter[i] = 0; + } } -void LSB_CountingBloomFilter::increment(const Address& addr) +void +LSB_CountingBloomFilter::increment(const Address& addr) { - int i = get_index(addr); - if (m_filter[i] < m_count); - m_filter[i] += 1; + int i = get_index(addr); + if (m_filter[i] < m_count) + m_filter[i] += 1; } -void LSB_CountingBloomFilter::decrement(const Address& addr) +void +LSB_CountingBloomFilter::decrement(const Address& addr) { - int i = get_index(addr); - if (m_filter[i] > 0) - m_filter[i] -= 1; + int i = get_index(addr); + if (m_filter[i] > 0) + m_filter[i] -= 1; } -void LSB_CountingBloomFilter::merge(AbstractBloomFilter * other_filter) +void +LSB_CountingBloomFilter::merge(AbstractBloomFilter * other_filter) { - // TODO + // TODO } -void LSB_CountingBloomFilter::set(const Address& addr) +void +LSB_CountingBloomFilter::set(const Address& addr) { - // TODO + // TODO } -void LSB_CountingBloomFilter::unset(const Address& addr) +void +LSB_CountingBloomFilter::unset(const Address& addr) { - // TODO + // TODO } -bool LSB_CountingBloomFilter::isSet(const Address& addr) +bool +LSB_CountingBloomFilter::isSet(const Address& addr) { - // TODO - return false; + // TODO + return false; } - -int LSB_CountingBloomFilter::getCount(const Address& addr) +int +LSB_CountingBloomFilter::getCount(const Address& addr) { - return m_filter[get_index(addr)]; + return m_filter[get_index(addr)]; } -int LSB_CountingBloomFilter::getTotalCount() +int +LSB_CountingBloomFilter::getTotalCount() { - int count = 0; + int count = 0; - for (int i = 0; i < m_filter_size; i++) { - count += m_filter[i]; - } - return count; + for (int i = 0; i < m_filter_size; i++) { + count += m_filter[i]; + } + return count; } -int LSB_CountingBloomFilter::getIndex(const Address& addr) +int +LSB_CountingBloomFilter::getIndex(const Address& addr) { - return get_index(addr); + return get_index(addr); } -void LSB_CountingBloomFilter::print(ostream& out) const +void +LSB_CountingBloomFilter::print(ostream& out) const { } -int LSB_CountingBloomFilter::readBit(const int index) { - return 0; - // TODO +int +LSB_CountingBloomFilter::readBit(const int index) +{ + return 0; + // TODO } -void LSB_CountingBloomFilter::writeBit(const int index, const int value) { - // TODO +void +LSB_CountingBloomFilter::writeBit(const int index, const int value) +{ + // TODO } -int LSB_CountingBloomFilter::get_index(const Address& addr) +int +LSB_CountingBloomFilter::get_index(const Address& addr) { - return addr.bitSelect( RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_filter_size_bits - 1); + return addr.bitSelect(RubySystem::getBlockSizeBits(), + RubySystem::getBlockSizeBits() + + m_filter_size_bits - 1); } diff --git a/src/mem/ruby/filters/LSB_CountingBloomFilter.hh b/src/mem/ruby/filters/LSB_CountingBloomFilter.hh index bfa2673fe..0d74c524a 100644 --- a/src/mem/ruby/filters/LSB_CountingBloomFilter.hh +++ b/src/mem/ruby/filters/LSB_CountingBloomFilter.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,55 +26,45 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * LSB_CountingBloomFilter.hh - * - * Description: - * - * - */ - -#ifndef LSB_COUNTING_BLOOM_FILTER_H -#define LSB_COUNTING_BLOOM_FILTER_H +#ifndef __MEM_RUBY_FILTERS_LSBCOUNTINGBLOOMFILTER_HH__ +#define __MEM_RUBY_FILTERS_LSBCOUNTINGBLOOMFILTER_HH__ #include "mem/gems_common/Map.hh" -#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/filters/AbstractBloomFilter.hh" -class LSB_CountingBloomFilter : public AbstractBloomFilter { -public: +class LSB_CountingBloomFilter : public AbstractBloomFilter +{ + public: + LSB_CountingBloomFilter(string config); + ~LSB_CountingBloomFilter(); - ~LSB_CountingBloomFilter(); - LSB_CountingBloomFilter(string config); + void clear(); + void increment(const Address& addr); + void decrement(const Address& addr); + void merge(AbstractBloomFilter * other_filter); + void set(const Address& addr); + void unset(const Address& addr); - void clear(); - void increment(const Address& addr); - void decrement(const Address& addr); - void merge(AbstractBloomFilter * other_filter); - void set(const Address& addr); - void unset(const Address& addr); + bool isSet(const Address& addr); + int getCount(const Address& addr); + int getTotalCount(); + int getIndex(const Address& addr); + int readBit(const int index); + void writeBit(const int index, const int value); - bool isSet(const Address& addr); - int getCount(const Address& addr); - int getTotalCount(); - int getIndex(const Address& addr); - int readBit(const int index); - void writeBit(const int index, const int value); + void print(ostream& out) const; - void print(ostream& out) const; + private: + int get_index(const Address& addr); -private: + Vector<int> m_filter; + int m_filter_size; + int m_filter_size_bits; - int get_index(const Address& addr); - - Vector<int> m_filter; - int m_filter_size; - int m_filter_size_bits; - - int m_count_bits; - int m_count; + int m_count_bits; + int m_count; }; - -#endif +#endif // __MEM_RUBY_FILTERS_LSBCOUNTINGBLOOMFILTER_HH__ diff --git a/src/mem/ruby/filters/MultiBitSelBloomFilter.cc b/src/mem/ruby/filters/MultiBitSelBloomFilter.cc index 844f80160..1fe316800 100644 --- a/src/mem/ruby/filters/MultiBitSelBloomFilter.cc +++ b/src/mem/ruby/filters/MultiBitSelBloomFilter.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,165 +26,173 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * NonCountingBloomFilter.cc - * - * Description: - * - * - */ - -#include "mem/ruby/filters/MultiBitSelBloomFilter.hh" #include "mem/gems_common/Map.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/filters/MultiBitSelBloomFilter.hh" MultiBitSelBloomFilter::MultiBitSelBloomFilter(string str) { + string tail(str); + string head = string_split(tail, '_'); - string tail(str); - string head = string_split(tail, '_'); - - // head contains filter size, tail contains bit offset from block number - m_filter_size = atoi(head.c_str()); + // head contains filter size, tail contains bit offset from block number + m_filter_size = atoi(head.c_str()); - head = string_split(tail, '_'); - m_num_hashes = atoi(head.c_str()); + head = string_split(tail, '_'); + m_num_hashes = atoi(head.c_str()); - head = string_split(tail, '_'); - m_skip_bits = atoi(head.c_str()); + head = string_split(tail, '_'); + m_skip_bits = atoi(head.c_str()); - if(tail == "Regular") { - isParallel = false; - } else if (tail == "Parallel") { - isParallel = true; - } else { - cout << "ERROR: Incorrect config string for MultiBitSel Bloom! :" << str << endl; - assert(0); - } + if(tail == "Regular") { + isParallel = false; + } else if (tail == "Parallel") { + isParallel = true; + } else { + cout << "ERROR: Incorrect config string for MultiBitSel Bloom! :" + << str << endl; + assert(0); + } - m_filter_size_bits = log_int(m_filter_size); + m_filter_size_bits = log_int(m_filter_size); - m_par_filter_size = m_filter_size/m_num_hashes; - m_par_filter_size_bits = log_int(m_par_filter_size); + m_par_filter_size = m_filter_size/m_num_hashes; + m_par_filter_size_bits = log_int(m_par_filter_size); - m_filter.setSize(m_filter_size); - clear(); + m_filter.setSize(m_filter_size); + clear(); } -MultiBitSelBloomFilter::~MultiBitSelBloomFilter(){ +MultiBitSelBloomFilter::~MultiBitSelBloomFilter() +{ } -void MultiBitSelBloomFilter::clear() +void +MultiBitSelBloomFilter::clear() { - for (int i = 0; i < m_filter_size; i++) { - m_filter[i] = 0; - } + for (int i = 0; i < m_filter_size; i++) { + m_filter[i] = 0; + } } -void MultiBitSelBloomFilter::increment(const Address& addr) +void +MultiBitSelBloomFilter::increment(const Address& addr) { - // Not used + // Not used } -void MultiBitSelBloomFilter::decrement(const Address& addr) +void +MultiBitSelBloomFilter::decrement(const Address& addr) { - // Not used + // Not used } -void MultiBitSelBloomFilter::merge(AbstractBloomFilter * other_filter){ - // assumes both filters are the same size! - MultiBitSelBloomFilter * temp = (MultiBitSelBloomFilter*) other_filter; - for(int i=0; i < m_filter_size; ++i){ - m_filter[i] |= (*temp)[i]; - } - +void +MultiBitSelBloomFilter::merge(AbstractBloomFilter *other_filter) +{ + // assumes both filters are the same size! + MultiBitSelBloomFilter * temp = (MultiBitSelBloomFilter*) other_filter; + for(int i = 0; i < m_filter_size; ++i){ + m_filter[i] |= (*temp)[i]; + } } -void MultiBitSelBloomFilter::set(const Address& addr) +void +MultiBitSelBloomFilter::set(const Address& addr) { - for (int i = 0; i < m_num_hashes; i++) { - int idx = get_index(addr, i); - m_filter[idx] = 1; - - //Profile hash value distribution - //g_system_ptr->getProfiler()->getXactProfiler()->profileHashValue(i, idx); //gem5:Arka for decomissioning of log_tm - } + for (int i = 0; i < m_num_hashes; i++) { + int idx = get_index(addr, i); + m_filter[idx] = 1; + } } -void MultiBitSelBloomFilter::unset(const Address& addr) +void +MultiBitSelBloomFilter::unset(const Address& addr) { - cout << "ERROR: Unset should never be called in a Bloom filter"; - assert(0); + cout << "ERROR: Unset should never be called in a Bloom filter"; + assert(0); } -bool MultiBitSelBloomFilter::isSet(const Address& addr) +bool +MultiBitSelBloomFilter::isSet(const Address& addr) { - bool res = true; + bool res = true; - for (int i=0; i < m_num_hashes; i++) { - int idx = get_index(addr, i); - res = res && m_filter[idx]; - } - return res; + for (int i=0; i < m_num_hashes; i++) { + int idx = get_index(addr, i); + res = res && m_filter[idx]; + } + return res; } - -int MultiBitSelBloomFilter::getCount(const Address& addr) +int +MultiBitSelBloomFilter::getCount(const Address& addr) { - return isSet(addr)? 1: 0; + return isSet(addr)? 1: 0; } -int MultiBitSelBloomFilter::getIndex(const Address& addr) +int +MultiBitSelBloomFilter::getIndex(const Address& addr) { - return 0; + return 0; } -int MultiBitSelBloomFilter::readBit(const int index) { - return 0; +int +MultiBitSelBloomFilter::readBit(const int index) +{ + return 0; } -void MultiBitSelBloomFilter::writeBit(const int index, const int value) { - +void +MultiBitSelBloomFilter::writeBit(const int index, const int value) +{ } -int MultiBitSelBloomFilter::getTotalCount() +int +MultiBitSelBloomFilter::getTotalCount() { - int count = 0; + int count = 0; - for (int i = 0; i < m_filter_size; i++) { - count += m_filter[i]; - } - return count; + for (int i = 0; i < m_filter_size; i++) { + count += m_filter[i]; + } + return count; } -void MultiBitSelBloomFilter::print(ostream& out) const +void +MultiBitSelBloomFilter::print(ostream& out) const { } -int MultiBitSelBloomFilter::get_index(const Address& addr, int i) +int +MultiBitSelBloomFilter::get_index(const Address& addr, int i) { - // m_skip_bits is used to perform BitSelect after skipping some bits. Used to simulate BitSel hashing on larger than cache-line granularities - uint64 x = (addr.getLineAddress()) >> m_skip_bits; - int y = hash_bitsel(x, i, m_num_hashes, 30, m_filter_size_bits); - //36-bit addresses, 6-bit cache lines - - if(isParallel) { - return (y % m_par_filter_size) + i*m_par_filter_size; - } else { - return y % m_filter_size; - } -} - - -int MultiBitSelBloomFilter::hash_bitsel(uint64 value, int index, int jump, int maxBits, int numBits) { - uint64 mask = 1; - int result = 0; - int bit, i; - - for(i = 0; i < numBits; i++) { - bit = (index + jump*i) % maxBits; - if (value & (mask << bit)) result += mask << i; - } - return result; + // m_skip_bits is used to perform BitSelect after skipping some + // bits. Used to simulate BitSel hashing on larger than cache-line + // granularities + uint64 x = (addr.getLineAddress()) >> m_skip_bits; + int y = hash_bitsel(x, i, m_num_hashes, 30, m_filter_size_bits); + //36-bit addresses, 6-bit cache lines + + if (isParallel) { + return (y % m_par_filter_size) + i*m_par_filter_size; + } else { + return y % m_filter_size; + } +} + +int +MultiBitSelBloomFilter::hash_bitsel(uint64 value, int index, int jump, + int maxBits, int numBits) +{ + uint64 mask = 1; + int result = 0; + int bit, i; + + for (i = 0; i < numBits; i++) { + bit = (index + jump*i) % maxBits; + if (value & (mask << bit)) result += mask << i; + } + return result; } diff --git a/src/mem/ruby/filters/MultiBitSelBloomFilter.hh b/src/mem/ruby/filters/MultiBitSelBloomFilter.hh index 360cbfdff..c3b441c20 100644 --- a/src/mem/ruby/filters/MultiBitSelBloomFilter.hh +++ b/src/mem/ruby/filters/MultiBitSelBloomFilter.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,70 +26,63 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * MultiBitSelBloomFilter.hh - * - * Description: - * - * - */ - -#ifndef MULTIBITSEL_BLOOM_FILTER_H -#define MULTIBITSEL_BLOOM_FILTER_H +#ifndef __MEM_RUBY_FILTERS_MULTIBITSELBLOOMFILTER_HH__ +#define __MEM_RUBY_FILTERS_MULTIBITSELBLOOMFILTER_HH__ #include "mem/gems_common/Map.hh" -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/System.hh" -#include "mem/ruby/profiler/Profiler.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/filters/AbstractBloomFilter.hh" +#include "mem/ruby/profiler/Profiler.hh" +#include "mem/ruby/system/System.hh" -class MultiBitSelBloomFilter : public AbstractBloomFilter { -public: - - ~MultiBitSelBloomFilter(); - MultiBitSelBloomFilter(string config); - - void clear(); - void increment(const Address& addr); - void decrement(const Address& addr); - void merge(AbstractBloomFilter * other_filter); - void set(const Address& addr); - void unset(const Address& addr); - - bool isSet(const Address& addr); - int getCount(const Address& addr); - int getTotalCount(); - void print(ostream& out) const; - - int getIndex(const Address& addr); - int readBit(const int index); - void writeBit(const int index, const int value); - - int operator[](const int index) const{ - return this->m_filter[index]; - } - -private: - - int get_index(const Address& addr, int hashNumber); - - int hash_bitsel(uint64 value, int index, int jump, int maxBits, int numBits); - - Vector<int> m_filter; - int m_filter_size; - int m_num_hashes; - int m_filter_size_bits; - int m_skip_bits; - - int m_par_filter_size; - int m_par_filter_size_bits; - - int m_count_bits; - int m_count; - - bool isParallel; - +class MultiBitSelBloomFilter : public AbstractBloomFilter +{ + public: + MultiBitSelBloomFilter(string config); + ~MultiBitSelBloomFilter(); + + void clear(); + void increment(const Address& addr); + void decrement(const Address& addr); + void merge(AbstractBloomFilter * other_filter); + void set(const Address& addr); + void unset(const Address& addr); + + bool isSet(const Address& addr); + int getCount(const Address& addr); + int getTotalCount(); + void print(ostream& out) const; + + int getIndex(const Address& addr); + int readBit(const int index); + void writeBit(const int index, const int value); + + int + operator[](const int index) const + { + return this->m_filter[index]; + } + + private: + int get_index(const Address& addr, int hashNumber); + + int hash_bitsel(uint64 value, int index, int jump, int maxBits, + int numBits); + + Vector<int> m_filter; + int m_filter_size; + int m_num_hashes; + int m_filter_size_bits; + int m_skip_bits; + + int m_par_filter_size; + int m_par_filter_size_bits; + + int m_count_bits; + int m_count; + + bool isParallel; }; -#endif +#endif // __MEM_RUBY_FILTERS_MULTIBITSELBLOOMFILTER_HH__ diff --git a/src/mem/ruby/filters/MultiGrainBloomFilter.cc b/src/mem/ruby/filters/MultiGrainBloomFilter.cc index 108168db3..543c4312a 100644 --- a/src/mem/ruby/filters/MultiGrainBloomFilter.cc +++ b/src/mem/ruby/filters/MultiGrainBloomFilter.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,142 +26,156 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * MultiGrainBloomFilter.cc - * - * Description: - * - * - */ - -#include "mem/ruby/filters/MultiGrainBloomFilter.hh" #include "mem/gems_common/Map.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/filters/MultiGrainBloomFilter.hh" MultiGrainBloomFilter::MultiGrainBloomFilter(string str) { - string tail(str); + string tail(str); - // split into the 2 filter sizes - string head = string_split(tail, '_'); + // split into the 2 filter sizes + string head = string_split(tail, '_'); - // head contains size of 1st bloom filter, tail contains size of 2nd bloom filter + // head contains size of 1st bloom filter, tail contains size of + // 2nd bloom filter - m_filter_size = atoi(head.c_str()); - m_filter_size_bits = log_int(m_filter_size); + m_filter_size = atoi(head.c_str()); + m_filter_size_bits = log_int(m_filter_size); - m_page_filter_size = atoi(tail.c_str()); - m_page_filter_size_bits = log_int(m_page_filter_size); + m_page_filter_size = atoi(tail.c_str()); + m_page_filter_size_bits = log_int(m_page_filter_size); - m_filter.setSize(m_filter_size); - m_page_filter.setSize(m_page_filter_size); - clear(); + m_filter.setSize(m_filter_size); + m_page_filter.setSize(m_page_filter_size); + clear(); } -MultiGrainBloomFilter::~MultiGrainBloomFilter(){ +MultiGrainBloomFilter::~MultiGrainBloomFilter() +{ } -void MultiGrainBloomFilter::clear() +void +MultiGrainBloomFilter::clear() { - for (int i = 0; i < m_filter_size; i++) { - m_filter[i] = 0; - } - for(int i=0; i < m_page_filter_size; ++i){ - m_page_filter[i] = 0; - } + for (int i = 0; i < m_filter_size; i++) { + m_filter[i] = 0; + } + for(int i=0; i < m_page_filter_size; ++i){ + m_page_filter[i] = 0; + } } -void MultiGrainBloomFilter::increment(const Address& addr) +void +MultiGrainBloomFilter::increment(const Address& addr) { - // Not used + // Not used } -void MultiGrainBloomFilter::decrement(const Address& addr) +void +MultiGrainBloomFilter::decrement(const Address& addr) { - // Not used + // Not used } -void MultiGrainBloomFilter::merge(AbstractBloomFilter * other_filter) +void +MultiGrainBloomFilter::merge(AbstractBloomFilter *other_filter) { - // TODO + // TODO } -void MultiGrainBloomFilter::set(const Address& addr) +void +MultiGrainBloomFilter::set(const Address& addr) { - int i = get_block_index(addr); - assert(i < m_filter_size); - assert(get_page_index(addr) < m_page_filter_size); - m_filter[i] = 1; - m_page_filter[i] = 1; + int i = get_block_index(addr); + assert(i < m_filter_size); + assert(get_page_index(addr) < m_page_filter_size); + m_filter[i] = 1; + m_page_filter[i] = 1; } -void MultiGrainBloomFilter::unset(const Address& addr) +void +MultiGrainBloomFilter::unset(const Address& addr) { - // not used + // not used } -bool MultiGrainBloomFilter::isSet(const Address& addr) +bool +MultiGrainBloomFilter::isSet(const Address& addr) { - int i = get_block_index(addr); - assert(i < m_filter_size); - assert(get_page_index(addr) < m_page_filter_size); - // we have to have both indices set - return (m_filter[i] && m_page_filter[i]); + int i = get_block_index(addr); + assert(i < m_filter_size); + assert(get_page_index(addr) < m_page_filter_size); + // we have to have both indices set + return (m_filter[i] && m_page_filter[i]); } -int MultiGrainBloomFilter::getCount(const Address& addr) +int +MultiGrainBloomFilter::getCount(const Address& addr) { - // not used - return 0; + // not used + return 0; } -int MultiGrainBloomFilter::getTotalCount() +int +MultiGrainBloomFilter::getTotalCount() { - int count = 0; + int count = 0; - for (int i = 0; i < m_filter_size; i++) { - count += m_filter[i]; - } + for (int i = 0; i < m_filter_size; i++) { + count += m_filter[i]; + } - for(int i=0; i < m_page_filter_size; ++i){ - count += m_page_filter[i] = 0; - } + for(int i=0; i < m_page_filter_size; ++i) { + count += m_page_filter[i] = 0; + } - return count; + return count; } -int MultiGrainBloomFilter::getIndex(const Address& addr) +int +MultiGrainBloomFilter::getIndex(const Address& addr) { - return 0; - // TODO + return 0; + // TODO } -int MultiGrainBloomFilter::readBit(const int index) { - return 0; - // TODO +int +MultiGrainBloomFilter::readBit(const int index) +{ + return 0; + // TODO } -void MultiGrainBloomFilter::writeBit(const int index, const int value) { - // TODO +void +MultiGrainBloomFilter::writeBit(const int index, const int value) +{ + // TODO } -void MultiGrainBloomFilter::print(ostream& out) const +void +MultiGrainBloomFilter::print(ostream& out) const { } -int MultiGrainBloomFilter::get_block_index(const Address& addr) +int +MultiGrainBloomFilter::get_block_index(const Address& addr) { - // grap a chunk of bits after byte offset - return addr.bitSelect( RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_filter_size_bits - 1); + // grap a chunk of bits after byte offset + return addr.bitSelect(RubySystem::getBlockSizeBits(), + RubySystem::getBlockSizeBits() + + m_filter_size_bits - 1); } -int MultiGrainBloomFilter::get_page_index(const Address & addr) +int +MultiGrainBloomFilter::get_page_index(const Address & addr) { - // grap a chunk of bits after first chunk - return addr.bitSelect( RubySystem::getBlockSizeBits() + m_filter_size_bits - 1, - RubySystem::getBlockSizeBits() + m_filter_size_bits - 1 + m_page_filter_size_bits - 1); + int bits = RubySystem::getBlockSizeBits() + m_filter_size_bits - 1; + + // grap a chunk of bits after first chunk + return addr.bitSelect(bits, bits + m_page_filter_size_bits - 1); } diff --git a/src/mem/ruby/filters/MultiGrainBloomFilter.hh b/src/mem/ruby/filters/MultiGrainBloomFilter.hh index 4e9bc70a2..4681e2806 100644 --- a/src/mem/ruby/filters/MultiGrainBloomFilter.hh +++ b/src/mem/ruby/filters/MultiGrainBloomFilter.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,61 +26,51 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * MultiGrainBloomFilter.hh - * - * Description: - * - * - */ - -#ifndef MULTIGRAIN_BLOOM_FILTER_H -#define MULTIGRAIN_BLOOM_FILTER_H +#ifndef __MEM_RUBY_FILTERS_MULTIGRAINBLOOMFILTER_HH__ +#define __MEM_RUBY_FILTERS_MULTIGRAINBLOOMFILTER_HH__ #include "mem/gems_common/Map.hh" -#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/filters/AbstractBloomFilter.hh" -class MultiGrainBloomFilter : public AbstractBloomFilter { -public: +class MultiGrainBloomFilter : public AbstractBloomFilter +{ + public: + MultiGrainBloomFilter(string str); + ~MultiGrainBloomFilter(); - ~MultiGrainBloomFilter(); - MultiGrainBloomFilter(string str); + void clear(); + void increment(const Address& addr); + void decrement(const Address& addr); + void merge(AbstractBloomFilter * other_filter); + void set(const Address& addr); + void unset(const Address& addr); - void clear(); - void increment(const Address& addr); - void decrement(const Address& addr); - void merge(AbstractBloomFilter * other_filter); - void set(const Address& addr); - void unset(const Address& addr); + bool isSet(const Address& addr); + int getCount(const Address& addr); + int getTotalCount(); + int getIndex(const Address& addr); + int readBit(const int index); + void writeBit(const int index, const int value); - bool isSet(const Address& addr); - int getCount(const Address& addr); - int getTotalCount(); - int getIndex(const Address& addr); - int readBit(const int index); - void writeBit(const int index, const int value); + void print(ostream& out) const; - void print(ostream& out) const; + private: + int get_block_index(const Address& addr); + int get_page_index(const Address & addr); -private: + // The block filter + Vector<int> m_filter; + int m_filter_size; + int m_filter_size_bits; + // The page number filter + Vector<int> m_page_filter; + int m_page_filter_size; + int m_page_filter_size_bits; - int get_block_index(const Address& addr); - int get_page_index(const Address & addr); - - // The block filter - Vector<int> m_filter; - int m_filter_size; - int m_filter_size_bits; - // The page number filter - Vector<int> m_page_filter; - int m_page_filter_size; - int m_page_filter_size_bits; - - int m_count_bits; - int m_count; + int m_count_bits; + int m_count; }; - -#endif +#endif // __MEM_RUBY_FILTERS_MULTIGRAINBLOOMFILTER_HH__ diff --git a/src/mem/ruby/filters/NonCountingBloomFilter.cc b/src/mem/ruby/filters/NonCountingBloomFilter.cc index 738945105..06c069c7e 100644 --- a/src/mem/ruby/filters/NonCountingBloomFilter.cc +++ b/src/mem/ruby/filters/NonCountingBloomFilter.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,118 +26,126 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * NonCountingBloomFilter.cc - * - * Description: - * - * - */ - -#include "mem/ruby/filters/NonCountingBloomFilter.hh" #include "mem/gems_common/Map.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/filters/NonCountingBloomFilter.hh" NonCountingBloomFilter::NonCountingBloomFilter(string str) { - string tail(str); - string head = string_split(tail, '_'); + string tail(str); + string head = string_split(tail, '_'); - // head contains filter size, tail contains bit offset from block number - m_filter_size = atoi(head.c_str()); - m_offset = atoi(tail.c_str()); - m_filter_size_bits = log_int(m_filter_size); + // head contains filter size, tail contains bit offset from block number + m_filter_size = atoi(head.c_str()); + m_offset = atoi(tail.c_str()); + m_filter_size_bits = log_int(m_filter_size); - - m_filter.setSize(m_filter_size); - clear(); + m_filter.setSize(m_filter_size); + clear(); } -NonCountingBloomFilter::~NonCountingBloomFilter(){ +NonCountingBloomFilter::~NonCountingBloomFilter() +{ } -void NonCountingBloomFilter::clear() +void +NonCountingBloomFilter::clear() { - for (int i = 0; i < m_filter_size; i++) { - m_filter[i] = 0; - } + for (int i = 0; i < m_filter_size; i++) { + m_filter[i] = 0; + } } -void NonCountingBloomFilter::increment(const Address& addr) +void +NonCountingBloomFilter::increment(const Address& addr) { - // Not used + // Not used } - -void NonCountingBloomFilter::decrement(const Address& addr) +void +NonCountingBloomFilter::decrement(const Address& addr) { - // Not used + // Not used } -void NonCountingBloomFilter::merge(AbstractBloomFilter * other_filter){ - // assumes both filters are the same size! - NonCountingBloomFilter * temp = (NonCountingBloomFilter*) other_filter; - for(int i=0; i < m_filter_size; ++i){ - m_filter[i] |= (*temp)[i]; - } - +void +NonCountingBloomFilter::merge(AbstractBloomFilter *other_filter) +{ + // assumes both filters are the same size! + NonCountingBloomFilter * temp = (NonCountingBloomFilter*) other_filter; + for(int i = 0; i < m_filter_size; ++i){ + m_filter[i] |= (*temp)[i]; + } } -void NonCountingBloomFilter::set(const Address& addr) +void +NonCountingBloomFilter::set(const Address& addr) { - int i = get_index(addr); - m_filter[i] = 1; + int i = get_index(addr); + m_filter[i] = 1; } -void NonCountingBloomFilter::unset(const Address& addr) +void +NonCountingBloomFilter::unset(const Address& addr) { - int i = get_index(addr); - m_filter[i] = 0; + int i = get_index(addr); + m_filter[i] = 0; } -bool NonCountingBloomFilter::isSet(const Address& addr) +bool +NonCountingBloomFilter::isSet(const Address& addr) { - int i = get_index(addr); - return (m_filter[i]); + int i = get_index(addr); + return (m_filter[i]); } -int NonCountingBloomFilter::getCount(const Address& addr) +int +NonCountingBloomFilter::getCount(const Address& addr) { - return m_filter[get_index(addr)]; + return m_filter[get_index(addr)]; } -int NonCountingBloomFilter::getTotalCount() +int +NonCountingBloomFilter::getTotalCount() { - int count = 0; + int count = 0; - for (int i = 0; i < m_filter_size; i++) { - count += m_filter[i]; - } - return count; + for (int i = 0; i < m_filter_size; i++) { + count += m_filter[i]; + } + return count; } -void NonCountingBloomFilter::print(ostream& out) const +void +NonCountingBloomFilter::print(ostream& out) const { } -int NonCountingBloomFilter::getIndex(const Address& addr) +int +NonCountingBloomFilter::getIndex(const Address& addr) { - return get_index(addr); + return get_index(addr); } -int NonCountingBloomFilter::readBit(const int index) { - return m_filter[index]; +int +NonCountingBloomFilter::readBit(const int index) +{ + return m_filter[index]; } -void NonCountingBloomFilter::writeBit(const int index, const int value) { - m_filter[index] = value; +void +NonCountingBloomFilter::writeBit(const int index, const int value) +{ + m_filter[index] = value; } -int NonCountingBloomFilter::get_index(const Address& addr) +int +NonCountingBloomFilter::get_index(const Address& addr) { - return addr.bitSelect( RubySystem::getBlockSizeBits() + m_offset, - RubySystem::getBlockSizeBits() + m_offset + m_filter_size_bits - 1); + return addr.bitSelect(RubySystem::getBlockSizeBits() + m_offset, + RubySystem::getBlockSizeBits() + m_offset + + m_filter_size_bits - 1); } diff --git a/src/mem/ruby/filters/NonCountingBloomFilter.hh b/src/mem/ruby/filters/NonCountingBloomFilter.hh index fd23fbdf7..bec645952 100644 --- a/src/mem/ruby/filters/NonCountingBloomFilter.hh +++ b/src/mem/ruby/filters/NonCountingBloomFilter.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,61 +26,53 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * NonCountingBloomFilter.hh - * - * Description: - * - * - */ - -#ifndef NONCOUNTING_BLOOM_FILTER_H -#define NONCOUNTING_BLOOM_FILTER_H +#ifndef __MEM_RUBY_FILTERS_NONCOUNTINGBLOOMFILTER_HH__ +#define __MEM_RUBY_FILTERS_NONCOUNTINGBLOOMFILTER_HH__ #include "mem/gems_common/Map.hh" -#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/filters/AbstractBloomFilter.hh" -class NonCountingBloomFilter : public AbstractBloomFilter { -public: - - ~NonCountingBloomFilter(); - NonCountingBloomFilter(string config); - - void clear(); - void increment(const Address& addr); - void decrement(const Address& addr); - void merge(AbstractBloomFilter * other_filter); - void set(const Address& addr); - void unset(const Address& addr); - - bool isSet(const Address& addr); - int getCount(const Address& addr); - int getTotalCount(); - - int getIndex(const Address& addr); - int readBit(const int index); - void writeBit(const int index, const int value); - - void print(ostream& out) const; - - int operator[](const int index) const{ - return this->m_filter[index]; - } - -private: - - int get_index(const Address& addr); - - Vector<int> m_filter; - int m_filter_size; - int m_offset; - int m_filter_size_bits; - - int m_count_bits; - int m_count; +class NonCountingBloomFilter : public AbstractBloomFilter +{ + public: + NonCountingBloomFilter(string config); + ~NonCountingBloomFilter(); + + void clear(); + void increment(const Address& addr); + void decrement(const Address& addr); + void merge(AbstractBloomFilter * other_filter); + void set(const Address& addr); + void unset(const Address& addr); + + bool isSet(const Address& addr); + int getCount(const Address& addr); + int getTotalCount(); + + int getIndex(const Address& addr); + int readBit(const int index); + void writeBit(const int index, const int value); + + void print(ostream& out) const; + + int + operator[](const int index) const + { + return this->m_filter[index]; + } + + private: + int get_index(const Address& addr); + + Vector<int> m_filter; + int m_filter_size; + int m_offset; + int m_filter_size_bits; + + int m_count_bits; + int m_count; }; - -#endif +#endif // __MEM_RUBY_FILTERS_NONCOUNTINGBLOOMFILTER_HH__ diff --git a/src/mem/ruby/libruby.cc b/src/mem/ruby/libruby.cc index 16b2bf346..de120036b 100644 --- a/src/mem/ruby/libruby.cc +++ b/src/mem/ruby/libruby.cc @@ -30,97 +30,101 @@ #include <algorithm> #include "config/gems_root.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/ruby/libruby_internal.hh" +#include "mem/ruby/recorder/Tracer.hh" +#include "mem/ruby/system/MemoryVector.hh" #include "mem/ruby/system/RubyPort.hh" #include "mem/ruby/system/System.hh" -#include "mem/ruby/eventqueue/RubyEventQueue.hh" -#include "mem/ruby/system/MemoryVector.hh" -#include "mem/ruby/common/Address.hh" -#include "mem/ruby/recorder/Tracer.hh" -string RubyRequestType_to_string(const RubyRequestType& obj) -{ - switch(obj) { - case RubyRequestType_IFETCH: - return "IFETCH"; - case RubyRequestType_LD: - return "LD"; - case RubyRequestType_ST: - return "ST"; - case RubyRequestType_Locked_Read: - return "Locked_Read"; - case RubyRequestType_Locked_Write: - return "Locked_Write"; - case RubyRequestType_RMW_Read: - return "RMW_Read"; - case RubyRequestType_RMW_Write: - return "RMW_Write"; - case RubyRequestType_NULL: - default: - assert(0); - return ""; - } +string +RubyRequestType_to_string(const RubyRequestType& obj) +{ + switch(obj) { + case RubyRequestType_IFETCH: + return "IFETCH"; + case RubyRequestType_LD: + return "LD"; + case RubyRequestType_ST: + return "ST"; + case RubyRequestType_Locked_Read: + return "Locked_Read"; + case RubyRequestType_Locked_Write: + return "Locked_Write"; + case RubyRequestType_RMW_Read: + return "RMW_Read"; + case RubyRequestType_RMW_Write: + return "RMW_Write"; + case RubyRequestType_NULL: + default: + assert(0); + return ""; + } } -RubyRequestType string_to_RubyRequestType(std::string str) +RubyRequestType +string_to_RubyRequestType(std::string str) { - if (str == "IFETCH") - return RubyRequestType_IFETCH; - else if (str == "LD") - return RubyRequestType_LD; - else if (str == "ST") - return RubyRequestType_ST; - else if (str == "Locked_Read") - return RubyRequestType_Locked_Read; - else if (str == "Locked_Write") - return RubyRequestType_Locked_Write; - else if (str == "RMW_Read") - return RubyRequestType_RMW_Read; - else if (str == "RMW_Write") - return RubyRequestType_RMW_Write; - else - assert(0); - return RubyRequestType_NULL; + if (str == "IFETCH") + return RubyRequestType_IFETCH; + else if (str == "LD") + return RubyRequestType_LD; + else if (str == "ST") + return RubyRequestType_ST; + else if (str == "Locked_Read") + return RubyRequestType_Locked_Read; + else if (str == "Locked_Write") + return RubyRequestType_Locked_Write; + else if (str == "RMW_Read") + return RubyRequestType_RMW_Read; + else if (str == "RMW_Write") + return RubyRequestType_RMW_Write; + else + assert(0); + return RubyRequestType_NULL; } -ostream& operator<<(ostream& out, const RubyRequestType& obj) +ostream& +operator<<(ostream& out, const RubyRequestType& obj) { - out << RubyRequestType_to_string(obj); - out << flush; - return out; + out << RubyRequestType_to_string(obj); + out << flush; + return out; } -ostream& operator<<(std::ostream& out, const RubyRequest& obj) +ostream& +operator<<(std::ostream& out, const RubyRequest& obj) { - out << hex << "0x" << obj.paddr << " data: 0x" << flush; - for (int i = 0; i < obj.len; i++) { - out << (int)obj.data[i]; - } - out << dec << " type: " << RubyRequestType_to_string(obj.type) << endl; - return out; + out << hex << "0x" << obj.paddr << " data: 0x" << flush; + for (int i = 0; i < obj.len; i++) { + out << (int)obj.data[i]; + } + out << dec << " type: " << RubyRequestType_to_string(obj.type) << endl; + return out; } -vector<string> tokenizeString(string str, string delims) +vector<string> +tokenizeString(string str, string delims) { - vector<string> tokens; - char* pch; - char* tmp; - const char* c_delims = delims.c_str(); - tmp = new char[str.length()+1]; - strcpy(tmp, str.c_str()); - pch = strtok(tmp, c_delims); - while (pch != NULL) { - string tmp_str(pch); - if (tmp_str == "null") tmp_str = ""; - tokens.push_back(tmp_str); + vector<string> tokens; + char* pch; + char* tmp; + const char* c_delims = delims.c_str(); + tmp = new char[str.length()+1]; + strcpy(tmp, str.c_str()); + pch = strtok(tmp, c_delims); + while (pch != NULL) { + string tmp_str(pch); + if (tmp_str == "null") tmp_str = ""; + tokens.push_back(tmp_str); - pch = strtok(NULL, c_delims); - } - delete [] tmp; - return tokens; + pch = strtok(NULL, c_delims); + } + delete [] tmp; + return tokens; } - /* * The current state of M5/Ruby integration breaks the libruby * interface. This code is ifdef'd out for now so that we can move @@ -129,41 +133,44 @@ vector<string> tokenizeString(string str, string delims) * later date. */ #if 0 -void libruby_init(const char* cfg_filename) -{ - ifstream cfg_output(cfg_filename); - - vector<RubyObjConf> * sys_conf = new vector<RubyObjConf>; - - string line; - getline(cfg_output, line) ; - while ( !cfg_output.eof() ) { - vector<string> tokens = tokenizeString(line, " "); - assert(tokens.size() >= 2); - vector<string> argv; - for (size_t i=2; i<tokens.size(); i++) { - std::replace(tokens[i].begin(), tokens[i].end(), '%', ' '); - std::replace(tokens[i].begin(), tokens[i].end(), '#', '\n'); - argv.push_back(tokens[i]); +void +libruby_init(const char* cfg_filename) +{ + ifstream cfg_output(cfg_filename); + + vector<RubyObjConf> * sys_conf = new vector<RubyObjConf>; + + string line; + getline(cfg_output, line) ; + while ( !cfg_output.eof() ) { + vector<string> tokens = tokenizeString(line, " "); + assert(tokens.size() >= 2); + vector<string> argv; + for (size_t i=2; i<tokens.size(); i++) { + std::replace(tokens[i].begin(), tokens[i].end(), '%', ' '); + std::replace(tokens[i].begin(), tokens[i].end(), '#', '\n'); + argv.push_back(tokens[i]); + } + sys_conf->push_back(RubyObjConf(tokens[0], tokens[1], argv)); + tokens.clear(); + argv.clear(); + getline(cfg_output, line); } - sys_conf->push_back(RubyObjConf(tokens[0], tokens[1], argv)); - tokens.clear(); - argv.clear(); - getline(cfg_output, line); - } - RubySystem::create(*sys_conf); - delete sys_conf; + RubySystem::create(*sys_conf); + delete sys_conf; } #endif -RubyPortHandle libruby_get_port(const char* port_name, void (*hit_callback)(int64_t access_id)) +RubyPortHandle +libruby_get_port(const char* port_name, + void (*hit_callback)(int64_t access_id)) { - // - // Fix me: Hit callback is now a non-static member function pointer of - // RubyPort and cannot be set to an arbitrary global function - // - return NULL;//static_cast<RubyPortHandle>(RubySystem::getPort(port_name, hit_callback)); + // + // Fix me: Hit callback is now a non-static member function pointer of + // RubyPort and cannot be set to an arbitrary global function + // + return NULL;//static_cast<RubyPortHandle>(RubySystem::getPort(port_name, hit_callback)); } RubyPortHandle libruby_get_port_by_name(const char* port_name) @@ -175,17 +182,20 @@ RubyPortHandle libruby_get_port_by_name(const char* port_name) return NULL;//static_cast<RubyPortHandle>(RubySystem::getPortOnly(port_name)); } -void libruby_write_ram(uint64_t paddr, uint8_t* data, int len) +void +libruby_write_ram(uint64_t paddr, uint8_t* data, int len) { - RubySystem::getMemoryVector()->write(Address(paddr), data, len); + RubySystem::getMemoryVector()->write(Address(paddr), data, len); } -void libruby_read_ram(uint64_t paddr, uint8_t* data, int len) +void +libruby_read_ram(uint64_t paddr, uint8_t* data, int len) { - RubySystem::getMemoryVector()->read(Address(paddr), data, len); + RubySystem::getMemoryVector()->read(Address(paddr), data, len); } -int64_t libruby_issue_request(RubyPortHandle p, struct RubyRequest request) +int64_t +libruby_issue_request(RubyPortHandle p, struct RubyRequest request) { // // Fix me: Ports should now be accessed using the python configuration @@ -194,45 +204,58 @@ int64_t libruby_issue_request(RubyPortHandle p, struct RubyRequest request) return 0;//return static_cast<RubyPort*>(p)->makeRequest(request); } -int libruby_tick(int n) +int +libruby_tick(int n) { - RubySystem::getEventQueue()->triggerEvents(RubySystem::getEventQueue()->getTime() + n); - return 0; + RubyEventQueue *eventq = RubySystem::getEventQueue(); + eventq->triggerEvents(eventq->getTime() + n); + return 0; } -void libruby_destroy() +void +libruby_destroy() { } -const char* libruby_last_error() +const char* +libruby_last_error() { - return ""; + return ""; } -void libruby_print_config(std::ostream & out) +void +libruby_print_config(std::ostream & out) { - RubySystem::printConfig(out); + RubySystem::printConfig(out); } -void libruby_print_stats(std::ostream & out) +void +libruby_print_stats(std::ostream & out) { - RubySystem::printStats(out); + RubySystem::printStats(out); } -void libruby_playback_trace(char * trace_filename) +void +libruby_playback_trace(char * trace_filename) { - RubySystem::getTracer()->playbackTrace(trace_filename); + RubySystem::getTracer()->playbackTrace(trace_filename); } -void libruby_start_tracing(char * record_filename) { - // start the trace - RubySystem::getTracer()->startTrace(record_filename); +void +libruby_start_tracing(char * record_filename) +{ + // start the trace + RubySystem::getTracer()->startTrace(record_filename); } -void libruby_stop_tracing() { - // start the trace - RubySystem::getTracer()->stopTrace(); +void +libruby_stop_tracing() +{ + // start the trace + RubySystem::getTracer()->stopTrace(); } -uint64_t libruby_get_time() { - return RubySystem::getCycleCount(0); +uint64_t +libruby_get_time() +{ + return RubySystem::getCycleCount(0); } diff --git a/src/mem/ruby/libruby.hh b/src/mem/ruby/libruby.hh index e22859818..6d83c3f08 100644 --- a/src/mem/ruby/libruby.hh +++ b/src/mem/ruby/libruby.hh @@ -26,11 +26,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LIBRUBY_H -#define LIBRUBY_H +#ifndef __MEM_RUBY_LIBRUBY_HH__ +#define __MEM_RUBY_LIBRUBY_HH__ -#include <stdint.h> #include <ostream> + +#include "base/types.hh" #include "mem/packet.hh" typedef void* RubyPortHandle; @@ -52,34 +53,35 @@ enum RubyAccessMode { RubyAccessMode_Device }; -struct RubyRequest { - uint64_t paddr; - uint8_t* data; - int len; - uint64_t pc; - RubyRequestType type; - RubyAccessMode access_mode; - PacketPtr pkt; - unsigned proc_id; - - RubyRequest() {} - RubyRequest(uint64_t _paddr, - uint8_t* _data, - int _len, - uint64_t _pc, - RubyRequestType _type, - RubyAccessMode _access_mode, - PacketPtr _pkt, - unsigned _proc_id = 100) - : paddr(_paddr), - data(_data), - len(_len), - pc(_pc), - type(_type), - access_mode(_access_mode), - pkt(_pkt), - proc_id(_proc_id) - {} +struct RubyRequest +{ + uint64_t paddr; + uint8_t* data; + int len; + uint64_t pc; + RubyRequestType type; + RubyAccessMode access_mode; + PacketPtr pkt; + unsigned proc_id; + + RubyRequest() {} + RubyRequest(uint64_t _paddr, + uint8_t* _data, + int _len, + uint64_t _pc, + RubyRequestType _type, + RubyAccessMode _access_mode, + PacketPtr _pkt, + unsigned _proc_id = 100) + : paddr(_paddr), + data(_data), + len(_len), + pc(_pc), + type(_type), + access_mode(_access_mode), + pkt(_pkt), + proc_id(_proc_id) + {} }; std::ostream& operator<<(std::ostream& out, const RubyRequest& obj); @@ -90,7 +92,8 @@ std::ostream& operator<<(std::ostream& out, const RubyRequest& obj); void libruby_init(const char* cfg_file); /** - * Tear down a configured system. Must be invoked after a call to libruby_init. + * Tear down a configured system. Must be invoked after a call to + * libruby_init. */ void libruby_destroy(); @@ -105,7 +108,8 @@ const char* libruby_last_error(); * this port to use when a request completes. Only one handle to a * port is allowed at a time. */ -RubyPortHandle libruby_get_port(const char* name, void (*hit_callback)(int64_t access_id)); +RubyPortHandle libruby_get_port(const char* name, + void (*hit_callback)(int64_t access_id)); /** * Retrieve a handle to a RubyPort object, identified by name in the @@ -113,7 +117,6 @@ RubyPortHandle libruby_get_port(const char* name, void (*hit_callback)(int64_t a */ RubyPortHandle libruby_get_port_by_name(const char* name); - /** * issue_request returns a unique access_id to identify the ruby * transaction. This access_id is later returned to the caller via @@ -126,14 +129,14 @@ int64_t libruby_issue_request(RubyPortHandle p, struct RubyRequest request); * ignores caches, and should be considered incoherent after * simulation starts. */ -void libruby_write_ram(uint64_t paddr, uint8_t * data, int len); +void libruby_write_ram(uint64_t paddr, uint8_t *data, int len); /** * reads data directory from Ruby's data array. Note that this * ignores caches, and should be considered incoherent after * simulation starts */ -void libruby_read_ram(uint64_t paddr, uint8_t * data, int len); +void libruby_read_ram(uint64_t paddr, uint8_t *data, int len); /** * tick the system n cycles. Eventually, will return the number of @@ -144,22 +147,22 @@ int libruby_tick(int n); /** * self explainitory */ -void libruby_print_config(std::ostream & out); +void libruby_print_config(std::ostream &out); /** * self explainitory */ -void libruby_print_stats(std::ostream & out); +void libruby_print_stats(std::ostream &out); /** * does not return until done */ -void libruby_playback_trace(char * trace_filename); +void libruby_playback_trace(char *trace_filename); /* * enables the tracer and opens the trace file */ -void libruby_start_tracing(char * record_filename); +void libruby_start_tracing(char *record_filename); /* * closes the trace file @@ -170,4 +173,5 @@ void libruby_stop_tracing(); * get time */ uint64_t libruby_get_time(); -#endif + +#endif // __MEM_RUBY_LIBRUBY_HH__ diff --git a/src/mem/ruby/libruby_internal.hh b/src/mem/ruby/libruby_internal.hh index 9e821ba7c..c64814051 100644 --- a/src/mem/ruby/libruby_internal.hh +++ b/src/mem/ruby/libruby_internal.hh @@ -26,16 +26,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LIBRUBY_INTERNAL_H -#define LIBRUBY_INTERNAL_H - -#include "mem/ruby/libruby.hh" +#ifndef __MEM_RUBY_LIBRUBY_INTERNAL_HH__ +#define __MEM_RUBY_LIBRUBY_INTERNAL_HH__ #include <ostream> #include <string> +#include "mem/ruby/libruby.hh" + std::string RubyRequestType_to_string(const RubyRequestType& obj); RubyRequestType string_to_RubyRequestType(std::string); std::ostream& operator<<(std::ostream& out, const RubyRequestType& obj); -#endif +#endif // __MEM_RUBY_LIBRUBY_INTERNAL_HH__ diff --git a/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc b/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc index 83039a9b0..3d8972c40 100644 --- a/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc +++ b/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,21 +26,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - * - * Description: See AbstractCacheEntry.hh - * - */ - #include "mem/ruby/slicc_interface/AbstractCacheEntry.hh" -AbstractCacheEntry::AbstractCacheEntry() { - m_Address.setAddress(0); - m_Permission = AccessPermission_NotPresent; +AbstractCacheEntry::AbstractCacheEntry() +{ + m_Address.setAddress(0); + m_Permission = AccessPermission_NotPresent; } -// still need to define destructor for subclasses -AbstractCacheEntry::~AbstractCacheEntry() { +AbstractCacheEntry::~AbstractCacheEntry() +{ } diff --git a/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh b/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh index b98e1fa07..223bc6fc8 100644 --- a/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh +++ b/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -28,49 +27,39 @@ */ /* - * $Id$ - * - * Description: Common base class for a machine node. - * + * Common base class for a machine node. */ -#ifndef AbstractCacheEntry_H -#define AbstractCacheEntry_H +#ifndef __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCACHEENTRY_HH__ +#define __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCACHEENTRY_HH__ -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/common/Address.hh" #include "mem/protocol/AccessPermission.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/slicc_interface/AbstractEntry.hh" class DataBlock; -class AbstractCacheEntry : public AbstractEntry { -public: - // Constructors - AbstractCacheEntry(); - - // Destructor, prevent it from instantiation - virtual ~AbstractCacheEntry() = 0; +class AbstractCacheEntry : public AbstractEntry +{ + public: + AbstractCacheEntry(); + virtual ~AbstractCacheEntry() = 0; - // Data Members (m_ prefix) - Address m_Address; // Address of this block, required by CacheMemory - Time m_LastRef; // Last time this block was referenced, required by CacheMemory - AccessPermission m_Permission; // Access permission for this block, required by CacheMemory + Address m_Address; // Address of this block, required by CacheMemory + Time m_LastRef; // Last time this block was referenced, required + // by CacheMemory + AccessPermission m_Permission; // Access permission for this + // block, required by CacheMemory }; -// Output operator declaration -ostream& operator<<(ostream& out, const AbstractCacheEntry& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const AbstractCacheEntry& obj) +inline ostream& +operator<<(ostream& out, const AbstractCacheEntry& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -#endif //AbstractCacheEntry_H +#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCACHEENTRY_HH__ diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index 390b7f730..facaf2adf 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ABSTRACTCONTROLLER_H -#define ABSTRACTCONTROLLER_H +#ifndef __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__ +#define __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__ #include "sim/sim_object.hh" #include "params/RubyController.hh" @@ -40,29 +40,30 @@ class MessageBuffer; class Network; -class AbstractController : public SimObject, public Consumer { -public: +class AbstractController : public SimObject, public Consumer +{ + public: typedef RubyControllerParams Params; AbstractController(const Params *p) : SimObject(p) {} - // returns the number of controllers created of the specific subtype - // virtual int getNumberOfControllers() const = 0; - virtual MessageBuffer* getMandatoryQueue() const = 0; - virtual const int & getVersion() const = 0; - virtual const string toString() const = 0; // returns text version of controller type - virtual const string getName() const = 0; // return instance name - virtual const MachineType getMachineType() const = 0; - virtual void blockOnQueue(Address, MessageBuffer*) = 0; - virtual void unblock(Address) = 0; - virtual void initNetworkPtr(Network* net_ptr) = 0; - - virtual void print(ostream & out) const = 0; - virtual void printStats(ostream & out) const = 0; - virtual void printConfig(ostream & out) const = 0; - virtual void wakeup() = 0; - // virtual void dumpStats(ostream & out) = 0; - virtual void clearStats() = 0; + // returns the number of controllers created of the specific subtype + // virtual int getNumberOfControllers() const = 0; + virtual MessageBuffer* getMandatoryQueue() const = 0; + virtual const int & getVersion() const = 0; + virtual const string toString() const = 0; // returns text version of + // controller type + virtual const string getName() const = 0; // return instance name + virtual const MachineType getMachineType() const = 0; + virtual void blockOnQueue(Address, MessageBuffer*) = 0; + virtual void unblock(Address) = 0; + virtual void initNetworkPtr(Network* net_ptr) = 0; + virtual void print(ostream & out) const = 0; + virtual void printStats(ostream & out) const = 0; + virtual void printConfig(ostream & out) const = 0; + virtual void wakeup() = 0; + // virtual void dumpStats(ostream & out) = 0; + virtual void clearStats() = 0; }; -#endif +#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__ diff --git a/src/mem/ruby/slicc_interface/AbstractEntry.cc b/src/mem/ruby/slicc_interface/AbstractEntry.cc index 914d4a37e..d66258eef 100644 --- a/src/mem/ruby/slicc_interface/AbstractEntry.cc +++ b/src/mem/ruby/slicc_interface/AbstractEntry.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -29,10 +28,10 @@ #include "mem/ruby/slicc_interface/AbstractEntry.hh" -// Must define constructor and destructor in subclasses -AbstractEntry::AbstractEntry() { +AbstractEntry::AbstractEntry() +{ } -AbstractEntry::~AbstractEntry() { +AbstractEntry::~AbstractEntry() +{ } - diff --git a/src/mem/ruby/slicc_interface/AbstractEntry.hh b/src/mem/ruby/slicc_interface/AbstractEntry.hh index 8e1968d62..eef9a5227 100644 --- a/src/mem/ruby/slicc_interface/AbstractEntry.hh +++ b/src/mem/ruby/slicc_interface/AbstractEntry.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,47 +26,35 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef AbstractEntry_H -#define AbstractEntry_H +#ifndef __MEM_RUBY_SLICC_INTERFACE_ABSTRACTENTRY_HH__ +#define __MEM_RUBY_SLICC_INTERFACE_ABSTRACTENTRY_HH__ -#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/protocol/AccessPermission.hh" class DataBlock; -class AbstractEntry { -public: - // Constructors - AbstractEntry(); - - // Destructor, prevent it from instantiation - virtual ~AbstractEntry() = 0; - - // Public Methods - - // The methods below are those called by ruby runtime, add when it is - // absolutely necessary and should all be virtual function. - virtual DataBlock& getDataBlk() = 0; - +class AbstractEntry +{ + public: + AbstractEntry(); + virtual ~AbstractEntry() = 0; - virtual void print(ostream& out) const = 0; + // The methods below are those called by ruby runtime, add when it + // is absolutely necessary and should all be virtual function. + virtual DataBlock& getDataBlk() = 0; + virtual void print(ostream& out) const = 0; }; -// Output operator declaration -ostream& operator<<(ostream& out, const AbstractEntry& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const AbstractEntry& obj) +inline ostream& +operator<<(ostream& out, const AbstractEntry& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -#endif //AbstractEntry_H +#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTENTRY_HH__ diff --git a/src/mem/ruby/slicc_interface/AbstractProtocol.hh b/src/mem/ruby/slicc_interface/AbstractProtocol.hh index d602f5e54..2cc64a258 100644 --- a/src/mem/ruby/slicc_interface/AbstractProtocol.hh +++ b/src/mem/ruby/slicc_interface/AbstractProtocol.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -28,33 +27,24 @@ */ /* - * $Id$ - * - * Description: Define all possible protocol parameters and their - * default value here. Normally, all parameters should - * have default value "false" means the feature of the - * protocol is turned off. - * + * Define all possible protocol parameters and their default value + * here. Normally, all parameters should have default value "false" + * means the feature of the protocol is turned off. */ -#ifndef AbstractProtocol_H -#define AbstractProtocol_H - -class AbstractProtocol { -public: - // Constructors - AbstractProtocol() {}; +#ifndef __MEM_RUBY_SLICC_INTERFACE_ABSTRACTPROTOCOL_HH__ +#define __MEM_RUBY_SLICC_INTERFACE_ABSTRACTPROTOCOL_HH__ - // Destructor, no instantiation - // No definition also, so no subclass can be instantiated also - virtual ~AbstractProtocol() = 0; +class AbstractProtocol +{ + public: + AbstractProtocol() {} - // Public Methods + virtual ~AbstractProtocol() = 0; - // Data Members (m_ prefix) - static const bool m_CMP = false ; - static const bool m_TwoLevelCache = false ; + static const bool m_CMP = false ; + static const bool m_TwoLevelCache = false ; }; -#endif //AbstractProtocol_H +#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTPROTOCOL_HH__ diff --git a/src/mem/ruby/slicc_interface/Message.hh b/src/mem/ruby/slicc_interface/Message.hh index fef4bdf59..d9df6f131 100644 --- a/src/mem/ruby/slicc_interface/Message.hh +++ b/src/mem/ruby/slicc_interface/Message.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,67 +26,58 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - */ - -#ifndef MESSAGE_H -#define MESSAGE_H +#ifndef __MEM_RUBY_SLICC_INTERFACE_MESSAGE_HH__ +#define __MEM_RUBY_SLICC_INTERFACE_MESSAGE_HH__ #include <iostream> -#include "mem/ruby/common/Global.hh" #include "mem/gems_common/RefCnt.hh" #include "mem/gems_common/RefCountable.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" class Message; typedef RefCnt<Message> MsgPtr; -class Message : public RefCountable { -public: - // Constructors - Message() : RefCountable() { m_time = g_eventQueue_ptr->getTime(); m_LastEnqueueTime = g_eventQueue_ptr->getTime(); m_DelayedCycles = 0;} - - // Destructor - virtual ~Message() { } - - // Public Methods - virtual Message* clone() const = 0; - virtual void destroy() = 0; - virtual void print(std::ostream& out) const = 0; - - void setDelayedCycles(const int& cycles) { m_DelayedCycles = cycles; } - const int& getDelayedCycles() const {return m_DelayedCycles;} - int& getDelayedCycles() {return m_DelayedCycles;} - void setLastEnqueueTime(const Time& time) { m_LastEnqueueTime = time; } - const Time& getLastEnqueueTime() const {return m_LastEnqueueTime;} - Time& getLastEnqueueTime() {return m_LastEnqueueTime;} - - const Time& getTime() const { return m_time; } - void setTime(const Time& new_time) { m_time = new_time; } -private: - // Private Methods - - // Data Members (m_ prefix) - Time m_time; - Time m_LastEnqueueTime; // my last enqueue time - int m_DelayedCycles; // my delayed cycles - +class Message : public RefCountable +{ + public: + Message() + : RefCountable() + { + m_time = g_eventQueue_ptr->getTime(); + m_LastEnqueueTime = g_eventQueue_ptr->getTime(); + m_DelayedCycles = 0; + } + + virtual ~Message() { } + + virtual Message* clone() const = 0; + virtual void destroy() = 0; + virtual void print(std::ostream& out) const = 0; + + void setDelayedCycles(const int& cycles) { m_DelayedCycles = cycles; } + const int& getDelayedCycles() const {return m_DelayedCycles;} + int& getDelayedCycles() {return m_DelayedCycles;} + void setLastEnqueueTime(const Time& time) { m_LastEnqueueTime = time; } + const Time& getLastEnqueueTime() const {return m_LastEnqueueTime;} + Time& getLastEnqueueTime() {return m_LastEnqueueTime;} + + const Time& getTime() const { return m_time; } + void setTime(const Time& new_time) { m_time = new_time; } + + private: + Time m_time; + Time m_LastEnqueueTime; // my last enqueue time + int m_DelayedCycles; // my delayed cycles }; -// Output operator declaration -std::ostream& operator<<(std::ostream& out, const Message& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -std::ostream& operator<<(std::ostream& out, const Message& obj) +inline std::ostream& +operator<<(std::ostream& out, const Message& obj) { - obj.print(out); - out << std::flush; - return out; + obj.print(out); + out << std::flush; + return out; } -#endif //MESSAGE_H +#endif // __MEM_RUBY_SLICC_INTERFACE_MESSAGE_HH__ diff --git a/src/mem/ruby/slicc_interface/NetworkMessage.hh b/src/mem/ruby/slicc_interface/NetworkMessage.hh index 150fd70fc..8a7c00094 100644 --- a/src/mem/ruby/slicc_interface/NetworkMessage.hh +++ b/src/mem/ruby/slicc_interface/NetworkMessage.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,89 +26,69 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * NetworkMessage.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef NetworkMessage_H -#define NetworkMessage_H +#ifndef __MEM_RUBY_SLICC_INTERFACE_NETWORKMESSAGE_HH__ +#define __MEM_RUBY_SLICC_INTERFACE_NETWORKMESSAGE_HH__ -#include "mem/ruby/common/Global.hh" #include "mem/gems_common/RefCnt.hh" #include "mem/gems_common/RefCountable.hh" -#include "mem/ruby/slicc_interface/Message.hh" #include "mem/protocol/MessageSizeType.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/NetDest.hh" +#include "mem/ruby/slicc_interface/Message.hh" class Address; class NetworkMessage; typedef RefCnt<NetworkMessage> NetMsgPtr; -class NetworkMessage : public Message { -public: - // Constructors - NetworkMessage() - :Message() +class NetworkMessage : public Message +{ + public: + NetworkMessage() + : Message() { - m_internal_dest_valid = false; + m_internal_dest_valid = false; } - // Destructor - virtual ~NetworkMessage() { } + virtual ~NetworkMessage() { } - // Public Methods + virtual const NetDest& getDestination() const = 0; + virtual NetDest& getDestination() = 0; + virtual const MessageSizeType& getMessageSize() const = 0; + virtual MessageSizeType& getMessageSize() = 0; - virtual const NetDest& getDestination() const = 0; - virtual NetDest& getDestination() = 0; - virtual const MessageSizeType& getMessageSize() const = 0; - virtual MessageSizeType& getMessageSize() = 0; - // virtual const Address& getAddress() const = 0; - // virtual Address& getAddress() = 0; + const NetDest& + getInternalDestination() const + { + if (m_internal_dest_valid == false) + return getDestination(); - const NetDest& getInternalDestination() const { - if (m_internal_dest_valid == false) { - return getDestination(); - } else { - return m_internal_dest; + return m_internal_dest; } - } - NetDest& getInternalDestination() { - if (m_internal_dest_valid == false) { - m_internal_dest = getDestination(); - m_internal_dest_valid = true; + NetDest& + getInternalDestination() + { + if (m_internal_dest_valid == false) { + m_internal_dest = getDestination(); + m_internal_dest_valid = true; + } + return m_internal_dest; } - return m_internal_dest; - } - - virtual void print(ostream& out) const = 0; -private: - // Private Methods + virtual void print(ostream& out) const = 0; - // Data Members (m_ prefix) - NetDest m_internal_dest; - bool m_internal_dest_valid; + private: + NetDest m_internal_dest; + bool m_internal_dest_valid; }; -// Output operator declaration -ostream& operator<<(ostream& out, const NetworkMessage& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const NetworkMessage& obj) +inline ostream& +operator<<(ostream& out, const NetworkMessage& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -#endif //NetworkMessage_H +#endif // __MEM_RUBY_SLICC_INTERFACE_NETWORKMESSAGE_HH__ diff --git a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc index 0821201e7..79b9821ba 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc +++ b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,7 +26,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" #include "mem/ruby/system/CacheMemory.hh" diff --git a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh index 5ffd0f295..c96667028 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,22 +26,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - */ - -#ifndef COMPONENTMAPPINGFNS_H -#define COMPONENTMAPPINGFNS_H +#ifndef __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_COMPONENTMAPPINGS_HH__ +#define __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_COMPONENTMAPPINGS_HH__ -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/NodeID.hh" -#include "mem/ruby/system/MachineID.hh" +#include "mem/protocol/GenericMachineType.hh" +#include "mem/protocol/MachineType.hh" #include "mem/ruby/common/Address.hh" -#include "mem/ruby/common/Set.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/NetDest.hh" -#include "mem/protocol/GenericMachineType.hh" +#include "mem/ruby/common/Set.hh" #include "mem/ruby/system/DirectoryMemory.hh" -#include "mem/protocol/MachineType.hh" +#include "mem/ruby/system/MachineID.hh" +#include "mem/ruby/system/NodeID.hh" #ifdef MACHINETYPE_L1Cache #define MACHINETYPE_L1CACHE_ENUM MachineType_L1Cache @@ -70,88 +65,100 @@ // used to determine the home directory // returns a value between 0 and total_directories_within_the_system -inline -NodeID map_Address_to_DirectoryNode(const Address& addr) +inline NodeID +map_Address_to_DirectoryNode(const Address& addr) { - return DirectoryMemory::mapAddressToDirectoryVersion(addr); + return DirectoryMemory::mapAddressToDirectoryVersion(addr); } // used to determine the home directory // returns a value between 0 and total_directories_within_the_system -inline -MachineID map_Address_to_Directory(const Address &addr) +inline MachineID +map_Address_to_Directory(const Address &addr) { - MachineID mach = {MachineType_Directory, map_Address_to_DirectoryNode(addr)}; - return mach; + MachineID mach = + {MachineType_Directory, map_Address_to_DirectoryNode(addr)}; + return mach; } -inline -MachineID map_Address_to_DMA(const Address & addr) +inline MachineID +map_Address_to_DMA(const Address & addr) { - MachineID dma = {MACHINETYPE_DMA_ENUM, 0}; - return dma; + MachineID dma = {MACHINETYPE_DMA_ENUM, 0}; + return dma; } -inline -NetDest broadcast(MachineType type) +inline NetDest +broadcast(MachineType type) { - NetDest dest; - for (int i=0; i<MachineType_base_count(type); i++) { - MachineID mach = {type, i}; - dest.add(mach); - } - return dest; + NetDest dest; + for (int i = 0; i < MachineType_base_count(type); i++) { + MachineID mach = {type, i}; + dest.add(mach); + } + return dest; } -inline -MachineID mapAddressToRange(const Address & addr, MachineType type, int low_bit, int num_bits) +inline MachineID +mapAddressToRange(const Address & addr, MachineType type, int low_bit, + int num_bits) { - MachineID mach = {type, 0}; - if (num_bits == 0) + MachineID mach = {type, 0}; + if (num_bits == 0) + return mach; + mach.num = addr.bitSelect(low_bit, low_bit + num_bits - 1); return mach; - mach.num = addr.bitSelect(low_bit, low_bit+num_bits-1); - return mach; } -extern inline NodeID machineIDToNodeID(MachineID machID) +inline NodeID +machineIDToNodeID(MachineID machID) { - return machID.num; + return machID.num; } -extern inline MachineType machineIDToMachineType(MachineID machID) +inline MachineType +machineIDToMachineType(MachineID machID) { - return machID.type; + return machID.type; } -extern inline NodeID L1CacheMachIDToProcessorNum(MachineID machID) +inline NodeID +L1CacheMachIDToProcessorNum(MachineID machID) { - assert(machID.type == MachineType_L1Cache); - return machID.num; + assert(machID.type == MachineType_L1Cache); + return machID.num; } -extern inline MachineID getL1MachineID(NodeID L1RubyNode) +inline MachineID +getL1MachineID(NodeID L1RubyNode) { - MachineID mach = {MACHINETYPE_L1CACHE_ENUM, L1RubyNode}; - return mach; + MachineID mach = {MACHINETYPE_L1CACHE_ENUM, L1RubyNode}; + return mach; } -extern inline GenericMachineType ConvertMachToGenericMach(MachineType machType) { - if (machType == MACHINETYPE_L1CACHE_ENUM) { - return GenericMachineType_L1Cache; - } else if (machType == MACHINETYPE_L2CACHE_ENUM) { - return GenericMachineType_L2Cache; - } else if (machType == MACHINETYPE_L3CACHE_ENUM) { - return GenericMachineType_L3Cache; - } else if (machType == MachineType_Directory) { - return GenericMachineType_Directory; - } else { +inline GenericMachineType +ConvertMachToGenericMach(MachineType machType) +{ + if (machType == MACHINETYPE_L1CACHE_ENUM) + return GenericMachineType_L1Cache; + + if (machType == MACHINETYPE_L2CACHE_ENUM) + return GenericMachineType_L2Cache; + + if (machType == MACHINETYPE_L3CACHE_ENUM) + return GenericMachineType_L3Cache; + + if (machType == MachineType_Directory) + return GenericMachineType_Directory; + ERROR_MSG("cannot convert to a GenericMachineType"); return GenericMachineType_NULL; - } } -extern inline int machineCount(MachineType machType) { +inline int +machineCount(MachineType machType) +{ return MachineType_base_count(machType); } -#endif // COMPONENTMAPPINGFNS_H +#endif // __MEM_RUBY_SLICC_INTERFACE_COMPONENTMAPPINGS_HH__ diff --git a/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc b/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc index 54d38c187..6ffc7fdb4 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc +++ b/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,66 +26,75 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * slicc_util.cc - * - * Description: See slicc_util.hh - * - * $Id$ - * - */ - +#include "mem/protocol/Protocol.hh" #include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/System.hh" -#include "mem/ruby/profiler/Profiler.hh" #include "mem/ruby/profiler/AddressProfiler.hh" -#include "mem/protocol/Protocol.hh" -#include "mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh" +#include "mem/ruby/profiler/Profiler.hh" #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" -// #include "TransactionInterfaceManager.hh" +#include "mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh" +#include "mem/ruby/system/System.hh" -void profile_request(int cache_state, Directory_State directory_state, GenericRequestType request_type) +void +profile_request(int cache_state, Directory_State directory_state, + GenericRequestType request_type) { - string requestStr = L1Cache_State_to_string(L1Cache_State(cache_state))+":"+ - Directory_State_to_string(directory_state)+":"+ - GenericRequestType_to_string(request_type); - g_system_ptr->getProfiler()->profileRequest(requestStr); + string requestStr = L1Cache_State_to_string(L1Cache_State(cache_state))+ + ":" + + Directory_State_to_string(directory_state) + ":" + + GenericRequestType_to_string(request_type); + g_system_ptr->getProfiler()->profileRequest(requestStr); } -void profile_request(const string& L1CacheState, const string& L2CacheState, const string& directoryState, const string& requestType) +void +profile_request(const string& L1CacheState, const string& L2CacheState, + const string& directoryState, const string& requestType) { - string requestStr = L1CacheState+":"+L2CacheState+":"+directoryState+":"+requestType; - g_system_ptr->getProfiler()->profileRequest(requestStr); + string requestStr = L1CacheState + ":" + L2CacheState + ":" + + directoryState + ":" + requestType; + + g_system_ptr->getProfiler()->profileRequest(requestStr); } -void profile_outstanding_request(int outstanding) +void +profile_outstanding_request(int outstanding) { - g_system_ptr->getProfiler()->profileOutstandingRequest(outstanding); + g_system_ptr->getProfiler()->profileOutstandingRequest(outstanding); } -void profile_average_latency_estimate(int latency) +void +profile_average_latency_estimate(int latency) { - g_system_ptr->getProfiler()->profileAverageLatencyEstimate(latency); + g_system_ptr->getProfiler()->profileAverageLatencyEstimate(latency); } -void profile_sharing(const Address& addr, AccessType type, NodeID requestor, const Set& sharers, const Set& owner) +void +profile_sharing(const Address& addr, AccessType type, NodeID requestor, + const Set& sharers, const Set& owner) { - g_system_ptr->getProfiler()->profileSharing(addr, type, requestor, sharers, owner); + g_system_ptr->getProfiler()-> + profileSharing(addr, type, requestor, sharers, owner); } -void profileMsgDelay(int virtualNetwork, int delayCycles) +void +profileMsgDelay(int virtualNetwork, int delayCycles) { - g_system_ptr->getProfiler()->profileMsgDelay(virtualNetwork, delayCycles); + g_system_ptr->getProfiler()->profileMsgDelay(virtualNetwork, delayCycles); } -void profileGetX(const Address& datablock, const Address& PC, const Set& owner, const Set& sharers, NodeID requestor) +void +profileGetX(const Address& datablock, const Address& PC, const Set& owner, + const Set& sharers, NodeID requestor) { - g_system_ptr->getProfiler()->getAddressProfiler()->profileGetX(datablock, PC, owner, sharers, requestor); + g_system_ptr->getProfiler()->getAddressProfiler()-> + profileGetX(datablock, PC, owner, sharers, requestor); } -void profileGetS(const Address& datablock, const Address& PC, const Set& owner, const Set& sharers, NodeID requestor) +void +profileGetS(const Address& datablock, const Address& PC, const Set& owner, + const Set& sharers, NodeID requestor) { - g_system_ptr->getProfiler()->getAddressProfiler()->profileGetS(datablock, PC, owner, sharers, requestor); + g_system_ptr->getProfiler()->getAddressProfiler()-> + profileGetS(datablock, PC, owner, sharers, requestor); } diff --git a/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh b/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh index 1529e6317..25495b6fa 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -28,36 +27,37 @@ */ /* - * slicc_util.hh - * - * Description: These are the functions that exported to slicc from ruby. - * - * $Id$ - * + * These are the functions that exported to slicc from ruby. */ -#ifndef RUBYSLICC_PROFILER_INTERFACE_H -#define RUBYSLICC_PROFILER_INTERFACE_H +#ifndef __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_PROFILER_INTERFACE_HH__ +#define __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_PROFILER_INTERFACE_HH__ -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/profiler/Profiler.hh" -#include "mem/ruby/common/Address.hh" -#include "mem/protocol/L1Cache_State.hh" #include "mem/protocol/AccessType.hh" -#include "mem/protocol/GenericRequestType.hh" #include "mem/protocol/Directory_State.hh" +#include "mem/protocol/GenericRequestType.hh" +#include "mem/protocol/L1Cache_State.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/profiler/Profiler.hh" #include "mem/ruby/system/NodeID.hh" class Set; -void profile_request(int cache_state, Directory_State directory_state, GenericRequestType request_type); +void profile_request(int cache_state, Directory_State directory_state, + GenericRequestType request_type); void profile_outstanding_persistent_request(int outstanding); void profile_outstanding_request(int outstanding); -void profile_sharing(const Address& addr, AccessType type, NodeID requestor, const Set& sharers, const Set& owner); -void profile_request(const string& L1CacheStateStr, const string& L2CacheStateStr, const string& directoryStateStr, const string& requestTypeStr); +void profile_sharing(const Address& addr, AccessType type, NodeID requestor, + const Set& sharers, const Set& owner); +void profile_request(const string& L1CacheStateStr, + const string& L2CacheStateStr, + const string& directoryStateStr, + const string& requestTypeStr); void profile_miss(const CacheMsg& msg, NodeID id); void profile_L1Cache_miss(const CacheMsg& msg, NodeID id); -void profile_L2Cache_miss(GenericRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit, NodeID l2cacheID); +void profile_L2Cache_miss(GenericRequestType requestType, AccessModeType type, + int msgSize, PrefetchBit pfBit, NodeID l2cacheID); void profile_token_retry(const Address& addr, AccessType type, int count); void profile_filter_action(int action); void profile_persistent_prediction(const Address& addr, AccessType type); @@ -65,9 +65,11 @@ void profile_average_latency_estimate(int latency); void profileMsgDelay(int virtualNetwork, int delayCycles); void profile_multicast_retry(const Address& addr, int count); -void profileGetX(const Address& datablock, const Address& PC, const Set& owner, const Set& sharers, NodeID requestor); -void profileGetS(const Address& datablock, const Address& PC, const Set& owner, const Set& sharers, NodeID requestor); +void profileGetX(const Address& datablock, const Address& PC, const Set& owner, + const Set& sharers, NodeID requestor); +void profileGetS(const Address& datablock, const Address& PC, const Set& owner, + const Set& sharers, NodeID requestor); void profileOverflow(const Address & addr, MachineID mach); -#endif // RUBYSLICC_PROFILER_INTERFACE_H +#endif // __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_PROFILER_INTERFACE_HH__ diff --git a/src/mem/ruby/slicc_interface/RubySlicc_Util.hh b/src/mem/ruby/slicc_interface/RubySlicc_Util.hh index 3d4fa3e5c..24240dc52 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_Util.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_Util.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -28,149 +27,163 @@ */ /* - * slicc_util.hh - * - * Description: These are the functions that exported to slicc from ruby. - * - * $Id$ - * + * These are the functions that exported to slicc from ruby. */ -#ifndef SLICC_UTIL_H -#define SLICC_UTIL_H +#ifndef __MEM_RUBY_SLICC_INTERFACE_RUBYSLICCUTIL_HH__ +#define __MEM_RUBY_SLICC_INTERFACE_RUBYSLICCUTIL_HH__ -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/common/Address.hh" -#include "mem/ruby/system/NodeID.hh" -#include "mem/ruby/system/MachineID.hh" +#include "mem/protocol/AccessType.hh" #include "mem/protocol/CacheMsg.hh" -#include "mem/protocol/GenericRequestType.hh" #include "mem/protocol/CacheRequestType.hh" -#include "mem/protocol/AccessType.hh" -#include "mem/protocol/MachineType.hh" #include "mem/protocol/Directory_State.hh" +#include "mem/protocol/GenericRequestType.hh" #include "mem/protocol/L1Cache_State.hh" +#include "mem/protocol/MachineType.hh" #include "mem/protocol/MessageSizeType.hh" -#include "mem/ruby/network/Network.hh" #include "mem/protocol/PrefetchBit.hh" -#include "mem/ruby/system/System.hh" - +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/network/Network.hh" #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" +#include "mem/ruby/system/MachineID.hh" +#include "mem/ruby/system/NodeID.hh" +#include "mem/ruby/system/System.hh" class Set; class NetDest; -extern inline int random(int n) +inline int +random(int n) { return random() % n; } -extern inline bool multicast_retry() +inline bool +multicast_retry() { - if (RubySystem::getRandomization()) { - return (random() & 0x1); - } else { - return true; - } + if (RubySystem::getRandomization()) { + return (random() & 0x1); + } else { + return true; + } } -extern inline int cache_state_to_int(L1Cache_State state) +inline int +cache_state_to_int(L1Cache_State state) { - return state; + return state; } -extern inline Time get_time() +inline Time +get_time() { - return g_eventQueue_ptr->getTime(); + return g_eventQueue_ptr->getTime(); } -extern inline Time zero_time() +inline Time +zero_time() { - return 0; + return 0; } -extern inline NodeID intToID(int nodenum) +inline NodeID +intToID(int nodenum) { - NodeID id = nodenum; - return id; + NodeID id = nodenum; + return id; } -extern inline int IDToInt(NodeID id) +inline int +IDToInt(NodeID id) { - int nodenum = id; - return nodenum; + int nodenum = id; + return nodenum; } -extern inline int addressToInt(Address addr) +inline int +addressToInt(Address addr) { - return (int) addr.getLineAddress(); + return (int)addr.getLineAddress(); } -extern inline bool long_enough_ago(Time event) +inline bool +long_enough_ago(Time event) { - return ((get_time() - event) > 200); + return ((get_time() - event) > 200); } -extern inline int getAddThenMod(int addend1, int addend2, int modulus) +inline int +getAddThenMod(int addend1, int addend2, int modulus) { - return (addend1 + addend2) % modulus; + return (addend1 + addend2) % modulus; } -extern inline Time getTimeModInt(Time time, int modulus) +inline Time +getTimeModInt(Time time, int modulus) { - return time % modulus; + return time % modulus; } -extern inline Time getTimePlusInt(Time addend1, int addend2) +inline Time +getTimePlusInt(Time addend1, int addend2) { - return (Time) addend1 + addend2; + return (Time) addend1 + addend2; } -extern inline Time getTimeMinusTime(Time t1, Time t2) +inline Time +getTimeMinusTime(Time t1, Time t2) { - ASSERT(t1 >= t2); - return t1 - t2; + ASSERT(t1 >= t2); + return t1 - t2; } -extern inline Time getPreviousDelayedCycles(Time t1, Time t2) +inline Time +getPreviousDelayedCycles(Time t1, Time t2) { - if (RubySystem::getRandomization()) { // when randomizing delayed - return 0; - } else { - return getTimeMinusTime(t1, t2); - } + if (RubySystem::getRandomization()) { // when randomizing delayed + return 0; + } else { + return getTimeMinusTime(t1, t2); + } } -extern inline void WARN_ERROR_TIME(Time time) +inline void +WARN_ERROR_TIME(Time time) { - WARN_EXPR(time); + WARN_EXPR(time); } -// Return type for time_to_int is "Time" and not "int" so we get a 64-bit integer -extern inline Time time_to_int(Time time) +// Return type for time_to_int is "Time" and not "int" so we get a +// 64-bit integer +inline Time +time_to_int(Time time) { - return time; + return time; } // Appends an offset to an address -extern inline Address setOffset(Address addr, int offset) +inline Address +setOffset(Address addr, int offset) { - Address result = addr; - result.setOffset(offset); - return result; + Address result = addr; + result.setOffset(offset); + return result; } // Makes an address into a line address -extern inline Address makeLineAddress(Address addr) +inline Address +makeLineAddress(Address addr) { - Address result = addr; - result.makeLineAddress(); - return result; + Address result = addr; + result.makeLineAddress(); + return result; } -extern inline int addressOffset(Address addr) +inline int +addressOffset(Address addr) { - return addr.getOffset(); + return addr.getOffset(); } -#endif //SLICC_UTIL_H +#endif // __MEM_RUBY_SLICC_INTERFACE_RUBYSLICCUTIL_HH__ diff --git a/src/mem/ruby/slicc_interface/RubySlicc_includes.hh b/src/mem/ruby/slicc_interface/RubySlicc_includes.hh index 76858ddba..ae98b3084 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_includes.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_includes.hh @@ -26,12 +26,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef RUBYSLICC_INCLUDES_H -#define RUBYSLICC_INCLUDES_H +#ifndef __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_INCLUDES_HH__ +#define __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_INCLUDES_HH__ #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" #include "mem/ruby/slicc_interface/RubySlicc_Util.hh" #include "mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh" -#endif +#endif // __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_INCLUDES_HH__ diff --git a/src/mem/ruby/system/AbstractMemOrCache.hh b/src/mem/ruby/system/AbstractMemOrCache.hh index 4a8b667e8..28b446ef8 100644 --- a/src/mem/ruby/system/AbstractMemOrCache.hh +++ b/src/mem/ruby/system/AbstractMemOrCache.hh @@ -26,42 +26,34 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * AbstractMemOrCache.hh - * - * Description: - * - * - */ - -#ifndef ABSTRACT_MEM_OR_CACHE_H -#define ABSTRACT_MEM_OR_CACHE_H - -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/common/Address.hh" - -class AbstractMemOrCache { -public: - - virtual ~AbstractMemOrCache() {}; - virtual void setConsumer(Consumer* consumer_ptr) = 0; - virtual Consumer* getConsumer() = 0; - - virtual void enqueue (const MsgPtr& message, int latency ) = 0; - virtual void enqueueMemRef (MemoryNode& memRef) = 0; - virtual void dequeue () = 0; - virtual const Message* peek () = 0; - virtual bool isReady () = 0; - virtual MemoryNode peekNode () = 0; - virtual bool areNSlotsAvailable (int n) = 0; - virtual void printConfig (ostream& out) = 0; - virtual void print (ostream& out) const = 0; - virtual void setDebug (int debugFlag) = 0; - -private: - +#ifndef __MEM_RUBY_SYSTEM_ABSTRACTMEMORCACHE_HH__ +#define __MEM_RUBY_SYSTEM_ABSTRACTMEMORCACHE_HH__ + +#include <iosfwd> + +#include "mem/ruby/slicc_interface/Message.hh" + +class Consumer; +class MemoryNode; +class Message; + +class AbstractMemOrCache +{ + public: + virtual ~AbstractMemOrCache() {}; + virtual void setConsumer(Consumer* consumer_ptr) = 0; + virtual Consumer* getConsumer() = 0; + + virtual void enqueue (const MsgPtr& message, int latency) = 0; + virtual void enqueueMemRef (MemoryNode& memRef) = 0; + virtual void dequeue () = 0; + virtual const Message* peek () = 0; + virtual bool isReady () = 0; + virtual MemoryNode peekNode () = 0; + virtual bool areNSlotsAvailable (int n) = 0; + virtual void printConfig (std::ostream& out) = 0; + virtual void print (std::ostream& out) const = 0; + virtual void setDebug (int debugFlag) = 0; }; - -#endif - +#endif // __MEM_RUBY_SYSTEM_ABSTRACTMEMORCACHE_HH__ diff --git a/src/mem/ruby/system/AbstractReplacementPolicy.hh b/src/mem/ruby/system/AbstractReplacementPolicy.hh index f06b8b8ee..3ddf4ab60 100644 --- a/src/mem/ruby/system/AbstractReplacementPolicy.hh +++ b/src/mem/ruby/system/AbstractReplacementPolicy.hh @@ -26,64 +26,64 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ABSTRACTREPLACEMENTPOLICY_H -#define ABSTRACTREPLACEMENTPOLICY_H +#ifndef __MEM_RUBY_SYSTEM_ABSTRACTREPLACEMENTPOLICY_HH__ +#define __MEM_RUBY_SYSTEM_ABSTRACTREPLACEMENTPOLICY_HH__ #include "mem/ruby/common/Global.hh" -class AbstractReplacementPolicy { - -public: - - AbstractReplacementPolicy(Index num_sets, Index assoc); - virtual ~AbstractReplacementPolicy(); +class AbstractReplacementPolicy +{ + public: + AbstractReplacementPolicy(Index num_sets, Index assoc); + virtual ~AbstractReplacementPolicy(); - /* touch a block. a.k.a. update timestamp */ - virtual void touch(Index set, Index way, Time time) = 0; + /* touch a block. a.k.a. update timestamp */ + virtual void touch(Index set, Index way, Time time) = 0; - /* returns the way to replace */ - virtual Index getVictim(Index set) const = 0; + /* returns the way to replace */ + virtual Index getVictim(Index set) const = 0; - /* get the time of the last access */ - Time getLastAccess(Index set, Index way); + /* get the time of the last access */ + Time getLastAccess(Index set, Index way); - protected: - unsigned int m_num_sets; /** total number of sets */ - unsigned int m_assoc; /** set associativity */ - Time **m_last_ref_ptr; /** timestamp of last reference */ + protected: + unsigned m_num_sets; /** total number of sets */ + unsigned m_assoc; /** set associativity */ + Time **m_last_ref_ptr; /** timestamp of last reference */ }; inline -AbstractReplacementPolicy::AbstractReplacementPolicy(Index num_sets, Index assoc) +AbstractReplacementPolicy::AbstractReplacementPolicy(Index num_sets, + Index assoc) { - m_num_sets = num_sets; - m_assoc = assoc; - m_last_ref_ptr = new Time*[m_num_sets]; - for(unsigned int i = 0; i < m_num_sets; i++){ - m_last_ref_ptr[i] = new Time[m_assoc]; - for(unsigned int j = 0; j < m_assoc; j++){ - m_last_ref_ptr[i][j] = 0; + m_num_sets = num_sets; + m_assoc = assoc; + m_last_ref_ptr = new Time*[m_num_sets]; + for(unsigned i = 0; i < m_num_sets; i++){ + m_last_ref_ptr[i] = new Time[m_assoc]; + for(unsigned j = 0; j < m_assoc; j++){ + m_last_ref_ptr[i][j] = 0; + } } - } } inline AbstractReplacementPolicy::~AbstractReplacementPolicy() { - if(m_last_ref_ptr != NULL){ - for(unsigned int i = 0; i < m_num_sets; i++){ - if(m_last_ref_ptr[i] != NULL){ - delete[] m_last_ref_ptr[i]; - } + if (m_last_ref_ptr != NULL){ + for (unsigned i = 0; i < m_num_sets; i++){ + if (m_last_ref_ptr[i] != NULL){ + delete[] m_last_ref_ptr[i]; + } + } + delete[] m_last_ref_ptr; } - delete[] m_last_ref_ptr; - } } -inline -Time AbstractReplacementPolicy::getLastAccess(Index set, Index way) +inline Time +AbstractReplacementPolicy::getLastAccess(Index set, Index way) { - return m_last_ref_ptr[set][way]; + return m_last_ref_ptr[set][way]; } -#endif // ABSTRACTREPLACEMENTPOLICY_H +#endif // __MEM_RUBY_SYSTEM_ABSTRACTREPLACEMENTPOLICY_HH__ diff --git a/src/mem/ruby/system/CacheMemory.cc b/src/mem/ruby/system/CacheMemory.cc index 35625245a..10ea8a6fc 100644 --- a/src/mem/ruby/system/CacheMemory.cc +++ b/src/mem/ruby/system/CacheMemory.cc @@ -28,19 +28,14 @@ #include "mem/ruby/system/CacheMemory.hh" -// ******************* Definitions ******************* - -// Output operator definition -ostream& operator<<(ostream& out, const CacheMemory& obj) +ostream& +operator<<(ostream& out, const CacheMemory& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } - -// **************************************************************** - CacheMemory * RubyCacheParams::create() { @@ -57,410 +52,451 @@ CacheMemory::CacheMemory(const Params *p) m_profiler_ptr = new CacheProfiler(name()); } - -void CacheMemory::init() +void +CacheMemory::init() { - m_cache_num_sets = (m_cache_size / m_cache_assoc) / RubySystem::getBlockSizeBytes(); + m_cache_num_sets = (m_cache_size / m_cache_assoc) / + RubySystem::getBlockSizeBytes(); assert(m_cache_num_sets > 1); m_cache_num_set_bits = log_int(m_cache_num_sets); assert(m_cache_num_set_bits > 0); - - if(m_policy == "PSEUDO_LRU") - m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc); + + if (m_policy == "PSEUDO_LRU") + m_replacementPolicy_ptr = + new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc); else if (m_policy == "LRU") - m_replacementPolicy_ptr = new LRUPolicy(m_cache_num_sets, m_cache_assoc); + m_replacementPolicy_ptr = + new LRUPolicy(m_cache_num_sets, m_cache_assoc); else - assert(false); - - m_cache.setSize(m_cache_num_sets); - m_locked.setSize(m_cache_num_sets); - for (int i = 0; i < m_cache_num_sets; i++) { - m_cache[i].setSize(m_cache_assoc); - m_locked[i].setSize(m_cache_assoc); - for (int j = 0; j < m_cache_assoc; j++) { - m_cache[i][j] = NULL; - m_locked[i][j] = -1; + assert(false); + + m_cache.setSize(m_cache_num_sets); + m_locked.setSize(m_cache_num_sets); + for (int i = 0; i < m_cache_num_sets; i++) { + m_cache[i].setSize(m_cache_assoc); + m_locked[i].setSize(m_cache_assoc); + for (int j = 0; j < m_cache_assoc; j++) { + m_cache[i][j] = NULL; + m_locked[i][j] = -1; + } } - } } CacheMemory::~CacheMemory() { - if(m_replacementPolicy_ptr != NULL) - delete m_replacementPolicy_ptr; - delete m_profiler_ptr; - for (int i = 0; i < m_cache_num_sets; i++) { - for (int j = 0; j < m_cache_assoc; j++) { - delete m_cache[i][j]; + if (m_replacementPolicy_ptr != NULL) + delete m_replacementPolicy_ptr; + delete m_profiler_ptr; + for (int i = 0; i < m_cache_num_sets; i++) { + for (int j = 0; j < m_cache_assoc; j++) { + delete m_cache[i][j]; + } } - } } -void CacheMemory::printConfig(ostream& out) +void +CacheMemory::printConfig(ostream& out) { - out << "Cache config: " << m_cache_name << endl; - out << " cache_associativity: " << m_cache_assoc << endl; - out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl; - const int cache_num_sets = 1 << m_cache_num_set_bits; - out << " num_cache_sets: " << cache_num_sets << endl; - out << " cache_set_size_bytes: " << cache_num_sets * RubySystem::getBlockSizeBytes() << endl; - out << " cache_set_size_Kbytes: " - << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<10) << endl; - out << " cache_set_size_Mbytes: " - << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<20) << endl; - out << " cache_size_bytes: " - << cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc << endl; - out << " cache_size_Kbytes: " - << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<10) << endl; - out << " cache_size_Mbytes: " - << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<20) << endl; + int block_size = RubySystem::getBlockSizeBytes(); + + out << "Cache config: " << m_cache_name << endl; + out << " cache_associativity: " << m_cache_assoc << endl; + out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl; + const int cache_num_sets = 1 << m_cache_num_set_bits; + out << " num_cache_sets: " << cache_num_sets << endl; + out << " cache_set_size_bytes: " << cache_num_sets * block_size << endl; + out << " cache_set_size_Kbytes: " + << double(cache_num_sets * block_size) / (1<<10) << endl; + out << " cache_set_size_Mbytes: " + << double(cache_num_sets * block_size) / (1<<20) << endl; + out << " cache_size_bytes: " + << cache_num_sets * block_size * m_cache_assoc << endl; + out << " cache_size_Kbytes: " + << double(cache_num_sets * block_size * m_cache_assoc) / (1<<10) + << endl; + out << " cache_size_Mbytes: " + << double(cache_num_sets * block_size * m_cache_assoc) / (1<<20) + << endl; } -// PRIVATE METHODS - // convert a Address to its location in the cache -Index CacheMemory::addressToCacheSet(const Address& address) const +Index +CacheMemory::addressToCacheSet(const Address& address) const { - assert(address == line_address(address)); - return address.bitSelect(RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_cache_num_set_bits-1); + assert(address == line_address(address)); + return address.bitSelect(RubySystem::getBlockSizeBits(), + RubySystem::getBlockSizeBits() + m_cache_num_set_bits - 1); } // Given a cache index: returns the index of the tag in a set. // returns -1 if the tag is not found. -int CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const +int +CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const { - assert(tag == line_address(tag)); - // search the set for the tags - m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag); - if (it != m_tag_index.end()) - if (m_cache[cacheSet][it->second]->m_Permission != AccessPermission_NotPresent) - return it->second; - return -1; // Not found + assert(tag == line_address(tag)); + // search the set for the tags + m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag); + if (it != m_tag_index.end()) + if (m_cache[cacheSet][it->second]->m_Permission != + AccessPermission_NotPresent) + return it->second; + return -1; // Not found } // Given a cache index: returns the index of the tag in a set. // returns -1 if the tag is not found. -int CacheMemory::findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const -{ - assert(tag == line_address(tag)); - // search the set for the tags - m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag); - if (it != m_tag_index.end()) - return it->second; - return -1; // Not found -} - -// PUBLIC METHODS -bool CacheMemory::tryCacheAccess(const Address& address, - CacheRequestType type, - DataBlock*& data_ptr) -{ - assert(address == line_address(address)); - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - if(loc != -1){ // Do we even have a tag match? - AbstractCacheEntry* entry = m_cache[cacheSet][loc]; - m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); - data_ptr = &(entry->getDataBlk()); - - if(entry->m_Permission == AccessPermission_Read_Write) { - return true; - } - if ((entry->m_Permission == AccessPermission_Read_Only) && - (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) { - return true; +int +CacheMemory::findTagInSetIgnorePermissions(Index cacheSet, + const Address& tag) const +{ + assert(tag == line_address(tag)); + // search the set for the tags + m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag); + if (it != m_tag_index.end()) + return it->second; + return -1; // Not found +} + +bool +CacheMemory::tryCacheAccess(const Address& address, CacheRequestType type, + DataBlock*& data_ptr) +{ + assert(address == line_address(address)); + DEBUG_EXPR(CACHE_COMP, HighPrio, address); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + if (loc != -1) { + // Do we even have a tag match? + AbstractCacheEntry* entry = m_cache[cacheSet][loc]; + m_replacementPolicy_ptr-> + touch(cacheSet, loc, g_eventQueue_ptr->getTime()); + data_ptr = &(entry->getDataBlk()); + + if (entry->m_Permission == AccessPermission_Read_Write) { + return true; + } + if ((entry->m_Permission == AccessPermission_Read_Only) && + (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) { + return true; + } + // The line must not be accessible } - // The line must not be accessible - } - data_ptr = NULL; - return false; + data_ptr = NULL; + return false; } -bool CacheMemory::testCacheAccess(const Address& address, - CacheRequestType type, - DataBlock*& data_ptr) +bool +CacheMemory::testCacheAccess(const Address& address, CacheRequestType type, + DataBlock*& data_ptr) { - assert(address == line_address(address)); - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - if(loc != -1){ // Do we even have a tag match? - AbstractCacheEntry* entry = m_cache[cacheSet][loc]; - m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); - data_ptr = &(entry->getDataBlk()); + assert(address == line_address(address)); + DEBUG_EXPR(CACHE_COMP, HighPrio, address); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + + if (loc != -1) { + // Do we even have a tag match? + AbstractCacheEntry* entry = m_cache[cacheSet][loc]; + m_replacementPolicy_ptr-> + touch(cacheSet, loc, g_eventQueue_ptr->getTime()); + data_ptr = &(entry->getDataBlk()); + + return m_cache[cacheSet][loc]->m_Permission != + AccessPermission_NotPresent; + } - return (m_cache[cacheSet][loc]->m_Permission != AccessPermission_NotPresent); - } - data_ptr = NULL; - return false; + data_ptr = NULL; + return false; } // tests to see if an address is present in the cache -bool CacheMemory::isTagPresent(const Address& address) const +bool +CacheMemory::isTagPresent(const Address& address) const { - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int location = findTagInSet(cacheSet, address); - - if (location == -1) { - // We didn't find the tag + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + + if (loc == -1) { + // We didn't find the tag + DEBUG_EXPR(CACHE_COMP, LowPrio, address); + DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match"); + return false; + } DEBUG_EXPR(CACHE_COMP, LowPrio, address); - DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match"); - return false; - } - DEBUG_EXPR(CACHE_COMP, LowPrio, address); - DEBUG_MSG(CACHE_COMP, LowPrio, "found"); - return true; + DEBUG_MSG(CACHE_COMP, LowPrio, "found"); + return true; } // Returns true if there is: // a) a tag match on this address or there is // b) an unused line in the same cache "way" -bool CacheMemory::cacheAvail(const Address& address) const +bool +CacheMemory::cacheAvail(const Address& address) const { - assert(address == line_address(address)); - - Index cacheSet = addressToCacheSet(address); - - for (int i=0; i < m_cache_assoc; i++) { - AbstractCacheEntry* entry = m_cache[cacheSet][i]; - if (entry != NULL) { - if (entry->m_Address == address || // Already in the cache - entry->m_Permission == AccessPermission_NotPresent) { // We found an empty entry - return true; - } - } else { - return true; + assert(address == line_address(address)); + + Index cacheSet = addressToCacheSet(address); + + for (int i = 0; i < m_cache_assoc; i++) { + AbstractCacheEntry* entry = m_cache[cacheSet][i]; + if (entry != NULL) { + if (entry->m_Address == address || + entry->m_Permission == AccessPermission_NotPresent) { + // Already in the cache or we found an empty entry + return true; + } + } else { + return true; + } } - } - return false; + return false; } -void CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry) +void +CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry) { - assert(address == line_address(address)); - assert(!isTagPresent(address)); - assert(cacheAvail(address)); - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - - // Find the first open slot - Index cacheSet = addressToCacheSet(address); - for (int i=0; i < m_cache_assoc; i++) { - if (m_cache[cacheSet][i] == NULL || - m_cache[cacheSet][i]->m_Permission == AccessPermission_NotPresent) { - m_cache[cacheSet][i] = entry; // Init entry - m_cache[cacheSet][i]->m_Address = address; - m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid; - DPRINTF(RubyCache, "Allocate clearing lock for addr: %llx\n", address); - m_locked[cacheSet][i] = -1; - m_tag_index[address] = i; - - m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime()); - - return; + assert(address == line_address(address)); + assert(!isTagPresent(address)); + assert(cacheAvail(address)); + DEBUG_EXPR(CACHE_COMP, HighPrio, address); + + // Find the first open slot + Index cacheSet = addressToCacheSet(address); + Vector<AbstractCacheEntry*> &set = m_cache[cacheSet]; + for (int i = 0; i < m_cache_assoc; i++) { + if (!set[i] || set[i]->m_Permission == AccessPermission_NotPresent) { + set[i] = entry; // Init entry + set[i]->m_Address = address; + set[i]->m_Permission = AccessPermission_Invalid; + DPRINTF(RubyCache, "Allocate clearing lock for addr: %x\n", + address); + m_locked[cacheSet][i] = -1; + m_tag_index[address] = i; + + m_replacementPolicy_ptr-> + touch(cacheSet, i, g_eventQueue_ptr->getTime()); + + return; + } } - } - ERROR_MSG("Allocate didn't find an available entry"); + ERROR_MSG("Allocate didn't find an available entry"); } -void CacheMemory::deallocate(const Address& address) +void +CacheMemory::deallocate(const Address& address) { - assert(address == line_address(address)); - assert(isTagPresent(address)); - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - Index cacheSet = addressToCacheSet(address); - int location = findTagInSet(cacheSet, address); - if (location != -1){ - delete m_cache[cacheSet][location]; - m_cache[cacheSet][location] = NULL; - DPRINTF(RubyCache, "Deallocate clearing lock for addr: %llx\n", address); - m_locked[cacheSet][location] = -1; - m_tag_index.erase(address); - } + assert(address == line_address(address)); + assert(isTagPresent(address)); + DEBUG_EXPR(CACHE_COMP, HighPrio, address); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + if (loc != -1) { + delete m_cache[cacheSet][loc]; + m_cache[cacheSet][loc] = NULL; + DPRINTF(RubyCache, "Deallocate clearing lock for addr: %x\n", + address); + m_locked[cacheSet][loc] = -1; + m_tag_index.erase(address); + } } // Returns with the physical address of the conflicting cache line -Address CacheMemory::cacheProbe(const Address& address) const +Address +CacheMemory::cacheProbe(const Address& address) const { - assert(address == line_address(address)); - assert(!cacheAvail(address)); + assert(address == line_address(address)); + assert(!cacheAvail(address)); - Index cacheSet = addressToCacheSet(address); - return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->m_Address; + Index cacheSet = addressToCacheSet(address); + return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]-> + m_Address; } // looks an address up in the cache -AbstractCacheEntry& CacheMemory::lookup(const Address& address) +AbstractCacheEntry& +CacheMemory::lookup(const Address& address) { - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - assert(loc != -1); - return *m_cache[cacheSet][loc]; + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + return *m_cache[cacheSet][loc]; } // looks an address up in the cache -const AbstractCacheEntry& CacheMemory::lookup(const Address& address) const +const AbstractCacheEntry& +CacheMemory::lookup(const Address& address) const { - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - assert(loc != -1); - return *m_cache[cacheSet][loc]; + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + return *m_cache[cacheSet][loc]; } -AccessPermission CacheMemory::getPermission(const Address& address) const +AccessPermission +CacheMemory::getPermission(const Address& address) const { - assert(address == line_address(address)); - return lookup(address).m_Permission; + assert(address == line_address(address)); + return lookup(address).m_Permission; } -void CacheMemory::changePermission(const Address& address, AccessPermission new_perm) +void +CacheMemory::changePermission(const Address& address, + AccessPermission new_perm) { - assert(address == line_address(address)); - lookup(address).m_Permission = new_perm; - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - if (new_perm != AccessPermission_Read_Write) { - DPRINTF(RubyCache, "Permission clearing lock for addr: %llx\n", address); - m_locked[cacheSet][loc] = -1; - } - assert(getPermission(address) == new_perm); + assert(address == line_address(address)); + lookup(address).m_Permission = new_perm; + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + if (new_perm != AccessPermission_Read_Write) { + DPRINTF(RubyCache, "Permission clearing lock for addr: %x\n", address); + m_locked[cacheSet][loc] = -1; + } + assert(getPermission(address) == new_perm); } // Sets the most recently used bit for a cache block -void CacheMemory::setMRU(const Address& address) +void +CacheMemory::setMRU(const Address& address) { - Index cacheSet; + Index cacheSet; - cacheSet = addressToCacheSet(address); - m_replacementPolicy_ptr->touch(cacheSet, - findTagInSet(cacheSet, address), - g_eventQueue_ptr->getTime()); + cacheSet = addressToCacheSet(address); + m_replacementPolicy_ptr-> + touch(cacheSet, findTagInSet(cacheSet, address), + g_eventQueue_ptr->getTime()); } -void CacheMemory::profileMiss(const CacheMsg & msg) +void +CacheMemory::profileMiss(const CacheMsg& msg) { - m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(), - msg.getSize(), msg.getPrefetch()); + m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(), + msg.getSize(), msg.getPrefetch()); } -void CacheMemory::recordCacheContents(CacheRecorder& tr) const +void +CacheMemory::recordCacheContents(CacheRecorder& tr) const { - for (int i = 0; i < m_cache_num_sets; i++) { - for (int j = 0; j < m_cache_assoc; j++) { - AccessPermission perm = m_cache[i][j]->m_Permission; - CacheRequestType request_type = CacheRequestType_NULL; - if (perm == AccessPermission_Read_Only) { - if (m_is_instruction_only_cache) { - request_type = CacheRequestType_IFETCH; - } else { - request_type = CacheRequestType_LD; + for (int i = 0; i < m_cache_num_sets; i++) { + for (int j = 0; j < m_cache_assoc; j++) { + AccessPermission perm = m_cache[i][j]->m_Permission; + CacheRequestType request_type = CacheRequestType_NULL; + if (perm == AccessPermission_Read_Only) { + if (m_is_instruction_only_cache) { + request_type = CacheRequestType_IFETCH; + } else { + request_type = CacheRequestType_LD; + } + } else if (perm == AccessPermission_Read_Write) { + request_type = CacheRequestType_ST; + } + + if (request_type != CacheRequestType_NULL) { +#if 0 + tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address, + Address(0), request_type, + m_replacementPolicy_ptr->getLastAccess(i, j)); +#endif + } } - } else if (perm == AccessPermission_Read_Write) { - request_type = CacheRequestType_ST; - } - - if (request_type != CacheRequestType_NULL) { - // tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address, - // Address(0), request_type, m_replacementPolicy_ptr->getLastAccess(i, j)); - } } - } -} - -void CacheMemory::print(ostream& out) const -{ - out << "Cache dump: " << m_cache_name << endl; - for (int i = 0; i < m_cache_num_sets; i++) { - for (int j = 0; j < m_cache_assoc; j++) { - if (m_cache[i][j] != NULL) { - out << " Index: " << i - << " way: " << j - << " entry: " << *m_cache[i][j] << endl; - } else { - out << " Index: " << i - << " way: " << j - << " entry: NULL" << endl; - } +} + +void +CacheMemory::print(ostream& out) const +{ + out << "Cache dump: " << m_cache_name << endl; + for (int i = 0; i < m_cache_num_sets; i++) { + for (int j = 0; j < m_cache_assoc; j++) { + if (m_cache[i][j] != NULL) { + out << " Index: " << i + << " way: " << j + << " entry: " << *m_cache[i][j] << endl; + } else { + out << " Index: " << i + << " way: " << j + << " entry: NULL" << endl; + } + } } - } } -void CacheMemory::printData(ostream& out) const +void +CacheMemory::printData(ostream& out) const { - out << "printData() not supported" << endl; + out << "printData() not supported" << endl; } -void CacheMemory::clearStats() const +void +CacheMemory::clearStats() const { - m_profiler_ptr->clearStats(); + m_profiler_ptr->clearStats(); } -void CacheMemory::printStats(ostream& out) const +void +CacheMemory::printStats(ostream& out) const { - m_profiler_ptr->printStats(out); + m_profiler_ptr->printStats(out); } -void CacheMemory::getMemoryValue(const Address& addr, char* value, - unsigned int size_in_bytes ){ - AbstractCacheEntry& entry = lookup(line_address(addr)); - unsigned int startByte = addr.getAddress() - line_address(addr).getAddress(); - for(unsigned int i=0; i<size_in_bytes; ++i){ - value[i] = entry.getDataBlk().getByte(i + startByte); - } +void +CacheMemory::getMemoryValue(const Address& addr, char* value, + unsigned size_in_bytes) +{ + AbstractCacheEntry& entry = lookup(line_address(addr)); + unsigned startByte = addr.getAddress() - line_address(addr).getAddress(); + for (unsigned i = 0; i < size_in_bytes; ++i) { + value[i] = entry.getDataBlk().getByte(i + startByte); + } } -void CacheMemory::setMemoryValue(const Address& addr, char* value, - unsigned int size_in_bytes ){ - AbstractCacheEntry& entry = lookup(line_address(addr)); - unsigned int startByte = addr.getAddress() - line_address(addr).getAddress(); - assert(size_in_bytes > 0); - for(unsigned int i=0; i<size_in_bytes; ++i){ - entry.getDataBlk().setByte(i + startByte, value[i]); - } +void +CacheMemory::setMemoryValue(const Address& addr, char* value, + unsigned size_in_bytes) +{ + AbstractCacheEntry& entry = lookup(line_address(addr)); + unsigned startByte = addr.getAddress() - line_address(addr).getAddress(); + assert(size_in_bytes > 0); + for (unsigned i = 0; i < size_in_bytes; ++i) { + entry.getDataBlk().setByte(i + startByte, value[i]); + } - // entry = lookup(line_address(addr)); + // entry = lookup(line_address(addr)); } -void -CacheMemory::setLocked(const Address& address, int context) -{ - DPRINTF(RubyCache, - "Setting Lock for addr: %llx to %d\n", - address, - context); - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - assert(loc != -1); - m_locked[cacheSet][loc] = context; +void +CacheMemory::setLocked(const Address& address, int context) +{ + DPRINTF(RubyCache, "Setting Lock for addr: %x to %d\n", address, context); + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + m_locked[cacheSet][loc] = context; } -void -CacheMemory::clearLocked(const Address& address) +void +CacheMemory::clearLocked(const Address& address) { - DPRINTF(RubyCache, "Clear Lock for addr: %llx\n", address); - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - assert(loc != -1); - m_locked[cacheSet][loc] = -1; + DPRINTF(RubyCache, "Clear Lock for addr: %x\n", address); + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + m_locked[cacheSet][loc] = -1; } bool CacheMemory::isLocked(const Address& address, int context) { - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - assert(loc != -1); - DPRINTF(RubyCache, - "Testing Lock for addr: %llx cur %d con %d\n", - address, - m_locked[cacheSet][loc], - context); - return m_locked[cacheSet][loc] == context; + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + DPRINTF(RubyCache, "Testing Lock for addr: %llx cur %d con %d\n", + address, m_locked[cacheSet][loc], context); + return m_locked[cacheSet][loc] == context; } diff --git a/src/mem/ruby/system/CacheMemory.hh b/src/mem/ruby/system/CacheMemory.hh index 74eb5d68d..bdf2bb25c 100644 --- a/src/mem/ruby/system/CacheMemory.hh +++ b/src/mem/ruby/system/CacheMemory.hh @@ -26,151 +26,144 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * CacheMemory.hh - * - * Description: - * - * $Id: CacheMemory.hh,v 3.7 2004/06/18 20:15:15 beckmann Exp $ - * - */ +#ifndef __MEM_RUBY_SYSTEM_CACHEMEMORY_HH__ +#define __MEM_RUBY_SYSTEM_CACHEMEMORY_HH__ -#ifndef CACHEMEMORY_H -#define CACHEMEMORY_H - -#include "sim/sim_object.hh" -#include "params/RubyCache.hh" +#include <vector> -#include "mem/ruby/common/Global.hh" +#include "base/hashmap.hh" +#include "mem/gems_common/Vector.hh" #include "mem/protocol/AccessPermission.hh" -#include "mem/ruby/common/Address.hh" -#include "mem/ruby/recorder/CacheRecorder.hh" +#include "mem/protocol/CacheMsg.hh" #include "mem/protocol/CacheRequestType.hh" -#include "mem/gems_common/Vector.hh" -#include "mem/ruby/common/DataBlock.hh" #include "mem/protocol/MachineType.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/DataBlock.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/profiler/CacheProfiler.hh" +#include "mem/ruby/recorder/CacheRecorder.hh" +#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh" +#include "mem/ruby/slicc_interface/AbstractController.hh" #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" -#include "mem/ruby/system/PseudoLRUPolicy.hh" #include "mem/ruby/system/LRUPolicy.hh" -#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh" +#include "mem/ruby/system/PseudoLRUPolicy.hh" #include "mem/ruby/system/System.hh" -#include "mem/ruby/slicc_interface/AbstractController.hh" -#include "mem/ruby/profiler/CacheProfiler.hh" -#include "mem/protocol/CacheMsg.hh" -#include "base/hashmap.hh" -#include <vector> - -class CacheMemory : public SimObject { -public: +#include "params/RubyCache.hh" +#include "sim/sim_object.hh" +class CacheMemory : public SimObject +{ + public: typedef RubyCacheParams Params; - // Constructors - CacheMemory(const Params *p); - // CacheMemory(const string & name); - void init(); - - // Destructor - ~CacheMemory(); + CacheMemory(const Params *p); + ~CacheMemory(); - // Public Methods - void printConfig(ostream& out); + void init(); - // perform a cache access and see if we hit or not. Return true on a hit. - bool tryCacheAccess(const Address& address, CacheRequestType type, DataBlock*& data_ptr); + // Public Methods + void printConfig(ostream& out); - // similar to above, but doesn't require full access check - bool testCacheAccess(const Address& address, CacheRequestType type, DataBlock*& data_ptr); + // perform a cache access and see if we hit or not. Return true on a hit. + bool tryCacheAccess(const Address& address, CacheRequestType type, + DataBlock*& data_ptr); - // tests to see if an address is present in the cache - bool isTagPresent(const Address& address) const; + // similar to above, but doesn't require full access check + bool testCacheAccess(const Address& address, CacheRequestType type, + DataBlock*& data_ptr); - // Returns true if there is: - // a) a tag match on this address or there is - // b) an unused line in the same cache "way" - bool cacheAvail(const Address& address) const; + // tests to see if an address is present in the cache + bool isTagPresent(const Address& address) const; - // find an unused entry and sets the tag appropriate for the address - void allocate(const Address& address, AbstractCacheEntry* new_entry); + // Returns true if there is: + // a) a tag match on this address or there is + // b) an unused line in the same cache "way" + bool cacheAvail(const Address& address) const; - // Explicitly free up this address - void deallocate(const Address& address); + // find an unused entry and sets the tag appropriate for the address + void allocate(const Address& address, AbstractCacheEntry* new_entry); - // Returns with the physical address of the conflicting cache line - Address cacheProbe(const Address& address) const; + // Explicitly free up this address + void deallocate(const Address& address); - // looks an address up in the cache - AbstractCacheEntry& lookup(const Address& address); - const AbstractCacheEntry& lookup(const Address& address) const; + // Returns with the physical address of the conflicting cache line + Address cacheProbe(const Address& address) const; - // Get/Set permission of cache block - AccessPermission getPermission(const Address& address) const; - void changePermission(const Address& address, AccessPermission new_perm); + // looks an address up in the cache + AbstractCacheEntry& lookup(const Address& address); + const AbstractCacheEntry& lookup(const Address& address) const; - int getLatency() const { return m_latency; } + // Get/Set permission of cache block + AccessPermission getPermission(const Address& address) const; + void changePermission(const Address& address, AccessPermission new_perm); - // Hook for checkpointing the contents of the cache - void recordCacheContents(CacheRecorder& tr) const; - void setAsInstructionCache(bool is_icache) { m_is_instruction_only_cache = is_icache; } + int getLatency() const { return m_latency; } - // Set this address to most recently used - void setMRU(const Address& address); + // Hook for checkpointing the contents of the cache + void recordCacheContents(CacheRecorder& tr) const; + void + setAsInstructionCache(bool is_icache) + { + m_is_instruction_only_cache = is_icache; + } - void profileMiss(const CacheMsg & msg); + // Set this address to most recently used + void setMRU(const Address& address); - void getMemoryValue(const Address& addr, char* value, - unsigned int size_in_bytes ); - void setMemoryValue(const Address& addr, char* value, - unsigned int size_in_bytes ); + void profileMiss(const CacheMsg & msg); - void setLocked (const Address& addr, int context); - void clearLocked (const Address& addr); - bool isLocked (const Address& addr, int context); - // Print cache contents - void print(ostream& out) const; - void printData(ostream& out) const; + void getMemoryValue(const Address& addr, char* value, + unsigned int size_in_bytes); + void setMemoryValue(const Address& addr, char* value, + unsigned int size_in_bytes); - void clearStats() const; - void printStats(ostream& out) const; + void setLocked (const Address& addr, int context); + void clearLocked (const Address& addr); + bool isLocked (const Address& addr, int context); + // Print cache contents + void print(ostream& out) const; + void printData(ostream& out) const; -private: - // Private Methods + void clearStats() const; + void printStats(ostream& out) const; - // convert a Address to its location in the cache - Index addressToCacheSet(const Address& address) const; + private: + // convert a Address to its location in the cache + Index addressToCacheSet(const Address& address) const; - // Given a cache tag: returns the index of the tag in a set. - // returns -1 if the tag is not found. - int findTagInSet(Index line, const Address& tag) const; - int findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const; + // Given a cache tag: returns the index of the tag in a set. + // returns -1 if the tag is not found. + int findTagInSet(Index line, const Address& tag) const; + int findTagInSetIgnorePermissions(Index cacheSet, + const Address& tag) const; - // Private copy constructor and assignment operator - CacheMemory(const CacheMemory& obj); - CacheMemory& operator=(const CacheMemory& obj); + // Private copy constructor and assignment operator + CacheMemory(const CacheMemory& obj); + CacheMemory& operator=(const CacheMemory& obj); -private: - const string m_cache_name; - int m_latency; + private: + const string m_cache_name; + int m_latency; - // Data Members (m_prefix) - bool m_is_instruction_only_cache; - bool m_is_data_only_cache; + // Data Members (m_prefix) + bool m_is_instruction_only_cache; + bool m_is_data_only_cache; - // The first index is the # of cache lines. - // The second index is the the amount associativity. - m5::hash_map<Address, int> m_tag_index; - Vector<Vector<AbstractCacheEntry*> > m_cache; - Vector<Vector<int> > m_locked; + // The first index is the # of cache lines. + // The second index is the the amount associativity. + m5::hash_map<Address, int> m_tag_index; + Vector<Vector<AbstractCacheEntry*> > m_cache; + Vector<Vector<int> > m_locked; - AbstractReplacementPolicy *m_replacementPolicy_ptr; + AbstractReplacementPolicy *m_replacementPolicy_ptr; - CacheProfiler* m_profiler_ptr; + CacheProfiler* m_profiler_ptr; - int m_cache_size; - string m_policy; - int m_cache_num_sets; - int m_cache_num_set_bits; - int m_cache_assoc; + int m_cache_size; + string m_policy; + int m_cache_num_sets; + int m_cache_num_set_bits; + int m_cache_assoc; }; -#endif //CACHEMEMORY_H +#endif // __MEM_RUBY_SYSTEM_CACHEMEMORY_HH__ diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc index 063b66862..315dab62a 100644 --- a/src/mem/ruby/system/DMASequencer.cc +++ b/src/mem/ruby/system/DMASequencer.cc @@ -26,149 +26,148 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "mem/ruby/system/DMASequencer.hh" -#include "mem/ruby/buffers/MessageBuffer.hh" -#include "mem/ruby/slicc_interface/AbstractController.hh" - -/* SLICC generated types */ #include "mem/protocol/SequencerMsg.hh" #include "mem/protocol/SequencerRequestType.hh" +#include "mem/ruby/buffers/MessageBuffer.hh" +#include "mem/ruby/slicc_interface/AbstractController.hh" +#include "mem/ruby/system/DMASequencer.hh" #include "mem/ruby/system/System.hh" -// -// Fix me: This code needs comments! -// - DMASequencer::DMASequencer(const Params *p) - : RubyPort(p) + : RubyPort(p) { } -void DMASequencer::init() +void +DMASequencer::init() { - RubyPort::init(); - m_is_busy = false; - m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits()); + RubyPort::init(); + m_is_busy = false; + m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits()); } -RequestStatus DMASequencer::makeRequest(const RubyRequest & request) +RequestStatus +DMASequencer::makeRequest(const RubyRequest &request) { - uint64_t paddr = request.paddr; - uint8_t* data = request.data; - int len = request.len; - bool write = false; - switch(request.type) { - case RubyRequestType_LD: - write = false; - break; - case RubyRequestType_ST: - write = true; - break; - case RubyRequestType_NULL: - case RubyRequestType_IFETCH: - case RubyRequestType_Locked_Read: - case RubyRequestType_Locked_Write: - case RubyRequestType_RMW_Read: - case RubyRequestType_RMW_Write: - case RubyRequestType_NUM: - panic("DMASequencer::makeRequest does not support the RubyRequestType"); - return RequestStatus_NULL; - } - - assert(!m_is_busy); // only support one outstanding DMA request - m_is_busy = true; - - active_request.start_paddr = paddr; - active_request.write = write; - active_request.data = data; - active_request.len = len; - active_request.bytes_completed = 0; - active_request.bytes_issued = 0; - active_request.pkt = request.pkt; - - SequencerMsg msg; - msg.getPhysicalAddress() = Address(paddr); - msg.getLineAddress() = line_address(msg.getPhysicalAddress()); - msg.getType() = write ? SequencerRequestType_ST : SequencerRequestType_LD; - int offset = paddr & m_data_block_mask; - - msg.getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ? - len : - RubySystem::getBlockSizeBytes() - offset; - - if (write) { - msg.getDataBlk().setData(data, offset, msg.getLen()); - } - - assert(m_mandatory_q_ptr != NULL); - m_mandatory_q_ptr->enqueue(msg); - active_request.bytes_issued += msg.getLen(); - - return RequestStatus_Issued; + uint64_t paddr = request.paddr; + uint8_t* data = request.data; + int len = request.len; + bool write = false; + switch(request.type) { + case RubyRequestType_LD: + write = false; + break; + case RubyRequestType_ST: + write = true; + break; + case RubyRequestType_NULL: + case RubyRequestType_IFETCH: + case RubyRequestType_Locked_Read: + case RubyRequestType_Locked_Write: + case RubyRequestType_RMW_Read: + case RubyRequestType_RMW_Write: + case RubyRequestType_NUM: + panic("DMASequencer::makeRequest does not support RubyRequestType"); + return RequestStatus_NULL; + } + + assert(!m_is_busy); // only support one outstanding DMA request + m_is_busy = true; + + active_request.start_paddr = paddr; + active_request.write = write; + active_request.data = data; + active_request.len = len; + active_request.bytes_completed = 0; + active_request.bytes_issued = 0; + active_request.pkt = request.pkt; + + SequencerMsg msg; + msg.getPhysicalAddress() = Address(paddr); + msg.getLineAddress() = line_address(msg.getPhysicalAddress()); + msg.getType() = write ? SequencerRequestType_ST : SequencerRequestType_LD; + int offset = paddr & m_data_block_mask; + + msg.getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ? + len : RubySystem::getBlockSizeBytes() - offset; + + if (write) { + msg.getDataBlk().setData(data, offset, msg.getLen()); + } + + assert(m_mandatory_q_ptr != NULL); + m_mandatory_q_ptr->enqueue(msg); + active_request.bytes_issued += msg.getLen(); + + return RequestStatus_Issued; } -void DMASequencer::issueNext() +void +DMASequencer::issueNext() { - assert(m_is_busy == true); - active_request.bytes_completed = active_request.bytes_issued; - if (active_request.len == active_request.bytes_completed) { - ruby_hit_callback(active_request.pkt); - m_is_busy = false; - return; - } - - SequencerMsg msg; - msg.getPhysicalAddress() = Address(active_request.start_paddr + - active_request.bytes_completed); - - assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0); - msg.getLineAddress() = line_address(msg.getPhysicalAddress()); - - msg.getType() = (active_request.write ? SequencerRequestType_ST : - SequencerRequestType_LD); - - msg.getLen() = (active_request.len - - active_request.bytes_completed < RubySystem::getBlockSizeBytes() ? - active_request.len - active_request.bytes_completed : - RubySystem::getBlockSizeBytes()); - - if (active_request.write) { - msg.getDataBlk().setData(&active_request.data[active_request.bytes_completed], - 0, msg.getLen()); - msg.getType() = SequencerRequestType_ST; - } else { - msg.getType() = SequencerRequestType_LD; - } - - assert(m_mandatory_q_ptr != NULL); - m_mandatory_q_ptr->enqueue(msg); - active_request.bytes_issued += msg.getLen(); + assert(m_is_busy == true); + active_request.bytes_completed = active_request.bytes_issued; + if (active_request.len == active_request.bytes_completed) { + ruby_hit_callback(active_request.pkt); + m_is_busy = false; + return; + } + + SequencerMsg msg; + msg.getPhysicalAddress() = Address(active_request.start_paddr + + active_request.bytes_completed); + + assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0); + msg.getLineAddress() = line_address(msg.getPhysicalAddress()); + + msg.getType() = (active_request.write ? SequencerRequestType_ST : + SequencerRequestType_LD); + + msg.getLen() = + (active_request.len - + active_request.bytes_completed < RubySystem::getBlockSizeBytes() ? + active_request.len - active_request.bytes_completed : + RubySystem::getBlockSizeBytes()); + + if (active_request.write) { + msg.getDataBlk(). + setData(&active_request.data[active_request.bytes_completed], + 0, msg.getLen()); + msg.getType() = SequencerRequestType_ST; + } else { + msg.getType() = SequencerRequestType_LD; + } + + assert(m_mandatory_q_ptr != NULL); + m_mandatory_q_ptr->enqueue(msg); + active_request.bytes_issued += msg.getLen(); } -void DMASequencer::dataCallback(const DataBlock & dblk) +void +DMASequencer::dataCallback(const DataBlock & dblk) { - assert(m_is_busy == true); - int len = active_request.bytes_issued - active_request.bytes_completed; - int offset = 0; - if (active_request.bytes_completed == 0) - offset = active_request.start_paddr & m_data_block_mask; - assert( active_request.write == false ); - memcpy(&active_request.data[active_request.bytes_completed], - dblk.getData(offset, len), len); - issueNext(); + assert(m_is_busy == true); + int len = active_request.bytes_issued - active_request.bytes_completed; + int offset = 0; + if (active_request.bytes_completed == 0) + offset = active_request.start_paddr & m_data_block_mask; + assert(active_request.write == false); + memcpy(&active_request.data[active_request.bytes_completed], + dblk.getData(offset, len), len); + issueNext(); } -void DMASequencer::ackCallback() +void +DMASequencer::ackCallback() { - issueNext(); + issueNext(); } -void DMASequencer::printConfig(ostream & out) +void +DMASequencer::printConfig(ostream & out) { - } - DMASequencer * DMASequencerParams::create() { diff --git a/src/mem/ruby/system/DMASequencer.hh b/src/mem/ruby/system/DMASequencer.hh index 24129526a..61d7ef1c6 100644 --- a/src/mem/ruby/system/DMASequencer.hh +++ b/src/mem/ruby/system/DMASequencer.hh @@ -26,48 +26,50 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DMASEQUENCER_H -#define DMASEQUENCER_H +#ifndef __MEM_RUBY_SYSTEM_DMASEQUENCER_HH__ +#define __MEM_RUBY_SYSTEM_DMASEQUENCER_HH__ #include <ostream> + #include "mem/ruby/common/DataBlock.hh" #include "mem/ruby/system/RubyPort.hh" - #include "params/DMASequencer.hh" -struct DMARequest { - uint64_t start_paddr; - int len; - bool write; - int bytes_completed; - int bytes_issued; - uint8* data; - PacketPtr pkt; +struct DMARequest +{ + uint64_t start_paddr; + int len; + bool write; + int bytes_completed; + int bytes_issued; + uint8* data; + PacketPtr pkt; }; -class DMASequencer :public RubyPort { -public: +class DMASequencer : public RubyPort +{ + public: typedef DMASequencerParams Params; - DMASequencer(const Params *); - void init(); - /* external interface */ - RequestStatus makeRequest(const RubyRequest & request); - bool busy() { return m_is_busy;} + DMASequencer(const Params *); + void init(); + /* external interface */ + RequestStatus makeRequest(const RubyRequest & request); + bool busy() { return m_is_busy;} - /* SLICC callback */ - void dataCallback(const DataBlock & dblk); - void ackCallback(); + /* SLICC callback */ + void dataCallback(const DataBlock & dblk); + void ackCallback(); - void printConfig(std::ostream & out); + void printConfig(std::ostream & out); -private: - void issueNext(); + private: + void issueNext(); -private: - bool m_is_busy; - uint64_t m_data_block_mask; - DMARequest active_request; - int num_active_requests; + private: + bool m_is_busy; + uint64_t m_data_block_mask; + DMARequest active_request; + int num_active_requests; }; -#endif // DMACONTROLLER_H +#endif // __MEM_RUBY_SYSTEM_DMASEQUENCER_HH__ diff --git a/src/mem/ruby/system/DirectoryMemory.cc b/src/mem/ruby/system/DirectoryMemory.cc index d8037aec1..93f537090 100644 --- a/src/mem/ruby/system/DirectoryMemory.cc +++ b/src/mem/ruby/system/DirectoryMemory.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,19 +26,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * DirectoryMemory.cc - * - * Description: See DirectoryMemory.hh - * - * $Id$ - * - */ - -#include "mem/ruby/system/System.hh" -#include "mem/ruby/system/DirectoryMemory.hh" -#include "mem/ruby/slicc_interface/RubySlicc_Util.hh" #include "mem/gems_common/util.hh" +#include "mem/ruby/slicc_interface/RubySlicc_Util.hh" +#include "mem/ruby/system/DirectoryMemory.hh" +#include "mem/ruby/system/System.hh" int DirectoryMemory::m_num_directories = 0; int DirectoryMemory::m_num_directories_bits = 0; @@ -58,89 +48,95 @@ DirectoryMemory::DirectoryMemory(const Params *p) m_numa_high_bit = p->numa_high_bit; } -void DirectoryMemory::init() +void +DirectoryMemory::init() { - m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes(); - - if (m_use_map) { - int entry_bits = log_int(m_num_entries); - assert(entry_bits >= m_map_levels); - m_sparseMemory = new SparseMemory(entry_bits, m_map_levels); - } else { - m_entries = new Directory_Entry*[m_num_entries]; - for (int i=0; i < m_num_entries; i++) - m_entries[i] = NULL; - m_ram = g_system_ptr->getMemoryVector(); - } - - m_num_directories++; - m_num_directories_bits = log_int(m_num_directories); - m_total_size_bytes += m_size_bytes; - - if (m_numa_high_bit == 0) { - m_numa_high_bit = RubySystem::getMemorySizeBits(); - } - assert(m_numa_high_bit != 0); + m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes(); + + if (m_use_map) { + int entry_bits = log_int(m_num_entries); + assert(entry_bits >= m_map_levels); + m_sparseMemory = new SparseMemory(entry_bits, m_map_levels); + } else { + m_entries = new Directory_Entry*[m_num_entries]; + for (int i = 0; i < m_num_entries; i++) + m_entries[i] = NULL; + m_ram = g_system_ptr->getMemoryVector(); + } + + m_num_directories++; + m_num_directories_bits = log_int(m_num_directories); + m_total_size_bytes += m_size_bytes; + + if (m_numa_high_bit == 0) { + m_numa_high_bit = RubySystem::getMemorySizeBits(); + } + assert(m_numa_high_bit != 0); } DirectoryMemory::~DirectoryMemory() { - // free up all the directory entries - if (m_entries != NULL) { - for (uint64 i = 0; i < m_num_entries; i++) { - if (m_entries[i] != NULL) { - delete m_entries[i]; - } - } - delete [] m_entries; - } else if (m_use_map) { - delete m_sparseMemory; - } + // free up all the directory entries + if (m_entries != NULL) { + for (uint64 i = 0; i < m_num_entries; i++) { + if (m_entries[i] != NULL) { + delete m_entries[i]; + } + } + delete [] m_entries; + } else if (m_use_map) { + delete m_sparseMemory; + } } -void DirectoryMemory::printConfig(ostream& out) const +void +DirectoryMemory::printConfig(ostream& out) const { - out << "DirectoryMemory module config: " << m_name << endl; - out << " version: " << m_version << endl; - out << " memory_bits: " << m_size_bits << endl; - out << " memory_size_bytes: " << m_size_bytes << endl; - out << " memory_size_Kbytes: " << double(m_size_bytes) / (1<<10) << endl; - out << " memory_size_Mbytes: " << double(m_size_bytes) / (1<<20) << endl; - out << " memory_size_Gbytes: " << double(m_size_bytes) / (1<<30) << endl; + out << "DirectoryMemory module config: " << m_name << endl + << " version: " << m_version << endl + << " memory_bits: " << m_size_bits << endl + << " memory_size_bytes: " << m_size_bytes << endl + << " memory_size_Kbytes: " << double(m_size_bytes) / (1<<10) << endl + << " memory_size_Mbytes: " << double(m_size_bytes) / (1<<20) << endl + << " memory_size_Gbytes: " << double(m_size_bytes) / (1<<30) << endl; } // Static method -void DirectoryMemory::printGlobalConfig(ostream & out) +void +DirectoryMemory::printGlobalConfig(ostream & out) { - out << "DirectoryMemory Global Config: " << endl; - out << " number of directory memories: " << m_num_directories << endl; - if (m_num_directories > 1) { - out << " number of selection bits: " << m_num_directories_bits << endl; - out << " selection bits: " << m_numa_high_bit - << "-" << m_numa_high_bit-m_num_directories_bits - << endl; - } - out << " total memory size bytes: " << m_total_size_bytes << endl; - out << " total memory bits: " << log_int(m_total_size_bytes) << endl; - + out << "DirectoryMemory Global Config: " << endl; + out << " number of directory memories: " << m_num_directories << endl; + if (m_num_directories > 1) { + out << " number of selection bits: " << m_num_directories_bits << endl + << " selection bits: " << m_numa_high_bit + << "-" << m_numa_high_bit-m_num_directories_bits + << endl; + } + out << " total memory size bytes: " << m_total_size_bytes << endl; + out << " total memory bits: " << log_int(m_total_size_bytes) << endl; } -uint64 DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address) +uint64 +DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address) { - if (m_num_directories_bits == 0) return 0; - uint64 ret = address.bitSelect(m_numa_high_bit - m_num_directories_bits, - m_numa_high_bit); - return ret; + if (m_num_directories_bits == 0) + return 0; + + uint64 ret = address.bitSelect(m_numa_high_bit - m_num_directories_bits, + m_numa_high_bit); + return ret; } -// Public method -bool DirectoryMemory::isPresent(PhysAddress address) +bool +DirectoryMemory::isPresent(PhysAddress address) { - bool ret = (mapAddressToDirectoryVersion(address) == m_version); - return ret; + bool ret = (mapAddressToDirectoryVersion(address) == m_version); + return ret; } -uint64 DirectoryMemory::mapAddressToLocalIdx(PhysAddress address) +uint64 +DirectoryMemory::mapAddressToLocalIdx(PhysAddress address) { uint64 ret = address.bitRemove(m_numa_high_bit - m_num_directories_bits, m_numa_high_bit) @@ -148,98 +144,99 @@ uint64 DirectoryMemory::mapAddressToLocalIdx(PhysAddress address) return ret; } -Directory_Entry& DirectoryMemory::lookup(PhysAddress address) +Directory_Entry& +DirectoryMemory::lookup(PhysAddress address) { - assert(isPresent(address)); - Directory_Entry* entry; - uint64 idx; - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - - if (m_use_map) { - if (m_sparseMemory->exist(address)) { - entry = m_sparseMemory->lookup(address); - assert(entry != NULL); - } else { - // - // Note: SparseMemory internally creates a new Directory Entry - // - m_sparseMemory->add(address); - entry = m_sparseMemory->lookup(address); - } - } else { - idx = mapAddressToLocalIdx(address); - assert(idx < m_num_entries); - entry = m_entries[idx]; + assert(isPresent(address)); + Directory_Entry* entry; + uint64 idx; + DEBUG_EXPR(CACHE_COMP, HighPrio, address); - if (entry == NULL) { - entry = new Directory_Entry(); - entry->getDataBlk().assign(m_ram->getBlockPtr(address)); - m_entries[idx] = entry; + if (m_use_map) { + if (m_sparseMemory->exist(address)) { + entry = m_sparseMemory->lookup(address); + assert(entry != NULL); + } else { + // Note: SparseMemory internally creates a new Directory Entry + m_sparseMemory->add(address); + entry = m_sparseMemory->lookup(address); + } + } else { + idx = mapAddressToLocalIdx(address); + assert(idx < m_num_entries); + entry = m_entries[idx]; + + if (entry == NULL) { + entry = new Directory_Entry(); + entry->getDataBlk().assign(m_ram->getBlockPtr(address)); + m_entries[idx] = entry; + } } - } - return (*entry); -} -/* -Directory_Entry& DirectoryMemory::lookup(PhysAddress address) -{ - assert(isPresent(address)); - Index index = address.memoryModuleIndex(); - - if (index < 0 || index > m_size) { - WARN_EXPR(address.getAddress()); - WARN_EXPR(index); - WARN_EXPR(m_size); - ERROR_MSG("Directory Memory Assertion: accessing memory out of range."); - } - Directory_Entry* entry = m_entries[index]; - - // allocate the directory entry on demand. - if (entry == NULL) { - entry = new Directory_Entry; - entry->getDataBlk().assign(m_ram->getBlockPtr(address)); - - // store entry to the table - m_entries[index] = entry; - } - - return (*entry); + return *entry; } -*/ -void DirectoryMemory::invalidateBlock(PhysAddress address) +#if 0 +Directory_Entry& +DirectoryMemory::lookup(PhysAddress address) { - - if (m_use_map) { - assert(m_sparseMemory->exist(address)); - m_sparseMemory->remove(address); - } - /* - else { assert(isPresent(address)); - Index index = address.memoryModuleIndex(); - + if (index < 0 || index > m_size) { - ERROR_MSG("Directory Memory Assertion: accessing memory out of range."); + WARN_EXPR(address.getAddress()); + WARN_EXPR(index); + WARN_EXPR(m_size); + ERROR_MSG("Directory Memory Assertion: accessing memory out of range"); } + Directory_Entry* entry = m_entries[index]; - if(m_entries[index] != NULL){ - delete m_entries[index]; - m_entries[index] = NULL; - } - } - */ + // allocate the directory entry on demand. + if (entry == NULL) { + entry = new Directory_Entry; + entry->getDataBlk().assign(m_ram->getBlockPtr(address)); + // store entry to the table + m_entries[index] = entry; + } + return *entry; } +#endif -void DirectoryMemory::print(ostream& out) const +void +DirectoryMemory::invalidateBlock(PhysAddress address) { + if (m_use_map) { + assert(m_sparseMemory->exist(address)); + m_sparseMemory->remove(address); + } +#if 0 + else { + assert(isPresent(address)); + + Index index = address.memoryModuleIndex(); + + if (index < 0 || index > m_size) { + ERROR_MSG("Directory Memory Assertion: " + "accessing memory out of range."); + } + + if (m_entries[index] != NULL){ + delete m_entries[index]; + m_entries[index] = NULL; + } + } +#endif +} +void +DirectoryMemory::print(ostream& out) const +{ } -void DirectoryMemory::printStats(ostream& out) const +void +DirectoryMemory::printStats(ostream& out) const { if (m_use_map) { m_sparseMemory->printStats(out); diff --git a/src/mem/ruby/system/DirectoryMemory.hh b/src/mem/ruby/system/DirectoryMemory.hh index 8b23ced02..4e7bfc4f6 100644 --- a/src/mem/ruby/system/DirectoryMemory.hh +++ b/src/mem/ruby/system/DirectoryMemory.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,94 +26,74 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * DirectoryMemory.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef DIRECTORYMEMORY_H -#define DIRECTORYMEMORY_H +#ifndef __MEM_RUBY_SYSTEM_DIRECTORYMEMORY_HH__ +#define __MEM_RUBY_SYSTEM_DIRECTORYMEMORY_HH__ -#include "mem/ruby/common/Global.hh" +#include "mem/protocol/Directory_Entry.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/system/MemoryVector.hh" -#include "mem/protocol/Directory_Entry.hh" -#include "sim/sim_object.hh" -#include "params/RubyDirectoryMemory.hh" #include "mem/ruby/system/SparseMemory.hh" +#include "params/RubyDirectoryMemory.hh" +#include "sim/sim_object.hh" -class DirectoryMemory : public SimObject { -public: - // Constructors +class DirectoryMemory : public SimObject +{ + public: typedef RubyDirectoryMemoryParams Params; DirectoryMemory(const Params *p); - void init(); - // DirectoryMemory(int version); - - // Destructor - ~DirectoryMemory(); - - uint64 mapAddressToLocalIdx(PhysAddress address); - static uint64 mapAddressToDirectoryVersion(PhysAddress address); - - bool isSparseImplementation() { return m_use_map; } - uint64 getSize() { return m_size_bytes; } - - // Public Methods - void printConfig(ostream& out) const; - static void printGlobalConfig(ostream & out); - bool isPresent(PhysAddress address); - Directory_Entry& lookup(PhysAddress address); - - void invalidateBlock(PhysAddress address); - - void print(ostream& out) const; - void printStats(ostream& out) const; - -private: - // Private Methods - - // Private copy constructor and assignment operator - DirectoryMemory(const DirectoryMemory& obj); - DirectoryMemory& operator=(const DirectoryMemory& obj); - -private: - const string m_name; - // Data Members (m_ prefix) - Directory_Entry **m_entries; - // int m_size; // # of memory module blocks this directory is responsible for - uint64 m_size_bytes; - uint64 m_size_bits; - uint64 m_num_entries; - int m_version; - - static int m_num_directories; - static int m_num_directories_bits; - static uint64_t m_total_size_bytes; - static int m_numa_high_bit; - - MemoryVector* m_ram; - SparseMemory* m_sparseMemory; - bool m_use_map; - int m_map_levels; + ~DirectoryMemory(); + + void init(); + + uint64 mapAddressToLocalIdx(PhysAddress address); + static uint64 mapAddressToDirectoryVersion(PhysAddress address); + + bool isSparseImplementation() { return m_use_map; } + uint64 getSize() { return m_size_bytes; } + + void printConfig(ostream& out) const; + static void printGlobalConfig(ostream & out); + bool isPresent(PhysAddress address); + Directory_Entry& lookup(PhysAddress address); + + void invalidateBlock(PhysAddress address); + + void print(ostream& out) const; + void printStats(ostream& out) const; + + private: + // Private copy constructor and assignment operator + DirectoryMemory(const DirectoryMemory& obj); + DirectoryMemory& operator=(const DirectoryMemory& obj); + + private: + const string m_name; + Directory_Entry **m_entries; + // int m_size; // # of memory module blocks this directory is + // responsible for + uint64 m_size_bytes; + uint64 m_size_bits; + uint64 m_num_entries; + int m_version; + + static int m_num_directories; + static int m_num_directories_bits; + static uint64_t m_total_size_bytes; + static int m_numa_high_bit; + + MemoryVector* m_ram; + SparseMemory* m_sparseMemory; + bool m_use_map; + int m_map_levels; }; -// Output operator declaration -ostream& operator<<(ostream& out, const DirectoryMemory& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const DirectoryMemory& obj) +inline ostream& +operator<<(ostream& out, const DirectoryMemory& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -#endif //DIRECTORYMEMORY_H +#endif // __MEM_RUBY_SYSTEM_DIRECTORYMEMORY_HH__ diff --git a/src/mem/ruby/system/LRUPolicy.hh b/src/mem/ruby/system/LRUPolicy.hh index 55b1eec6e..b1b9d7478 100644 --- a/src/mem/ruby/system/LRUPolicy.hh +++ b/src/mem/ruby/system/LRUPolicy.hh @@ -26,26 +26,26 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LRUPOLICY_H -#define LRUPOLICY_H +#ifndef __MEM_RUBY_SYSTEM_LRUPOLICY_HH__ +#define __MEM_RUBY_SYSTEM_LRUPOLICY_HH__ #include "mem/ruby/system/AbstractReplacementPolicy.hh" /* Simple true LRU replacement policy */ -class LRUPolicy : public AbstractReplacementPolicy { - public: - - LRUPolicy(Index num_sets, Index assoc); - ~LRUPolicy(); +class LRUPolicy : public AbstractReplacementPolicy +{ + public: + LRUPolicy(Index num_sets, Index assoc); + ~LRUPolicy(); - void touch(Index set, Index way, Time time); - Index getVictim(Index set) const; + void touch(Index set, Index way, Time time); + Index getVictim(Index set) const; }; inline LRUPolicy::LRUPolicy(Index num_sets, Index assoc) - : AbstractReplacementPolicy(num_sets, assoc) + : AbstractReplacementPolicy(num_sets, assoc) { } @@ -54,39 +54,42 @@ LRUPolicy::~LRUPolicy() { } -inline -void LRUPolicy::touch(Index set, Index index, Time time){ - assert(index >= 0 && index < m_assoc); - assert(set >= 0 && set < m_num_sets); +inline void +LRUPolicy::touch(Index set, Index index, Time time) +{ + assert(index >= 0 && index < m_assoc); + assert(set >= 0 && set < m_num_sets); - m_last_ref_ptr[set][index] = time; + m_last_ref_ptr[set][index] = time; } -inline -Index LRUPolicy::getVictim(Index set) const { - // assert(m_assoc != 0); - Time time, smallest_time; - Index smallest_index; - - smallest_index = 0; - smallest_time = m_last_ref_ptr[set][0]; - - for (unsigned int i=0; i < m_assoc; i++) { - time = m_last_ref_ptr[set][i]; - //assert(m_cache[cacheSet][i].m_Permission != AccessPermission_NotPresent); - - if (time < smallest_time){ - smallest_index = i; - smallest_time = time; +inline Index +LRUPolicy::getVictim(Index set) const +{ + // assert(m_assoc != 0); + Time time, smallest_time; + Index smallest_index; + + smallest_index = 0; + smallest_time = m_last_ref_ptr[set][0]; + + for (unsigned i = 0; i < m_assoc; i++) { + time = m_last_ref_ptr[set][i]; + // assert(m_cache[cacheSet][i].m_Permission != + // AccessPermission_NotPresent); + + if (time < smallest_time) { + smallest_index = i; + smallest_time = time; + } } - } - // DEBUG_EXPR(CACHE_COMP, MedPrio, cacheSet); - // DEBUG_EXPR(CACHE_COMP, MedPrio, smallest_index); - // DEBUG_EXPR(CACHE_COMP, MedPrio, m_cache[cacheSet][smallest_index]); - // DEBUG_EXPR(CACHE_COMP, MedPrio, *this); + // DEBUG_EXPR(CACHE_COMP, MedPrio, cacheSet); + // DEBUG_EXPR(CACHE_COMP, MedPrio, smallest_index); + // DEBUG_EXPR(CACHE_COMP, MedPrio, m_cache[cacheSet][smallest_index]); + // DEBUG_EXPR(CACHE_COMP, MedPrio, *this); - return smallest_index; + return smallest_index; } -#endif // PSEUDOLRUBITS_H +#endif // __MEM_RUBY_SYSTEM_LRUPOLICY_HH__ diff --git a/src/mem/ruby/system/MachineID.hh b/src/mem/ruby/system/MachineID.hh index 9da71f349..716196248 100644 --- a/src/mem/ruby/system/MachineID.hh +++ b/src/mem/ruby/system/MachineID.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,66 +26,55 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * NodeID.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef MACHINEID_H -#define MACHINEID_H +#ifndef __MEM_RUBY_SYSTEM_MACHINEID_HH__ +#define __MEM_RUBY_SYSTEM_MACHINEID_HH__ #include <iostream> #include <string> -#include "mem/ruby/common/Global.hh" #include "mem/gems_common/util.hh" #include "mem/protocol/MachineType.hh" +#include "mem/ruby/common/Global.hh" -struct MachineID { - MachineType type; - int num; // range: 0 ... number of this machine's components in the system - 1 +struct MachineID +{ + MachineType type; + int num; // range: 0 ... number of this machine's components in system - 1 }; -extern inline -std::string MachineIDToString (MachineID machine) { - return MachineType_to_string(machine.type)+"_"+int_to_string(machine.num); +inline std::string +MachineIDToString(MachineID machine) +{ + return MachineType_to_string(machine.type)+"_"+int_to_string(machine.num); } -extern inline -bool operator==(const MachineID & obj1, const MachineID & obj2) +inline bool +operator==(const MachineID & obj1, const MachineID & obj2) { - return (obj1.type == obj2.type && obj1.num == obj2.num); + return (obj1.type == obj2.type && obj1.num == obj2.num); } -extern inline -bool operator!=(const MachineID & obj1, const MachineID & obj2) +inline bool +operator!=(const MachineID & obj1, const MachineID & obj2) { - return (obj1.type != obj2.type || obj1.num != obj2.num); + return (obj1.type != obj2.type || obj1.num != obj2.num); } // Output operator declaration std::ostream& operator<<(std::ostream& out, const MachineID& obj); -// ******************* Definitions ******************* - -// Output operator definition -extern inline -std::ostream& operator<<(std::ostream& out, const MachineID& obj) +inline std::ostream& +operator<<(std::ostream& out, const MachineID& obj) { - if ((obj.type < MachineType_NUM) && (obj.type >= MachineType_FIRST)) { - out << MachineType_to_string(obj.type); - } else { - out << "NULL"; - } - out << "-"; - out << obj.num; - out << std::flush; - return out; + if ((obj.type < MachineType_NUM) && (obj.type >= MachineType_FIRST)) { + out << MachineType_to_string(obj.type); + } else { + out << "NULL"; + } + out << "-"; + out << obj.num; + out << std::flush; + return out; } - -#endif //MACHINEID_H +#endif // __MEM_RUBY_SYSTEM_MACHINEID_HH__ diff --git a/src/mem/ruby/system/MemoryControl.cc b/src/mem/ruby/system/MemoryControl.cc index 0f12efc36..963cc3947 100644 --- a/src/mem/ruby/system/MemoryControl.cc +++ b/src/mem/ruby/system/MemoryControl.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -28,8 +27,6 @@ */ /* - * MemoryControl.cc - * * Description: This module simulates a basic DDR-style memory controller * (and can easily be extended to do FB-DIMM as well). * @@ -105,25 +102,21 @@ * then no more than four activates may happen within any 16 cycle window. * Refreshes are included in the activates. * - * - * $Id: $ - * */ -#include "mem/ruby/common/Global.hh" +#include <list> + +#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 "mem/ruby/network/Network.hh" #include "mem/ruby/profiler/Profiler.hh" -#include "mem/ruby/system/System.hh" -#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" #include "mem/ruby/slicc_interface/NetworkMessage.hh" -#include "mem/ruby/network/Network.hh" - -#include "mem/ruby/common/Consumer.hh" - +#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" #include "mem/ruby/system/MemoryControl.hh" - -#include <list> +#include "mem/ruby/system/System.hh" class Consumer; @@ -140,11 +133,12 @@ class Consumer; // Output operator definition -ostream& operator<<(ostream& out, const MemoryControl& obj) +ostream& +operator<<(ostream& out, const MemoryControl& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } @@ -178,471 +172,509 @@ MemoryControl::MemoryControl(const Params *p) m_dimms_per_channel); } -void MemoryControl::init() +void +MemoryControl::init() { - m_msg_counter = 0; - - m_debug = 0; - - assert(m_tFaw <= 62); // must fit in a uint64 shift register - - m_total_banks = m_banks_per_rank * m_ranks_per_dimm * m_dimms_per_channel; - m_total_ranks = m_ranks_per_dimm * m_dimms_per_channel; - m_refresh_period_system = m_refresh_period / m_total_banks; - - m_bankQueues = new list<MemoryNode> [m_total_banks]; - assert(m_bankQueues); - - m_bankBusyCounter = new int [m_total_banks]; - assert(m_bankBusyCounter); - - m_oldRequest = new int [m_total_banks]; - assert(m_oldRequest); - - for (int i=0; i<m_total_banks; i++) { - m_bankBusyCounter[i] = 0; - m_oldRequest[i] = 0; - } - - m_busBusyCounter_Basic = 0; - m_busBusyCounter_Write = 0; - m_busBusyCounter_ReadNewRank = 0; - m_busBusy_WhichRank = 0; - - m_roundRobin = 0; - m_refresh_count = 1; - m_need_refresh = 0; - m_refresh_bank = 0; - m_awakened = 0; - m_idleCount = 0; - m_ageCounter = 0; - - // Each tfaw shift register keeps a moving bit pattern - // which shows when recent activates have occurred. - // m_tfaw_count keeps track of how many 1 bits are set - // in each shift register. When m_tfaw_count is >= 4, - // new activates are not allowed. - m_tfaw_shift = new uint64 [m_total_ranks]; - m_tfaw_count = new int [m_total_ranks]; - for (int i=0; i<m_total_ranks; i++) { - m_tfaw_shift[i] = 0; - m_tfaw_count[i] = 0; - } -} + m_msg_counter = 0; + m_debug = 0; -// DESTRUCTOR + assert(m_tFaw <= 62); // must fit in a uint64 shift register -MemoryControl::~MemoryControl () { - delete [] m_bankQueues; - delete [] m_bankBusyCounter; - delete [] m_oldRequest; - delete m_profiler_ptr; -} + m_total_banks = m_banks_per_rank * m_ranks_per_dimm * m_dimms_per_channel; + m_total_ranks = m_ranks_per_dimm * m_dimms_per_channel; + m_refresh_period_system = m_refresh_period / m_total_banks; + m_bankQueues = new list<MemoryNode> [m_total_banks]; + assert(m_bankQueues); -// PUBLIC METHODS + m_bankBusyCounter = new int [m_total_banks]; + assert(m_bankBusyCounter); -// enqueue new request from directory - -void MemoryControl::enqueue (const MsgPtr& message, int latency) { - Time current_time = g_eventQueue_ptr->getTime(); - Time arrival_time = current_time + latency; - const MemoryMsg* memMess = dynamic_cast<const MemoryMsg*>(message.ref()); - physical_address_t addr = memMess->getAddress().getAddress(); - MemoryRequestType type = memMess->getType(); - bool is_mem_read = (type == MemoryRequestType_MEMORY_READ); - MemoryNode thisReq(arrival_time, message, addr, is_mem_read, !is_mem_read); - enqueueMemRef(thisReq); -} - -// Alternate entry point used when we already have a MemoryNode structure built. - -void MemoryControl::enqueueMemRef (MemoryNode& memRef) { - m_msg_counter++; - memRef.m_msg_counter = m_msg_counter; - Time arrival_time = memRef.m_time; - uint64 at = arrival_time; - bool is_mem_read = memRef.m_is_mem_read; - physical_address_t addr = memRef.m_addr; - int bank = getBank(addr); - if (m_debug) { - printf("New memory request%7d: 0x%08llx %c arrived at %10lld ", m_msg_counter, addr, is_mem_read? 'R':'W', at); - printf("bank =%3x\n", bank); - } - - m_profiler_ptr->profileMemReq(bank); - m_input_queue.push_back(memRef); - if (!m_awakened) { - g_eventQueue_ptr->scheduleEvent(this, 1); - m_awakened = 1; - } -} + m_oldRequest = new int [m_total_banks]; + assert(m_oldRequest); + for (int i = 0; i < m_total_banks; i++) { + m_bankBusyCounter[i] = 0; + m_oldRequest[i] = 0; + } + m_busBusyCounter_Basic = 0; + m_busBusyCounter_Write = 0; + m_busBusyCounter_ReadNewRank = 0; + m_busBusy_WhichRank = 0; -// dequeue, peek, and isReady are used to transfer completed requests -// back to the directory + m_roundRobin = 0; + m_refresh_count = 1; + m_need_refresh = 0; + m_refresh_bank = 0; + m_awakened = 0; + m_idleCount = 0; + m_ageCounter = 0; -void MemoryControl::dequeue () { - assert(isReady()); - m_response_queue.pop_front(); + // Each tfaw shift register keeps a moving bit pattern + // which shows when recent activates have occurred. + // m_tfaw_count keeps track of how many 1 bits are set + // in each shift register. When m_tfaw_count is >= 4, + // new activates are not allowed. + m_tfaw_shift = new uint64[m_total_ranks]; + m_tfaw_count = new int[m_total_ranks]; + for (int i = 0; i < m_total_ranks; i++) { + m_tfaw_shift[i] = 0; + m_tfaw_count[i] = 0; + } } - -const Message* MemoryControl::peek () { - MemoryNode node = peekNode(); - Message* msg_ptr = node.m_msgptr.ref(); - assert(msg_ptr != NULL); - return msg_ptr; +MemoryControl::~MemoryControl() +{ + delete [] m_bankQueues; + delete [] m_bankBusyCounter; + delete [] m_oldRequest; + delete m_profiler_ptr; } - -MemoryNode MemoryControl::peekNode () { - assert(isReady()); - MemoryNode req = m_response_queue.front(); - uint64 returnTime = req.m_time; - if (m_debug) { - printf("Old memory request%7d: 0x%08llx %c peeked at %10lld\n", - req.m_msg_counter, req.m_addr, req.m_is_mem_read? 'R':'W', returnTime); - } - return req; +// enqueue new request from directory +void +MemoryControl::enqueue(const MsgPtr& message, int latency) +{ + Time current_time = g_eventQueue_ptr->getTime(); + Time arrival_time = current_time + latency; + const MemoryMsg* memMess = dynamic_cast<const MemoryMsg*>(message.ref()); + physical_address_t addr = memMess->getAddress().getAddress(); + MemoryRequestType type = memMess->getType(); + bool is_mem_read = (type == MemoryRequestType_MEMORY_READ); + MemoryNode thisReq(arrival_time, message, addr, is_mem_read, !is_mem_read); + enqueueMemRef(thisReq); } +// Alternate entry point used when we already have a MemoryNode +// structure built. +void +MemoryControl::enqueueMemRef(MemoryNode& memRef) +{ + m_msg_counter++; + memRef.m_msg_counter = m_msg_counter; + Time arrival_time = memRef.m_time; + uint64 at = arrival_time; + bool is_mem_read = memRef.m_is_mem_read; + physical_address_t addr = memRef.m_addr; + int bank = getBank(addr); + if (m_debug) { + cprintf("New memory request%7d: %#08x %c arrived at %10d bank = %3x\n", + m_msg_counter, addr, is_mem_read? 'R':'W', at, bank); + } -bool MemoryControl::isReady () { - return ((!m_response_queue.empty()) && - (m_response_queue.front().m_time <= g_eventQueue_ptr->getTime())); + m_profiler_ptr->profileMemReq(bank); + m_input_queue.push_back(memRef); + if (!m_awakened) { + g_eventQueue_ptr->scheduleEvent(this, 1); + m_awakened = 1; + } } -void MemoryControl::setConsumer (Consumer* consumer_ptr) { - m_consumer_ptr = consumer_ptr; +// dequeue, peek, and isReady are used to transfer completed requests +// back to the directory +void +MemoryControl::dequeue() +{ + assert(isReady()); + m_response_queue.pop_front(); } -void MemoryControl::print (ostream& out) const { +const Message* +MemoryControl::peek() +{ + MemoryNode node = peekNode(); + Message* msg_ptr = node.m_msgptr.ref(); + assert(msg_ptr != NULL); + return msg_ptr; } - -void MemoryControl::printConfig (ostream& out) { - out << "Memory Control " << name() << ":" << endl; - out << " Ruby cycles per memory cycle: " << m_mem_bus_cycle_multiplier << endl; - out << " Basic read latency: " << m_mem_ctl_latency << endl; - if (m_mem_fixed_delay) { - out << " Fixed Latency mode: Added cycles = " << m_mem_fixed_delay << endl; - } else { - out << " Bank busy time: " << m_bank_busy_time << " memory cycles" << endl; - out << " Memory channel busy time: " << m_basic_bus_busy_time << endl; - out << " Dead cycles between reads to different ranks: " << m_rank_rank_delay << endl; - out << " Dead cycle between a read and a write: " << m_read_write_delay << endl; - out << " tFaw (four-activate) window: " << m_tFaw << endl; - } - out << " Banks per rank: " << m_banks_per_rank << endl; - out << " Ranks per DIMM: " << m_ranks_per_dimm << endl; - out << " DIMMs per channel: " << m_dimms_per_channel << endl; - out << " LSB of bank field in address: " << m_bank_bit_0 << endl; - out << " LSB of rank field in address: " << m_rank_bit_0 << endl; - out << " LSB of DIMM field in address: " << m_dimm_bit_0 << endl; - out << " Max size of each bank queue: " << m_bank_queue_size << endl; - out << " Refresh period (within one bank): " << m_refresh_period << endl; - out << " Arbitration randomness: " << m_mem_random_arbitrate << endl; +MemoryNode +MemoryControl::peekNode() +{ + assert(isReady()); + MemoryNode req = m_response_queue.front(); + uint64 returnTime = req.m_time; + if (m_debug) { + cprintf("Old memory request%7d: %#08x %c peeked at %10d\n", + req.m_msg_counter, req.m_addr, req.m_is_mem_read ? 'R':'W', + returnTime); + } + return req; } +bool +MemoryControl::isReady() +{ + return ((!m_response_queue.empty()) && + (m_response_queue.front().m_time <= g_eventQueue_ptr->getTime())); +} -void MemoryControl::setDebug (int debugFlag) { - m_debug = debugFlag; +void +MemoryControl::setConsumer(Consumer* consumer_ptr) +{ + m_consumer_ptr = consumer_ptr; } -void MemoryControl::clearStats() const +void +MemoryControl::print(ostream& out) const { - m_profiler_ptr->clearStats(); } -void MemoryControl::printStats(ostream& out) const +void +MemoryControl::printConfig(ostream& out) { - m_profiler_ptr->printStats(out); + out << "Memory Control " << name() << ":" << endl; + out << " Ruby cycles per memory cycle: " << m_mem_bus_cycle_multiplier + << endl; + out << " Basic read latency: " << m_mem_ctl_latency << endl; + if (m_mem_fixed_delay) { + out << " Fixed Latency mode: Added cycles = " << m_mem_fixed_delay + << endl; + } else { + out << " Bank busy time: " << m_bank_busy_time << " memory cycles" + << endl; + out << " Memory channel busy time: " << m_basic_bus_busy_time << endl; + out << " Dead cycles between reads to different ranks: " + << m_rank_rank_delay << endl; + out << " Dead cycle between a read and a write: " + << m_read_write_delay << endl; + out << " tFaw (four-activate) window: " << m_tFaw << endl; + } + out << " Banks per rank: " << m_banks_per_rank << endl; + out << " Ranks per DIMM: " << m_ranks_per_dimm << endl; + out << " DIMMs per channel: " << m_dimms_per_channel << endl; + out << " LSB of bank field in address: " << m_bank_bit_0 << endl; + out << " LSB of rank field in address: " << m_rank_bit_0 << endl; + out << " LSB of DIMM field in address: " << m_dimm_bit_0 << endl; + out << " Max size of each bank queue: " << m_bank_queue_size << endl; + out << " Refresh period (within one bank): " << m_refresh_period << endl; + out << " Arbitration randomness: " << m_mem_random_arbitrate << endl; } +void +MemoryControl::setDebug(int debugFlag) +{ + m_debug = debugFlag; +} -// **************************************************************** +void +MemoryControl::clearStats() const +{ + m_profiler_ptr->clearStats(); +} -// PRIVATE METHODS +void +MemoryControl::printStats(ostream& out) const +{ + m_profiler_ptr->printStats(out); +} // Queue up a completed request to send back to directory +void +MemoryControl::enqueueToDirectory(MemoryNode req, int latency) +{ + Time arrival_time = g_eventQueue_ptr->getTime() + + (latency * m_mem_bus_cycle_multiplier); + req.m_time = arrival_time; + m_response_queue.push_back(req); -void MemoryControl::enqueueToDirectory (MemoryNode req, int latency) { - Time arrival_time = g_eventQueue_ptr->getTime() - + (latency * m_mem_bus_cycle_multiplier); - req.m_time = arrival_time; - m_response_queue.push_back(req); - - // schedule the wake up - g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, arrival_time); + // schedule the wake up + g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, arrival_time); } - - // getBank returns an integer that is unique for each // bank across this memory controller. - -int MemoryControl::getBank (physical_address_t addr) { - int dimm = (addr >> m_dimm_bit_0) & (m_dimms_per_channel - 1); - int rank = (addr >> m_rank_bit_0) & (m_ranks_per_dimm - 1); - int bank = (addr >> m_bank_bit_0) & (m_banks_per_rank - 1); - return (dimm * m_ranks_per_dimm * m_banks_per_rank) - + (rank * m_banks_per_rank) - + bank; +int +MemoryControl::getBank(physical_address_t addr) +{ + int dimm = (addr >> m_dimm_bit_0) & (m_dimms_per_channel - 1); + int rank = (addr >> m_rank_bit_0) & (m_ranks_per_dimm - 1); + int bank = (addr >> m_bank_bit_0) & (m_banks_per_rank - 1); + return (dimm * m_ranks_per_dimm * m_banks_per_rank) + + (rank * m_banks_per_rank) + + bank; } // getRank returns an integer that is unique for each rank // and independent of individual bank. - -int MemoryControl::getRank (int bank) { - int rank = (bank / m_banks_per_rank); - assert (rank < (m_ranks_per_dimm * m_dimms_per_channel)); - return rank; +int +MemoryControl::getRank(int bank) +{ + int rank = (bank / m_banks_per_rank); + assert (rank < (m_ranks_per_dimm * m_dimms_per_channel)); + return rank; } - // queueReady determines if the head item in a bank queue // can be issued this cycle +bool +MemoryControl::queueReady(int bank) +{ + if ((m_bankBusyCounter[bank] > 0) && !m_mem_fixed_delay) { + m_profiler_ptr->profileMemBankBusy(); +#if 0 + if (m_debug) + printf(" bank %x busy %d\n", bank, m_bankBusyCounter[bank]); +#endif + return false; + } -bool MemoryControl::queueReady (int bank) { - if ((m_bankBusyCounter[bank] > 0) && !m_mem_fixed_delay) { - m_profiler_ptr->profileMemBankBusy(); - //if (m_debug) printf(" bank %x busy %d\n", bank, m_bankBusyCounter[bank]); - return false; - } - if (m_mem_random_arbitrate >= 2) { - if ((random() % 100) < m_mem_random_arbitrate) { - m_profiler_ptr->profileMemRandBusy(); - return false; + if (m_mem_random_arbitrate >= 2) { + if ((random() % 100) < m_mem_random_arbitrate) { + m_profiler_ptr->profileMemRandBusy(); + return false; + } } - } - if (m_mem_fixed_delay) return true; - if ((m_ageCounter > (2 * m_bank_busy_time)) && !m_oldRequest[bank]) { - m_profiler_ptr->profileMemNotOld(); - return false; - } - if (m_busBusyCounter_Basic == m_basic_bus_busy_time) { - // Another bank must have issued this same cycle. - // For profiling, we count this as an arb wait rather than - // a bus wait. This is a little inaccurate since it MIGHT - // have also been blocked waiting for a read-write or a - // read-read instead, but it's pretty close. - m_profiler_ptr->profileMemArbWait(1); - return false; - } - if (m_busBusyCounter_Basic > 0) { - m_profiler_ptr->profileMemBusBusy(); - return false; - } - int rank = getRank(bank); - if (m_tfaw_count[rank] >= ACTIVATE_PER_TFAW) { - m_profiler_ptr->profileMemTfawBusy(); - return false; - } - bool write = !m_bankQueues[bank].front().m_is_mem_read; - if (write && (m_busBusyCounter_Write > 0)) { - m_profiler_ptr->profileMemReadWriteBusy(); - return false; - } - if (!write && (rank != m_busBusy_WhichRank) - && (m_busBusyCounter_ReadNewRank > 0)) { - m_profiler_ptr->profileMemDataBusBusy(); - return false; - } - return true; -} + if (m_mem_fixed_delay) + return true; -// issueRefresh checks to see if this bank has a refresh scheduled -// and, if so, does the refresh and returns true + if ((m_ageCounter > (2 * m_bank_busy_time)) && !m_oldRequest[bank]) { + m_profiler_ptr->profileMemNotOld(); + return false; + } -bool MemoryControl::issueRefresh (int bank) { - if (!m_need_refresh || (m_refresh_bank != bank)) return false; - if (m_bankBusyCounter[bank] > 0) return false; - // Note that m_busBusyCounter will prevent multiple issues during - // the same cycle, as well as on different but close cycles: - if (m_busBusyCounter_Basic > 0) return false; - int rank = getRank(bank); - if (m_tfaw_count[rank] >= ACTIVATE_PER_TFAW) return false; - - // Issue it: - - //if (m_debug) { - //uint64 current_time = g_eventQueue_ptr->getTime(); - //printf(" Refresh bank %3x at %lld\n", bank, current_time); - //} - m_profiler_ptr->profileMemRefresh(); - m_need_refresh--; - m_refresh_bank++; - if (m_refresh_bank >= m_total_banks) m_refresh_bank = 0; - m_bankBusyCounter[bank] = m_bank_busy_time; - m_busBusyCounter_Basic = m_basic_bus_busy_time; - m_busBusyCounter_Write = m_basic_bus_busy_time; - m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time; - markTfaw(rank); - return true; -} + if (m_busBusyCounter_Basic == m_basic_bus_busy_time) { + // Another bank must have issued this same cycle. For + // profiling, we count this as an arb wait rather than a bus + // wait. This is a little inaccurate since it MIGHT have also + // been blocked waiting for a read-write or a read-read + // instead, but it's pretty close. + m_profiler_ptr->profileMemArbWait(1); + return false; + } + if (m_busBusyCounter_Basic > 0) { + m_profiler_ptr->profileMemBusBusy(); + return false; + } -// Mark the activate in the tFaw shift register -void MemoryControl::markTfaw (int rank) { - if (m_tFaw) { - m_tfaw_shift[rank] |= (1 << (m_tFaw-1)); - m_tfaw_count[rank]++; - } -} + int rank = getRank(bank); + if (m_tfaw_count[rank] >= ACTIVATE_PER_TFAW) { + m_profiler_ptr->profileMemTfawBusy(); + return false; + } + bool write = !m_bankQueues[bank].front().m_is_mem_read; + if (write && (m_busBusyCounter_Write > 0)) { + m_profiler_ptr->profileMemReadWriteBusy(); + return false; + } -// Issue a memory request: Activate the bank, -// reserve the address and data buses, and queue -// the request for return to the requesting -// processor after a fixed latency. + if (!write && (rank != m_busBusy_WhichRank) + && (m_busBusyCounter_ReadNewRank > 0)) { + m_profiler_ptr->profileMemDataBusBusy(); + return false; + } -void MemoryControl::issueRequest (int bank) { - int rank = getRank(bank); - MemoryNode req = m_bankQueues[bank].front(); - m_bankQueues[bank].pop_front(); - if (m_debug) { - uint64 current_time = g_eventQueue_ptr->getTime(); - printf(" Mem issue request%7d: 0x%08llx %c at %10lld bank =%3x\n", - req.m_msg_counter, req.m_addr, req.m_is_mem_read? 'R':'W', current_time, bank); - } - if (req.m_msgptr.ref() != NULL) { // don't enqueue L3 writebacks - enqueueToDirectory(req, m_mem_ctl_latency + m_mem_fixed_delay); - } - m_oldRequest[bank] = 0; - markTfaw(rank); - m_bankBusyCounter[bank] = m_bank_busy_time; - m_busBusy_WhichRank = rank; - if (req.m_is_mem_read) { - m_profiler_ptr->profileMemRead(); - m_busBusyCounter_Basic = m_basic_bus_busy_time; - m_busBusyCounter_Write = m_basic_bus_busy_time + m_read_write_delay; - m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time + m_rank_rank_delay; - } else { - m_profiler_ptr->profileMemWrite(); + return true; +} + +// issueRefresh checks to see if this bank has a refresh scheduled +// and, if so, does the refresh and returns true +bool +MemoryControl::issueRefresh(int bank) +{ + if (!m_need_refresh || (m_refresh_bank != bank)) + return false; + if (m_bankBusyCounter[bank] > 0) + return false; + // Note that m_busBusyCounter will prevent multiple issues during + // the same cycle, as well as on different but close cycles: + if (m_busBusyCounter_Basic > 0) + return false; + int rank = getRank(bank); + if (m_tfaw_count[rank] >= ACTIVATE_PER_TFAW) + return false; + + // Issue it: +#if 0 + if (m_debug) { + uint64 current_time = g_eventQueue_ptr->getTime(); + printf(" Refresh bank %3x at %lld\n", bank, current_time); + } +#endif + + m_profiler_ptr->profileMemRefresh(); + m_need_refresh--; + m_refresh_bank++; + if (m_refresh_bank >= m_total_banks) + m_refresh_bank = 0; + m_bankBusyCounter[bank] = m_bank_busy_time; m_busBusyCounter_Basic = m_basic_bus_busy_time; m_busBusyCounter_Write = m_basic_bus_busy_time; m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time; - } + markTfaw(rank); + return true; +} + +// Mark the activate in the tFaw shift register +void +MemoryControl::markTfaw(int rank) +{ + if (m_tFaw) { + m_tfaw_shift[rank] |= (1 << (m_tFaw-1)); + m_tfaw_count[rank]++; + } } +// Issue a memory request: Activate the bank, reserve the address and +// data buses, and queue the request for return to the requesting +// processor after a fixed latency. +void +MemoryControl::issueRequest(int bank) +{ + int rank = getRank(bank); + MemoryNode req = m_bankQueues[bank].front(); + m_bankQueues[bank].pop_front(); + if (m_debug) { + uint64 current_time = g_eventQueue_ptr->getTime(); + cprintf(" Mem issue request%7d: %#08x %c at %10d " + "bank=%3x\n", + req.m_msg_counter, req.m_addr, req.m_is_mem_read? 'R':'W', + current_time, bank); + } + if (req.m_msgptr.ref() != NULL) { // don't enqueue L3 writebacks + enqueueToDirectory(req, m_mem_ctl_latency + m_mem_fixed_delay); + } + m_oldRequest[bank] = 0; + markTfaw(rank); + m_bankBusyCounter[bank] = m_bank_busy_time; + m_busBusy_WhichRank = rank; + if (req.m_is_mem_read) { + m_profiler_ptr->profileMemRead(); + m_busBusyCounter_Basic = m_basic_bus_busy_time; + m_busBusyCounter_Write = m_basic_bus_busy_time + m_read_write_delay; + m_busBusyCounter_ReadNewRank = + m_basic_bus_busy_time + m_rank_rank_delay; + } else { + m_profiler_ptr->profileMemWrite(); + m_busBusyCounter_Basic = m_basic_bus_busy_time; + m_busBusyCounter_Write = m_basic_bus_busy_time; + m_busBusyCounter_ReadNewRank = m_basic_bus_busy_time; + } +} // executeCycle: This function is called once per memory clock cycle // to simulate all the periodic hardware. +void +MemoryControl::executeCycle() +{ + // Keep track of time by counting down the busy counters: + for (int bank=0; bank < m_total_banks; bank++) { + if (m_bankBusyCounter[bank] > 0) m_bankBusyCounter[bank]--; + } + if (m_busBusyCounter_Write > 0) + m_busBusyCounter_Write--; + if (m_busBusyCounter_ReadNewRank > 0) + m_busBusyCounter_ReadNewRank--; + if (m_busBusyCounter_Basic > 0) + m_busBusyCounter_Basic--; + + // Count down the tFAW shift registers: + for (int rank=0; rank < m_total_ranks; rank++) { + if (m_tfaw_shift[rank] & 1) m_tfaw_count[rank]--; + m_tfaw_shift[rank] >>= 1; + } + + // After time period expires, latch an indication that we need a refresh. + // Disable refresh if in mem_fixed_delay mode. + if (!m_mem_fixed_delay) m_refresh_count--; + if (m_refresh_count == 0) { + m_refresh_count = m_refresh_period_system; + + // Are we overrunning our ability to refresh? + assert(m_need_refresh < 10); + m_need_refresh++; + } -void MemoryControl::executeCycle () { - // Keep track of time by counting down the busy counters: - for (int bank=0; bank < m_total_banks; bank++) { - if (m_bankBusyCounter[bank] > 0) m_bankBusyCounter[bank]--; - } - if (m_busBusyCounter_Write > 0) m_busBusyCounter_Write--; - if (m_busBusyCounter_ReadNewRank > 0) m_busBusyCounter_ReadNewRank--; - if (m_busBusyCounter_Basic > 0) m_busBusyCounter_Basic--; - - // Count down the tFAW shift registers: - for (int rank=0; rank < m_total_ranks; rank++) { - if (m_tfaw_shift[rank] & 1) m_tfaw_count[rank]--; - m_tfaw_shift[rank] >>= 1; - } - - // After time period expires, latch an indication that we need a refresh. - // Disable refresh if in mem_fixed_delay mode. - if (!m_mem_fixed_delay) m_refresh_count--; - if (m_refresh_count == 0) { - m_refresh_count = m_refresh_period_system; - assert (m_need_refresh < 10); // Are we overrunning our ability to refresh? - m_need_refresh++; - } - - // If this batch of requests is all done, make a new batch: - m_ageCounter++; - int anyOld = 0; - for (int bank=0; bank < m_total_banks; bank++) { - anyOld |= m_oldRequest[bank]; - } - if (!anyOld) { + // If this batch of requests is all done, make a new batch: + m_ageCounter++; + int anyOld = 0; for (int bank=0; bank < m_total_banks; bank++) { - if (!m_bankQueues[bank].empty()) m_oldRequest[bank] = 1; + anyOld |= m_oldRequest[bank]; } - m_ageCounter = 0; - } - - // If randomness desired, re-randomize round-robin position each cycle - if (m_mem_random_arbitrate) { - m_roundRobin = random() % m_total_banks; - } - - - // For each channel, scan round-robin, and pick an old, ready - // request and issue it. Treat a refresh request as if it - // were at the head of its bank queue. After we issue something, - // keep scanning the queues just to gather statistics about - // how many are waiting. If in mem_fixed_delay mode, we can issue - // more than one request per cycle. - - int queueHeads = 0; - int banksIssued = 0; - for (int i = 0; i < m_total_banks; i++) { - m_roundRobin++; - if (m_roundRobin >= m_total_banks) m_roundRobin = 0; - issueRefresh(m_roundRobin); - int qs = m_bankQueues[m_roundRobin].size(); - if (qs > 1) { - m_profiler_ptr->profileMemBankQ(qs-1); + if (!anyOld) { + for (int bank=0; bank < m_total_banks; bank++) { + if (!m_bankQueues[bank].empty()) m_oldRequest[bank] = 1; + } + m_ageCounter = 0; + } + + // If randomness desired, re-randomize round-robin position each cycle + if (m_mem_random_arbitrate) { + m_roundRobin = random() % m_total_banks; } - if (qs > 0) { - m_idleCount = IDLECOUNT_MAX_VALUE; // we're not idle if anything is queued - queueHeads++; - if (queueReady(m_roundRobin)) { - issueRequest(m_roundRobin); - banksIssued++; - if (m_mem_fixed_delay) { - m_profiler_ptr->profileMemWaitCycles(m_mem_fixed_delay); + + // For each channel, scan round-robin, and pick an old, ready + // request and issue it. Treat a refresh request as if it were at + // the head of its bank queue. After we issue something, keep + // scanning the queues just to gather statistics about how many + // are waiting. If in mem_fixed_delay mode, we can issue more + // than one request per cycle. + int queueHeads = 0; + int banksIssued = 0; + for (int i = 0; i < m_total_banks; i++) { + m_roundRobin++; + if (m_roundRobin >= m_total_banks) m_roundRobin = 0; + issueRefresh(m_roundRobin); + int qs = m_bankQueues[m_roundRobin].size(); + if (qs > 1) { + m_profiler_ptr->profileMemBankQ(qs-1); + } + if (qs > 0) { + // we're not idle if anything is queued + m_idleCount = IDLECOUNT_MAX_VALUE; + queueHeads++; + if (queueReady(m_roundRobin)) { + issueRequest(m_roundRobin); + banksIssued++; + if (m_mem_fixed_delay) { + m_profiler_ptr->profileMemWaitCycles(m_mem_fixed_delay); + } + } } - } } - } - - // memWaitCycles is a redundant catch-all for the specific counters in queueReady - m_profiler_ptr->profileMemWaitCycles(queueHeads - banksIssued); - - // Check input queue and move anything to bank queues if not full. - // Since this is done here at the end of the cycle, there will always - // be at least one cycle of latency in the bank queue. - // We deliberately move at most one request per cycle (to simulate - // typical hardware). Note that if one bank queue fills up, other - // requests can get stuck behind it here. - - if (!m_input_queue.empty()) { - m_idleCount = IDLECOUNT_MAX_VALUE; // we're not idle if anything is pending - MemoryNode req = m_input_queue.front(); - int bank = getBank(req.m_addr); - if (m_bankQueues[bank].size() < m_bank_queue_size) { - m_input_queue.pop_front(); - m_bankQueues[bank].push_back(req); + + // memWaitCycles is a redundant catch-all for the specific + // counters in queueReady + m_profiler_ptr->profileMemWaitCycles(queueHeads - banksIssued); + + // Check input queue and move anything to bank queues if not full. + // Since this is done here at the end of the cycle, there will + // always be at least one cycle of latency in the bank queue. We + // deliberately move at most one request per cycle (to simulate + // typical hardware). Note that if one bank queue fills up, other + // requests can get stuck behind it here. + if (!m_input_queue.empty()) { + // we're not idle if anything is pending + m_idleCount = IDLECOUNT_MAX_VALUE; + MemoryNode req = m_input_queue.front(); + int bank = getBank(req.m_addr); + if (m_bankQueues[bank].size() < m_bank_queue_size) { + m_input_queue.pop_front(); + m_bankQueues[bank].push_back(req); + } + m_profiler_ptr->profileMemInputQ(m_input_queue.size()); } - m_profiler_ptr->profileMemInputQ(m_input_queue.size()); - } } - // wakeup: This function is called once per memory controller clock cycle. - -void MemoryControl::wakeup () { - - // execute everything - executeCycle(); - - m_idleCount--; - if (m_idleCount <= 0) { - m_awakened = 0; - } else { - // Reschedule ourselves so that we run every memory cycle: - g_eventQueue_ptr->scheduleEvent(this, m_mem_bus_cycle_multiplier); - } +void +MemoryControl::wakeup() +{ + // execute everything + executeCycle(); + + m_idleCount--; + if (m_idleCount <= 0) { + m_awakened = 0; + } else { + // Reschedule ourselves so that we run every memory cycle: + g_eventQueue_ptr->scheduleEvent(this, m_mem_bus_cycle_multiplier); + } } MemoryControl * diff --git a/src/mem/ruby/system/MemoryControl.hh b/src/mem/ruby/system/MemoryControl.hh index b96055cb1..d42c1e6e0 100644 --- a/src/mem/ruby/system/MemoryControl.hh +++ b/src/mem/ruby/system/MemoryControl.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,34 +26,24 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * MemoryControl.hh - * - * Description: See MemoryControl.cc - * - * $Id: $ - * - */ +#ifndef __MEM_RUBY_SYSTEM_MEMORY_CONTROL_HH__ +#define __MEM_RUBY_SYSTEM_MEMORY_CONTROL_HH__ -#ifndef MEMORY_CONTROL_H -#define MEMORY_CONTROL_H +#include <list> -#include "mem/ruby/common/Global.hh" #include "mem/gems_common/Map.hh" -#include "mem/ruby/common/Address.hh" -#include "mem/ruby/profiler/MemCntrlProfiler.hh" -#include "mem/ruby/system/System.hh" -#include "mem/ruby/slicc_interface/Message.hh" #include "mem/gems_common/util.hh" -#include "mem/ruby/system/MemoryNode.hh" -// Note that "MemoryMsg" is in the "generated" directory: #include "mem/protocol/MemoryMsg.hh" +#include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Consumer.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/profiler/MemCntrlProfiler.hh" +#include "mem/ruby/slicc_interface/Message.hh" #include "mem/ruby/system/AbstractMemOrCache.hh" -#include "sim/sim_object.hh" +#include "mem/ruby/system/MemoryNode.hh" +#include "mem/ruby/system/System.hh" #include "params/RubyMemoryControl.hh" - -#include <list> +#include "sim/sim_object.hh" // This constant is part of the definition of tFAW; see // the comments in header to MemoryControl.cc @@ -64,124 +53,117 @@ class Consumer; -class MemoryControl : public SimObject, public Consumer, public AbstractMemOrCache { -public: - - // Constructors +class MemoryControl : + public SimObject, public Consumer, public AbstractMemOrCache +{ + public: typedef RubyMemoryControlParams Params; MemoryControl(const Params *p); - void init(); - - // Destructor - ~MemoryControl (); - - // Public Methods - - void wakeup() ; - - void setConsumer (Consumer* consumer_ptr); - Consumer* getConsumer () { return m_consumer_ptr; }; - void setDescription (const string& name) { m_description = name; }; - string getDescription () { return m_description; }; - - // Called from the directory: - void enqueue (const MsgPtr& message, int latency ); - void enqueueMemRef (MemoryNode& memRef); - void dequeue (); - const Message* peek (); - MemoryNode peekNode (); - bool isReady(); - bool areNSlotsAvailable (int n) { return true; }; // infinite queue length - - //// Called from L3 cache: - //void writeBack(physical_address_t addr); - - void printConfig (ostream& out); - void print (ostream& out) const; - void setDebug (int debugFlag); - void clearStats() const; - void printStats(ostream& out) const; - - - //added by SS - int getBanksPerRank() { return m_banks_per_rank; }; - int getRanksPerDimm() { return m_ranks_per_dimm; }; - int getDimmsPerChannel() { return m_dimms_per_channel; } - -private: - - void enqueueToDirectory (MemoryNode req, int latency); - int getBank (physical_address_t addr); - int getRank (int bank); - bool queueReady (int bank); - void issueRequest (int bank); - bool issueRefresh (int bank); - void markTfaw (int rank); - void executeCycle (); - - // Private copy constructor and assignment operator - MemoryControl (const MemoryControl& obj); - MemoryControl& operator=(const MemoryControl& obj); - - // data members - Consumer* m_consumer_ptr; // Consumer to signal a wakeup() - string m_description; - int m_msg_counter; - int m_awakened; - - int m_mem_bus_cycle_multiplier; - int m_banks_per_rank; - int m_ranks_per_dimm; - int m_dimms_per_channel; - int m_bank_bit_0; - int m_rank_bit_0; - int m_dimm_bit_0; - unsigned int m_bank_queue_size; - int m_bank_busy_time; - int m_rank_rank_delay; - int m_read_write_delay; - int m_basic_bus_busy_time; - int m_mem_ctl_latency; - int m_refresh_period; - int m_mem_random_arbitrate; - int m_tFaw; - int m_mem_fixed_delay; - - int m_total_banks; - int m_total_ranks; - int m_refresh_period_system; - - // queues where memory requests live - - list<MemoryNode> m_response_queue; - list<MemoryNode> m_input_queue; - list<MemoryNode>* m_bankQueues; - - // Each entry indicates number of address-bus cycles until bank - // is reschedulable: - int* m_bankBusyCounter; - int* m_oldRequest; - - uint64* m_tfaw_shift; - int* m_tfaw_count; - - // Each of these indicates number of address-bus cycles until - // we can issue a new request of the corresponding type: - int m_busBusyCounter_Write; - int m_busBusyCounter_ReadNewRank; - int m_busBusyCounter_Basic; - - int m_busBusy_WhichRank; // which rank last granted - int m_roundRobin; // which bank queue was last granted - int m_refresh_count; // cycles until next refresh - int m_need_refresh; // set whenever m_refresh_count goes to zero - int m_refresh_bank; // which bank to refresh next - int m_ageCounter; // age of old requests; to detect starvation - int m_idleCount; // watchdog timer for shutting down - int m_debug; // turn on printf's - - MemCntrlProfiler* m_profiler_ptr; + void init(); + + ~MemoryControl(); + + void wakeup(); + + void setConsumer(Consumer* consumer_ptr); + Consumer* getConsumer() { return m_consumer_ptr; }; + void setDescription(const string& name) { m_description = name; }; + string getDescription() { return m_description; }; + + // Called from the directory: + void enqueue(const MsgPtr& message, int latency ); + void enqueueMemRef(MemoryNode& memRef); + void dequeue(); + const Message* peek(); + MemoryNode peekNode(); + bool isReady(); + bool areNSlotsAvailable(int n) { return true; }; // infinite queue length + + //// Called from L3 cache: + //void writeBack(physical_address_t addr); + + void printConfig(ostream& out); + void print(ostream& out) const; + void setDebug(int debugFlag); + void clearStats() const; + void printStats(ostream& out) const; + + //added by SS + int getBanksPerRank() { return m_banks_per_rank; }; + int getRanksPerDimm() { return m_ranks_per_dimm; }; + int getDimmsPerChannel() { return m_dimms_per_channel; } + + private: + void enqueueToDirectory(MemoryNode req, int latency); + int getBank(physical_address_t addr); + int getRank(int bank); + bool queueReady(int bank); + void issueRequest(int bank); + bool issueRefresh(int bank); + void markTfaw(int rank); + void executeCycle(); + + // Private copy constructor and assignment operator + MemoryControl (const MemoryControl& obj); + MemoryControl& operator=(const MemoryControl& obj); + + // data members + Consumer* m_consumer_ptr; // Consumer to signal a wakeup() + string m_description; + int m_msg_counter; + int m_awakened; + + int m_mem_bus_cycle_multiplier; + int m_banks_per_rank; + int m_ranks_per_dimm; + int m_dimms_per_channel; + int m_bank_bit_0; + int m_rank_bit_0; + int m_dimm_bit_0; + unsigned int m_bank_queue_size; + int m_bank_busy_time; + int m_rank_rank_delay; + int m_read_write_delay; + int m_basic_bus_busy_time; + int m_mem_ctl_latency; + int m_refresh_period; + int m_mem_random_arbitrate; + int m_tFaw; + int m_mem_fixed_delay; + + int m_total_banks; + int m_total_ranks; + int m_refresh_period_system; + + // queues where memory requests live + list<MemoryNode> m_response_queue; + list<MemoryNode> m_input_queue; + list<MemoryNode>* m_bankQueues; + + // Each entry indicates number of address-bus cycles until bank + // is reschedulable: + int* m_bankBusyCounter; + int* m_oldRequest; + + uint64* m_tfaw_shift; + int* m_tfaw_count; + + // Each of these indicates number of address-bus cycles until + // we can issue a new request of the corresponding type: + int m_busBusyCounter_Write; + int m_busBusyCounter_ReadNewRank; + int m_busBusyCounter_Basic; + + int m_busBusy_WhichRank; // which rank last granted + int m_roundRobin; // which bank queue was last granted + int m_refresh_count; // cycles until next refresh + int m_need_refresh; // set whenever m_refresh_count goes to zero + int m_refresh_bank; // which bank to refresh next + int m_ageCounter; // age of old requests; to detect starvation + int m_idleCount; // watchdog timer for shutting down + int m_debug; // turn on printf's + + MemCntrlProfiler* m_profiler_ptr; }; -#endif // MEMORY_CONTROL_H - +#endif // __MEM_RUBY_SYSTEM_MEMORY_CONTROL_HH__ diff --git a/src/mem/ruby/system/MemoryNode.cc b/src/mem/ruby/system/MemoryNode.cc index 5b74f497a..07262fba0 100644 --- a/src/mem/ruby/system/MemoryNode.cc +++ b/src/mem/ruby/system/MemoryNode.cc @@ -30,11 +30,12 @@ using namespace std; -void MemoryNode::print(ostream& out) const +void +MemoryNode::print(ostream& out) const { - out << "["; - out << m_time << ", "; - out << m_msg_counter << ", "; - out << m_msgptr << "; "; - out << "]"; + out << "["; + out << m_time << ", "; + out << m_msg_counter << ", "; + out << m_msgptr << "; "; + out << "]"; } diff --git a/src/mem/ruby/system/MemoryNode.hh b/src/mem/ruby/system/MemoryNode.hh index 2c2b987ae..10648b715 100644 --- a/src/mem/ruby/system/MemoryNode.hh +++ b/src/mem/ruby/system/MemoryNode.hh @@ -35,68 +35,59 @@ * message is enqueued to be sent back to the directory. */ -#ifndef MEMORYNODE_H -#define MEMORYNODE_H +#ifndef __MEM_RUBY_SYSTEM_MEMORYNODE_HH__ +#define __MEM_RUBY_SYSTEM_MEMORYNODE_HH__ #include <iostream> +#include "mem/protocol/MemoryRequestType.hh" #include "mem/ruby/common/Global.hh" #include "mem/ruby/slicc_interface/Message.hh" -#include "mem/protocol/MemoryRequestType.hh" - -class MemoryNode { - -public: - // Constructors - -// old one: - MemoryNode(const Time& time, int counter, const MsgPtr& msgptr, const physical_address_t addr, const bool is_mem_read) { - m_time = time; - m_msg_counter = counter; - m_msgptr = msgptr; - m_addr = addr; - m_is_mem_read = is_mem_read; - m_is_dirty_wb = !is_mem_read; - } - -// new one: - MemoryNode(const Time& time, const MsgPtr& msgptr, const physical_address_t addr, const bool is_mem_read, const bool is_dirty_wb) { - m_time = time; - m_msg_counter = 0; - m_msgptr = msgptr; - m_addr = addr; - m_is_mem_read = is_mem_read; - m_is_dirty_wb = is_dirty_wb; - } - // Destructor - ~MemoryNode() {}; - - // Public Methods - void print(std::ostream& out) const; - - // Data Members (m_ prefix) (all public -- this is really more a struct) - - Time m_time; - int m_msg_counter; - MsgPtr m_msgptr; - physical_address_t m_addr; - bool m_is_mem_read; - bool m_is_dirty_wb; +class MemoryNode +{ + public: + // old constructor + MemoryNode(const Time& time, int counter, const MsgPtr& msgptr, + const physical_address_t addr, const bool is_mem_read) + { + m_time = time; + m_msg_counter = counter; + m_msgptr = msgptr; + m_addr = addr; + m_is_mem_read = is_mem_read; + m_is_dirty_wb = !is_mem_read; + } + + // new constructor + MemoryNode(const Time& time, const MsgPtr& msgptr, + const physical_address_t addr, const bool is_mem_read, + const bool is_dirty_wb) + { + m_time = time; + m_msg_counter = 0; + m_msgptr = msgptr; + m_addr = addr; + m_is_mem_read = is_mem_read; + m_is_dirty_wb = is_dirty_wb; + } + + void print(std::ostream& out) const; + + Time m_time; + int m_msg_counter; + MsgPtr m_msgptr; + physical_address_t m_addr; + bool m_is_mem_read; + bool m_is_dirty_wb; }; -// Output operator declaration -std::ostream& operator<<(std::ostream& out, const MemoryNode& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -std::ostream& operator<<(std::ostream& out, const MemoryNode& obj) +inline std::ostream& +operator<<(std::ostream& out, const MemoryNode& obj) { - obj.print(out); - out << std::flush; - return out; + obj.print(out); + out << std::flush; + return out; } -#endif //MEMORYNODE_H +#endif // __MEM_RUBY_SYSTEM_MEMORYNODE_HH__ diff --git a/src/mem/ruby/system/MemoryVector.hh b/src/mem/ruby/system/MemoryVector.hh index e450059fd..15cea168d 100644 --- a/src/mem/ruby/system/MemoryVector.hh +++ b/src/mem/ruby/system/MemoryVector.hh @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MEMORYVECTOR_H -#define MEMORYVECTOR_H +#ifndef __MEM_RUBY_SYSTEM_MEMORYVECTOR_HH__ +#define __MEM_RUBY_SYSTEM_MEMORYVECTOR_HH__ #include "mem/ruby/common/Address.hh" @@ -36,117 +36,121 @@ class DirectoryMemory; /** * MemoryVector holds memory data (DRAM only) */ -class MemoryVector { - public: - MemoryVector(); - MemoryVector(uint32 size); - ~MemoryVector(); - friend class DirectoryMemory; +class MemoryVector +{ + public: + MemoryVector(); + MemoryVector(uint32 size); + ~MemoryVector(); + friend class DirectoryMemory; - void setSize(uint32 size); // destructive + void setSize(uint32 size); // destructive - void write(const Address & paddr, uint8* data, int len); - uint8* read(const Address & paddr, uint8* data, int len); + void write(const Address & paddr, uint8* data, int len); + uint8* read(const Address & paddr, uint8* data, int len); -private: - uint8* getBlockPtr(const PhysAddress & addr); + private: + uint8* getBlockPtr(const PhysAddress & addr); - uint32 m_size; - uint8** m_pages; - uint32 m_num_pages; - const uint32 m_page_offset_mask; + uint32 m_size; + uint8** m_pages; + uint32 m_num_pages; + const uint32 m_page_offset_mask; }; inline MemoryVector::MemoryVector() - : m_page_offset_mask(4095) + : m_page_offset_mask(4095) { - m_size = 0; - m_num_pages = 0; - m_pages = NULL; + m_size = 0; + m_num_pages = 0; + m_pages = NULL; } inline MemoryVector::MemoryVector(uint32 size) - : m_page_offset_mask(4095) + : m_page_offset_mask(4095) { - setSize(size); + setSize(size); } inline MemoryVector::~MemoryVector() { - for (int i=0; i<m_num_pages; i++) { - if (m_pages[i] != 0) { - delete [] m_pages[i]; + for (int i = 0; i < m_num_pages; i++) { + if (m_pages[i] != 0) { + delete [] m_pages[i]; + } } - } - delete [] m_pages; + delete [] m_pages; } -inline -void MemoryVector::setSize(uint32 size) +inline void +MemoryVector::setSize(uint32 size) { - if (m_pages != NULL){ - for (int i=0; i<m_num_pages; i++) { - if (m_pages[i] != 0) { - delete [] m_pages[i]; - } + if (m_pages != NULL){ + for (int i = 0; i < m_num_pages; i++) { + if (m_pages[i] != 0) { + delete [] m_pages[i]; + } + } + delete [] m_pages; } - delete [] m_pages; - } - m_size = size; - assert(size%4096 == 0); - m_num_pages = size >> 12; - m_pages = new uint8*[m_num_pages]; - memset(m_pages, 0, m_num_pages * sizeof(uint8*)); + m_size = size; + assert(size%4096 == 0); + m_num_pages = size >> 12; + m_pages = new uint8*[m_num_pages]; + memset(m_pages, 0, m_num_pages * sizeof(uint8*)); } -inline -void MemoryVector::write(const Address & paddr, uint8* data, int len) +inline void +MemoryVector::write(const Address & paddr, uint8* data, int len) { - assert(paddr.getAddress() + len <= m_size); - uint32 page_num = paddr.getAddress() >> 12; - if (m_pages[page_num] == 0) { - bool all_zeros = true; - for (int i=0;i<len;i++) { - if (data[i] != 0) { - all_zeros = false; - break; - } + assert(paddr.getAddress() + len <= m_size); + uint32 page_num = paddr.getAddress() >> 12; + if (m_pages[page_num] == 0) { + bool all_zeros = true; + for (int i = 0; i < len;i++) { + if (data[i] != 0) { + all_zeros = false; + break; + } + } + if (all_zeros) + return; + m_pages[page_num] = new uint8[4096]; + memset(m_pages[page_num], 0, 4096); + uint32 offset = paddr.getAddress() & m_page_offset_mask; + memcpy(&m_pages[page_num][offset], data, len); + } else { + memcpy(&m_pages[page_num][paddr.getAddress()&m_page_offset_mask], + data, len); } - if (all_zeros) return; - m_pages[page_num] = new uint8[4096]; - memset(m_pages[page_num], 0, 4096); - uint32 offset = paddr.getAddress() & m_page_offset_mask; - memcpy(&m_pages[page_num][offset], data, len); - } else { - memcpy(&m_pages[page_num][paddr.getAddress()&m_page_offset_mask], data, len); - } } -inline -uint8* MemoryVector::read(const Address & paddr, uint8* data, int len) +inline uint8* +MemoryVector::read(const Address & paddr, uint8* data, int len) { - assert(paddr.getAddress() + len <= m_size); - uint32 page_num = paddr.getAddress() >> 12; - if (m_pages[page_num] == 0) { - memset(data, 0, len); - } else { - memcpy(data, &m_pages[page_num][paddr.getAddress()&m_page_offset_mask], len); - } - return data; + assert(paddr.getAddress() + len <= m_size); + uint32 page_num = paddr.getAddress() >> 12; + if (m_pages[page_num] == 0) { + memset(data, 0, len); + } else { + memcpy(data, &m_pages[page_num][paddr.getAddress()&m_page_offset_mask], + len); + } + return data; } -inline -uint8* MemoryVector::getBlockPtr(const PhysAddress & paddr) +inline uint8* +MemoryVector::getBlockPtr(const PhysAddress & paddr) { - uint32 page_num = paddr.getAddress() >> 12; - if (m_pages[page_num] == 0) { - m_pages[page_num] = new uint8[4096]; - memset(m_pages[page_num], 0, 4096); - } - return &m_pages[page_num][paddr.getAddress()&m_page_offset_mask]; + uint32 page_num = paddr.getAddress() >> 12; + if (m_pages[page_num] == 0) { + m_pages[page_num] = new uint8[4096]; + memset(m_pages[page_num], 0, 4096); + } + return &m_pages[page_num][paddr.getAddress()&m_page_offset_mask]; } -#endif // MEMORYVECTOR_H +#endif // __MEM_RUBY_SYSTEM_MEMORYVECTOR_HH__ diff --git a/src/mem/ruby/system/NodeID.hh b/src/mem/ruby/system/NodeID.hh index 6191ad489..4ce8d8a8d 100644 --- a/src/mem/ruby/system/NodeID.hh +++ b/src/mem/ruby/system/NodeID.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,26 +26,20 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * NodeID.hh - * - * Description: - * - * $Id: NodeID.hh,v 3.3 2003/12/04 15:01:39 xu Exp $ - * - */ - -#ifndef NODEID_H -#define NODEID_H +#ifndef __MEM_RUBY_SYSTEM_NODEID_HH__ +#define __MEM_RUBY_SYSTEM_NODEID_HH__ #include <string> -#include "mem/ruby/common/Global.hh" #include "mem/gems_common/util.hh" +#include "mem/ruby/common/Global.hh" typedef int NodeID; -extern inline -std::string NodeIDToString (NodeID node) { return int_to_string(node); } +inline std::string +NodeIDToString(NodeID node) +{ + return int_to_string(node); +} -#endif //NODEID_H +#endif // __MEM_RUBY_SYSTEM_NODEID_HH__ diff --git a/src/mem/ruby/system/PerfectCacheMemory.hh b/src/mem/ruby/system/PerfectCacheMemory.hh index 6561d028b..f1fb8b2e9 100644 --- a/src/mem/ruby/system/PerfectCacheMemory.hh +++ b/src/mem/ruby/system/PerfectCacheMemory.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,215 +26,188 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * PerfectCacheMemory.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef PERFECTCACHEMEMORY_H -#define PERFECTCACHEMEMORY_H +#ifndef __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__ +#define __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__ -#include "mem/ruby/common/Global.hh" #include "mem/gems_common/Map.hh" #include "mem/protocol/AccessPermission.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" template<class ENTRY> -class PerfectCacheLineState { -public: - PerfectCacheLineState() { m_permission = AccessPermission_NUM; } - AccessPermission m_permission; - ENTRY m_entry; +struct PerfectCacheLineState +{ + PerfectCacheLineState() { m_permission = AccessPermission_NUM; } + AccessPermission m_permission; + ENTRY m_entry; }; template<class ENTRY> -extern inline -ostream& operator<<(ostream& out, const PerfectCacheLineState<ENTRY>& obj) +inline ostream& +operator<<(ostream& out, const PerfectCacheLineState<ENTRY>& obj) { - return out; + return out; } template<class ENTRY> -class PerfectCacheMemory { -public: - - // Constructors - PerfectCacheMemory(); - - // Destructor - //~PerfectCacheMemory(); - - // Public Methods +class PerfectCacheMemory +{ + public: + PerfectCacheMemory(); - static void printConfig(ostream& out); + static void printConfig(ostream& out); - // perform a cache access and see if we hit or not. Return true on - // a hit. - bool tryCacheAccess(const CacheMsg& msg, bool& block_stc, ENTRY*& entry); + // perform a cache access and see if we hit or not. Return true + // on a hit. + bool tryCacheAccess(const CacheMsg& msg, bool& block_stc, ENTRY*& entry); - // tests to see if an address is present in the cache - bool isTagPresent(const Address& address) const; + // tests to see if an address is present in the cache + bool isTagPresent(const Address& address) const; - // Returns true if there is: - // a) a tag match on this address or there is - // b) an Invalid line in the same cache "way" - bool cacheAvail(const Address& address) const; + // Returns true if there is: + // a) a tag match on this address or there is + // b) an Invalid line in the same cache "way" + bool cacheAvail(const Address& address) const; - // find an Invalid entry and sets the tag appropriate for the address - void allocate(const Address& address); + // find an Invalid entry and sets the tag appropriate for the address + void allocate(const Address& address); - void deallocate(const Address& address); + void deallocate(const Address& address); - // Returns with the physical address of the conflicting cache line - Address cacheProbe(const Address& newAddress) const; + // Returns with the physical address of the conflicting cache line + Address cacheProbe(const Address& newAddress) const; - // looks an address up in the cache - ENTRY& lookup(const Address& address); - const ENTRY& lookup(const Address& address) const; + // looks an address up in the cache + ENTRY& lookup(const Address& address); + const ENTRY& lookup(const Address& address) const; - // Get/Set permission of cache block - AccessPermission getPermission(const Address& address) const; - void changePermission(const Address& address, AccessPermission new_perm); + // Get/Set permission of cache block + AccessPermission getPermission(const Address& address) const; + void changePermission(const Address& address, AccessPermission new_perm); - // Print cache contents - void print(ostream& out) const; -private: - // Private Methods + // Print cache contents + void print(ostream& out) const; - // Private copy constructor and assignment operator - PerfectCacheMemory(const PerfectCacheMemory& obj); - PerfectCacheMemory& operator=(const PerfectCacheMemory& obj); + private: + // Private copy constructor and assignment operator + PerfectCacheMemory(const PerfectCacheMemory& obj); + PerfectCacheMemory& operator=(const PerfectCacheMemory& obj); - // Data Members (m_prefix) - Map<Address, PerfectCacheLineState<ENTRY> > m_map; + // Data Members (m_prefix) + Map<Address, PerfectCacheLineState<ENTRY> > m_map; }; -// Output operator declaration -//ostream& operator<<(ostream& out, const PerfectCacheMemory<ENTRY>& obj); - -// ******************* Definitions ******************* - -// Output operator definition template<class ENTRY> -extern inline -ostream& operator<<(ostream& out, const PerfectCacheMemory<ENTRY>& obj) +inline ostream& +operator<<(ostream& out, const PerfectCacheMemory<ENTRY>& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } - -// **************************************************************** - template<class ENTRY> -extern inline +inline PerfectCacheMemory<ENTRY>::PerfectCacheMemory() { } -// STATIC METHODS - template<class ENTRY> -extern inline -void PerfectCacheMemory<ENTRY>::printConfig(ostream& out) +inline void +PerfectCacheMemory<ENTRY>::printConfig(ostream& out) { } -// PUBLIC METHODS - template<class ENTRY> -extern inline -bool PerfectCacheMemory<ENTRY>::tryCacheAccess(const CacheMsg& msg, bool& block_stc, ENTRY*& entry) +inline bool +PerfectCacheMemory<ENTRY>::tryCacheAccess(const CacheMsg& msg, + bool& block_stc, ENTRY*& entry) { - ERROR_MSG("not implemented"); + ERROR_MSG("not implemented"); } // tests to see if an address is present in the cache template<class ENTRY> -extern inline -bool PerfectCacheMemory<ENTRY>::isTagPresent(const Address& address) const +inline bool +PerfectCacheMemory<ENTRY>::isTagPresent(const Address& address) const { - return m_map.exist(line_address(address)); + return m_map.exist(line_address(address)); } template<class ENTRY> -extern inline -bool PerfectCacheMemory<ENTRY>::cacheAvail(const Address& address) const +inline bool +PerfectCacheMemory<ENTRY>::cacheAvail(const Address& address) const { - return true; + return true; } // find an Invalid or already allocated entry and sets the tag // appropriate for the address template<class ENTRY> -extern inline -void PerfectCacheMemory<ENTRY>::allocate(const Address& address) +inline void +PerfectCacheMemory<ENTRY>::allocate(const Address& address) { - PerfectCacheLineState<ENTRY> line_state; - line_state.m_permission = AccessPermission_Busy; - line_state.m_entry = ENTRY(); - m_map.add(line_address(address), line_state); + PerfectCacheLineState<ENTRY> line_state; + line_state.m_permission = AccessPermission_Busy; + line_state.m_entry = ENTRY(); + m_map.add(line_address(address), line_state); } // deallocate entry template<class ENTRY> -extern inline -void PerfectCacheMemory<ENTRY>::deallocate(const Address& address) +inline void +PerfectCacheMemory<ENTRY>::deallocate(const Address& address) { - m_map.erase(line_address(address)); + m_map.erase(line_address(address)); } // Returns with the physical address of the conflicting cache line template<class ENTRY> -extern inline -Address PerfectCacheMemory<ENTRY>::cacheProbe(const Address& newAddress) const +inline Address +PerfectCacheMemory<ENTRY>::cacheProbe(const Address& newAddress) const { - ERROR_MSG("cacheProbe called in perfect cache"); + ERROR_MSG("cacheProbe called in perfect cache"); } // looks an address up in the cache template<class ENTRY> -extern inline -ENTRY& PerfectCacheMemory<ENTRY>::lookup(const Address& address) +inline ENTRY& +PerfectCacheMemory<ENTRY>::lookup(const Address& address) { - return m_map.lookup(line_address(address)).m_entry; + return m_map.lookup(line_address(address)).m_entry; } // looks an address up in the cache template<class ENTRY> -extern inline -const ENTRY& PerfectCacheMemory<ENTRY>::lookup(const Address& address) const +inline const ENTRY& +PerfectCacheMemory<ENTRY>::lookup(const Address& address) const { - return m_map.lookup(line_address(address)).m_entry; + return m_map.lookup(line_address(address)).m_entry; } template<class ENTRY> -extern inline -AccessPermission PerfectCacheMemory<ENTRY>::getPermission(const Address& address) const +inline AccessPermission +PerfectCacheMemory<ENTRY>::getPermission(const Address& address) const { - return m_map.lookup(line_address(address)).m_permission; + return m_map.lookup(line_address(address)).m_permission; } template<class ENTRY> -extern inline -void PerfectCacheMemory<ENTRY>::changePermission(const Address& address, AccessPermission new_perm) +inline void +PerfectCacheMemory<ENTRY>::changePermission(const Address& address, + AccessPermission new_perm) { - Address line_address = address; - line_address.makeLineAddress(); - PerfectCacheLineState<ENTRY>& line_state = m_map.lookup(line_address); - AccessPermission old_perm = line_state.m_permission; - line_state.m_permission = new_perm; + Address line_address = address; + line_address.makeLineAddress(); + PerfectCacheLineState<ENTRY>& line_state = m_map.lookup(line_address); + AccessPermission old_perm = line_state.m_permission; + line_state.m_permission = new_perm; } template<class ENTRY> -extern inline -void PerfectCacheMemory<ENTRY>::print(ostream& out) const +inline void +PerfectCacheMemory<ENTRY>::print(ostream& out) const { } -#endif //PERFECTCACHEMEMORY_H +#endif // __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__ diff --git a/src/mem/ruby/system/PersistentTable.cc b/src/mem/ruby/system/PersistentTable.cc index 58b67ea60..1d971ae21 100644 --- a/src/mem/ruby/system/PersistentTable.cc +++ b/src/mem/ruby/system/PersistentTable.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,178 +26,187 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "mem/ruby/system/PersistentTable.hh" #include "mem/gems_common/util.hh" +#include "mem/ruby/system/PersistentTable.hh" // randomize so that handoffs are not locality-aware -// int persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}; -// int persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - +#if 0 +int persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, + 10, 14, 3, 7, 11, 15}; +int persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15}; +#endif PersistentTable::PersistentTable() { - m_map_ptr = new Map<Address, PersistentTableEntry>; + m_map_ptr = new Map<Address, PersistentTableEntry>; } PersistentTable::~PersistentTable() { - delete m_map_ptr; - m_map_ptr = NULL; + delete m_map_ptr; + m_map_ptr = NULL; } -void PersistentTable::persistentRequestLock(const Address& address, - MachineID locker, - AccessType type) +void +PersistentTable::persistentRequestLock(const Address& address, + MachineID locker, + AccessType type) { - - // if (locker == m_chip_ptr->getID() ) - // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker - // << " requesting lock for " << address << endl; - - // MachineID locker = (MachineID) persistent_randomize[llocker]; - - 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); +#if 0 + if (locker == m_chip_ptr->getID()) + cout << "Chip " << m_chip_ptr->getID() << ": " << llocker + << " requesting lock for " << address << endl; + + MachineID locker = (MachineID) persistent_randomize[llocker]; +#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); + + // + // 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); + } + assert(entry.m_marked.isSubset(entry.m_starving)); } - m_map_ptr->add(address, entry); - } else { +} + +void +PersistentTable::persistentRequestUnlock(const Address& address, + MachineID unlocker) +{ +#if 0 + if (unlocker == m_chip_ptr->getID()) + cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker + << " requesting unlock for " << address << endl; + + MachineID unlocker = (MachineID) persistent_randomize[uunlocker]; +#endif + + assert(address == line_address(address)); + assert(m_map_ptr->exist(address)); PersistentTableEntry& entry = m_map_ptr->lookup(address); // - // Make sure we're not already in the locked set + // Make sure we're 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); - } + assert(entry.m_starving.isElement(unlocker)); + assert(entry.m_marked.isSubset(entry.m_starving)); + entry.m_starving.remove(unlocker); + entry.m_marked.remove(unlocker); + entry.m_request_to_write.remove(unlocker); assert(entry.m_marked.isSubset(entry.m_starving)); - } -} -void PersistentTable::persistentRequestUnlock(const Address& address, - MachineID unlocker) -{ - // if (unlocker == m_chip_ptr->getID() ) - // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker - // << " requesting unlock for " << address << endl; - - // MachineID unlocker = (MachineID) persistent_randomize[uunlocker]; - - assert(address == line_address(address)); - assert(m_map_ptr->exist(address)); - PersistentTableEntry& entry = m_map_ptr->lookup(address); - - // - // Make sure we're in the locked set - // - assert(entry.m_starving.isElement(unlocker)); - assert(entry.m_marked.isSubset(entry.m_starving)); - entry.m_starving.remove(unlocker); - entry.m_marked.remove(unlocker); - entry.m_request_to_write.remove(unlocker); - assert(entry.m_marked.isSubset(entry.m_starving)); - - // Deallocate if empty - if (entry.m_starving.isEmpty()) { - assert(entry.m_marked.isEmpty()); - m_map_ptr->erase(address); - } + // Deallocate if empty + if (entry.m_starving.isEmpty()) { + assert(entry.m_marked.isEmpty()); + m_map_ptr->erase(address); + } } -bool PersistentTable::okToIssueStarving(const Address& address, - MachineID machId) const +bool +PersistentTable::okToIssueStarving(const Address& address, + MachineID machId) const { - assert(address == line_address(address)); - if (!m_map_ptr->exist(address)) { - // - // No entry present - // - return true; - } else if (m_map_ptr->lookup(address).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()); - } + assert(address == line_address(address)); + if (!m_map_ptr->exist(address)) { + // No entry present + return true; + } else if (m_map_ptr->lookup(address).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(); + } } -MachineID PersistentTable::findSmallest(const Address& address) const +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); - return entry.m_starving.smallestElement(); + assert(address == line_address(address)); + assert(m_map_ptr->exist(address)); + const PersistentTableEntry& entry = m_map_ptr->lookup(address); + return entry.m_starving.smallestElement(); } -AccessType PersistentTable::typeOfSmallest(const Address& address) const +AccessType +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); - if (entry.m_request_to_write.isElement(entry.m_starving.smallestElement())) { - return AccessType_Write; - } else { - return AccessType_Read; - } + assert(address == line_address(address)); + assert(m_map_ptr->exist(address)); + const PersistentTableEntry& entry = m_map_ptr->lookup(address); + if (entry.m_request_to_write. + isElement(entry.m_starving.smallestElement())) { + return AccessType_Write; + } else { + return AccessType_Read; + } } -void PersistentTable::markEntries(const Address& address) +void +PersistentTable::markEntries(const Address& address) { - assert(address == line_address(address)); - if (m_map_ptr->exist(address)) { - PersistentTableEntry& entry = m_map_ptr->lookup(address); + assert(address == line_address(address)); + if (m_map_ptr->exist(address)) { + PersistentTableEntry& entry = m_map_ptr->lookup(address); - // - // None should be marked - // - assert(entry.m_marked.isEmpty()); + // None should be marked + assert(entry.m_marked.isEmpty()); - // - // Mark all the nodes currently in the table - // - entry.m_marked = entry.m_starving; - } + // Mark all the nodes currently in the table + entry.m_marked = entry.m_starving; + } } -bool PersistentTable::isLocked(const Address& address) const +bool +PersistentTable::isLocked(const Address& address) const { - assert(address == line_address(address)); - // If an entry is present, it must be locked - return (m_map_ptr->exist(address)); + assert(address == line_address(address)); + + // If an entry is present, it must be locked + return m_map_ptr->exist(address); } -int PersistentTable::countStarvingForAddress(const Address& address) const +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 { - return 0; - } + if (m_map_ptr->exist(address)) { + PersistentTableEntry& entry = m_map_ptr->lookup(address); + return (entry.m_starving.count()); + } else { + return 0; + } } -int PersistentTable::countReadStarvingForAddress(const Address& address) const +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 { - return 0; - } + 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 { + return 0; + } } -void PersistentTable::print(ostream& out) const +void +PersistentTable::print(ostream& out) const { } diff --git a/src/mem/ruby/system/PersistentTable.hh b/src/mem/ruby/system/PersistentTable.hh index 8cbb48817..defcae2b8 100644 --- a/src/mem/ruby/system/PersistentTable.hh +++ b/src/mem/ruby/system/PersistentTable.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,76 +26,74 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef PersistentTable_H -#define PersistentTable_H +#ifndef __MEM_RUBY_SYSTEM_PERSISTENTTABLE_HH__ +#define __MEM_RUBY_SYSTEM_PERSISTENTTABLE_HH__ -#include "mem/ruby/common/Global.hh" #include "mem/gems_common/Map.hh" -#include "mem/ruby/common/Address.hh" -#include "mem/ruby/system/MachineID.hh" #include "mem/protocol/AccessType.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/NetDest.hh" +#include "mem/ruby/system/MachineID.hh" -class PersistentTableEntry { -public: - void print(ostream& out) const {} +class PersistentTableEntry +{ + public: + void print(ostream& out) const {} - NetDest m_starving; - NetDest m_marked; - NetDest m_request_to_write; + NetDest m_starving; + NetDest m_marked; + NetDest m_request_to_write; }; -class PersistentTable { -public: - // Constructors - PersistentTable(); +class PersistentTable +{ + public: + // Constructors + PersistentTable(); - // Destructor - ~PersistentTable(); + // Destructor + ~PersistentTable(); - // Public Methods - void persistentRequestLock(const Address& address, MachineID locker, AccessType type); - void persistentRequestUnlock(const Address& address, MachineID unlocker); - bool okToIssueStarving(const Address& address, MachineID machID) const; - MachineID findSmallest(const Address& address) const; - AccessType typeOfSmallest(const Address& address) const; - void markEntries(const Address& address); - bool isLocked(const Address& addr) const; - int countStarvingForAddress(const Address& addr) const; - int countReadStarvingForAddress(const Address& addr) const; + // Public Methods + void persistentRequestLock(const Address& address, MachineID locker, + AccessType type); + void persistentRequestUnlock(const Address& address, MachineID unlocker); + bool okToIssueStarving(const Address& address, MachineID machID) const; + MachineID findSmallest(const Address& address) const; + AccessType typeOfSmallest(const Address& address) const; + void markEntries(const Address& address); + bool isLocked(const Address& addr) const; + int countStarvingForAddress(const Address& addr) const; + int countReadStarvingForAddress(const Address& addr) const; - static void printConfig(ostream& out) {} + static void printConfig(ostream& out) {} - void print(ostream& out) const; -private: - // Private Methods + void print(ostream& out) const; - // Private copy constructor and assignment operator - PersistentTable(const PersistentTable& obj); - PersistentTable& operator=(const PersistentTable& obj); + private: + // Private copy constructor and assignment operator + PersistentTable(const PersistentTable& obj); + PersistentTable& operator=(const PersistentTable& obj); - // Data Members (m_prefix) - Map<Address, PersistentTableEntry>* m_map_ptr; + // Data Members (m_prefix) + Map<Address, PersistentTableEntry>* m_map_ptr; }; -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const PersistentTable& obj) +inline ostream& +operator<<(ostream& out, const PersistentTable& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const PersistentTableEntry& obj) +inline ostream& +operator<<(ostream& out, const PersistentTableEntry& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -#endif //PersistentTable_H +#endif // __MEM_RUBY_SYSTEM_PERSISTENTTABLE_HH__ diff --git a/src/mem/ruby/system/PseudoLRUPolicy.hh b/src/mem/ruby/system/PseudoLRUPolicy.hh index 61bf72c3e..1e1e68188 100644 --- a/src/mem/ruby/system/PseudoLRUPolicy.hh +++ b/src/mem/ruby/system/PseudoLRUPolicy.hh @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef PSEUDOLRUPOLICY_H -#define PSEUDOLRUPOLICY_H +#ifndef __MEM_RUBY_SYSTEM_PSEUDOLRUPOLICY_HH__ +#define __MEM_RUBY_SYSTEM_PSEUDOLRUPOLICY_HH__ #include "mem/ruby/system/AbstractReplacementPolicy.hh" @@ -44,94 +44,97 @@ * 2 is one below the associativy, and most fair when it is one above. */ -class PseudoLRUPolicy : public AbstractReplacementPolicy { - public: - - PseudoLRUPolicy(Index num_sets, Index assoc); - ~PseudoLRUPolicy(); - - void touch(Index set, Index way, Time time); - Index getVictim(Index set) const; - - private: - unsigned int m_effective_assoc; /** nearest (to ceiling) power of 2 */ - unsigned int m_num_levels; /** number of levels in the tree */ - uint64* m_trees; /** bit representation of the trees, one for each set */ +class PseudoLRUPolicy : public AbstractReplacementPolicy +{ + public: + PseudoLRUPolicy(Index num_sets, Index assoc); + ~PseudoLRUPolicy(); + + void touch(Index set, Index way, Time time); + Index getVictim(Index set) const; + + private: + unsigned int m_effective_assoc; /** nearest (to ceiling) power of 2 */ + unsigned int m_num_levels; /** number of levels in the tree */ + uint64* m_trees; /** bit representation of the + * trees, one for each set */ }; inline PseudoLRUPolicy::PseudoLRUPolicy(Index num_sets, Index assoc) - : AbstractReplacementPolicy(num_sets, assoc) + : AbstractReplacementPolicy(num_sets, assoc) { - int num_tree_nodes; - - // associativity cannot exceed capacity of tree representation - assert(num_sets > 0 && assoc > 1 && assoc <= (Index) sizeof(uint64)*4); - - m_trees = NULL; - m_num_levels = 0; - - m_effective_assoc = 1; - while(m_effective_assoc < assoc){ - m_effective_assoc <<= 1; // effective associativity is ceiling power of 2 - } - assoc = m_effective_assoc; - while(true){ - assoc /= 2; - if(!assoc) break; - m_num_levels++; - } - assert(m_num_levels < sizeof(unsigned int)*4); - num_tree_nodes = (1 << m_num_levels) - 1; - m_trees = new uint64[m_num_sets]; - for(unsigned int i=0; i< m_num_sets; i++){ - m_trees[i] = 0; - } + int num_tree_nodes; + + // associativity cannot exceed capacity of tree representation + assert(num_sets > 0 && assoc > 1 && assoc <= (Index) sizeof(uint64)*4); + + m_trees = NULL; + m_num_levels = 0; + + m_effective_assoc = 1; + while (m_effective_assoc < assoc) { + // effective associativity is ceiling power of 2 + m_effective_assoc <<= 1; + } + assoc = m_effective_assoc; + while (true) { + assoc /= 2; + if(!assoc) break; + m_num_levels++; + } + assert(m_num_levels < sizeof(unsigned int)*4); + num_tree_nodes = (1 << m_num_levels) - 1; + m_trees = new uint64[m_num_sets]; + for (unsigned i = 0; i < m_num_sets; i++) { + m_trees[i] = 0; + } } inline PseudoLRUPolicy::~PseudoLRUPolicy() { - if(m_trees != NULL) - delete[] m_trees; + if (m_trees != NULL) + delete[] m_trees; } -inline -void PseudoLRUPolicy::touch(Index set, Index index, Time time){ - assert(index >= 0 && index < m_assoc); - assert(set >= 0 && set < m_num_sets); - - int tree_index = 0; - int node_val; - for(int i=m_num_levels -1; i>=0; i--){ - node_val = (index >> i)&1; - if(node_val) - m_trees[set] |= node_val << tree_index; - else - m_trees[set] &= ~(1 << tree_index); - tree_index = node_val ? (tree_index*2)+2 : (tree_index*2)+1; - } - m_last_ref_ptr[set][index] = time; +inline void +PseudoLRUPolicy::touch(Index set, Index index, Time time) +{ + assert(index >= 0 && index < m_assoc); + assert(set >= 0 && set < m_num_sets); + + int tree_index = 0; + int node_val; + for (int i = m_num_levels - 1; i >= 0; i--) { + node_val = (index >> i)&1; + if (node_val) + m_trees[set] |= node_val << tree_index; + else + m_trees[set] &= ~(1 << tree_index); + tree_index = node_val ? (tree_index*2)+2 : (tree_index*2)+1; + } + m_last_ref_ptr[set][index] = time; } -inline -Index PseudoLRUPolicy::getVictim(Index set) const { - // assert(m_assoc != 0); - - Index index = 0; - - int tree_index = 0; - int node_val; - for(unsigned int i=0;i<m_num_levels;i++){ - node_val = (m_trees[set]>>tree_index)&1; - index += node_val?0:(m_effective_assoc >> (i+1)); - tree_index = node_val? (tree_index*2)+1 : (tree_index*2)+2; - } - assert(index >= 0 && index < m_effective_assoc); - - /* return either the found index or the max possible index */ - /* NOTE: this is not a fair replacement when assoc is not a power of 2 */ - return (index > (m_assoc-1)) ? m_assoc-1:index; +inline Index +PseudoLRUPolicy::getVictim(Index set) const +{ + // assert(m_assoc != 0); + Index index = 0; + + int tree_index = 0; + int node_val; + for (unsigned i = 0; i < m_num_levels; i++){ + node_val = (m_trees[set] >> tree_index) & 1; + index += node_val ? 0 : (m_effective_assoc >> (i + 1)); + tree_index = node_val ? (tree_index * 2) + 1 : (tree_index * 2) + 2; + } + assert(index >= 0 && index < m_effective_assoc); + + /* return either the found index or the max possible index */ + /* NOTE: this is not a fair replacement when assoc is not a power of 2 */ + return (index > (m_assoc - 1)) ? m_assoc - 1 : index; } -#endif // PSEUDOLRUPOLICY_H +#endif // __MEM_RUBY_SYSTEM_PSEUDOLRUPOLICY_HH__ diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index 480c13ad8..87a98185c 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 2009 Advanced Micro Devices, Inc. * All rights reserved. @@ -27,10 +26,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "cpu/rubytest/RubyTester.hh" #include "mem/physical.hh" -#include "mem/ruby/system/RubyPort.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" -#include "cpu/rubytest/RubyTester.hh" +#include "mem/ruby/system/RubyPort.hh" RubyPort::RubyPort(const Params *p) : MemObject(p) @@ -39,7 +38,7 @@ RubyPort::RubyPort(const Params *p) assert(m_version != -1); physmem = p->physmem; - + m_controller = NULL; m_mandatory_q_ptr = NULL; @@ -48,7 +47,8 @@ RubyPort::RubyPort(const Params *p) physMemPort = NULL; } -void RubyPort::init() +void +RubyPort::init() { assert(m_controller != NULL); m_mandatory_q_ptr = m_controller->getMandatoryQueue(); @@ -59,38 +59,38 @@ RubyPort::getPort(const std::string &if_name, int idx) { if (if_name == "port") { return new M5Port(csprintf("%s-port%d", name(), idx), this); - } else if (if_name == "pio_port") { - // + } + + if (if_name == "pio_port") { // ensure there is only one pio port - // assert(pio_port == NULL); - pio_port = new PioPort(csprintf("%s-pio-port%d", name(), idx), - this); + pio_port = new PioPort(csprintf("%s-pio-port%d", name(), idx), this); return pio_port; - } else if (if_name == "physMemPort") { - // + } + + if (if_name == "physMemPort") { // RubyPort should only have one port to physical memory - // assert (physMemPort == NULL); - physMemPort = new M5Port(csprintf("%s-physMemPort", name()), - this); - + physMemPort = new M5Port(csprintf("%s-physMemPort", name()), this); + return physMemPort; - } else if (if_name == "functional") { - // - // Calls for the functional port only want to access functional memory. - // Therefore, directly pass these calls ports to physmem. - // + } + + if (if_name == "functional") { + // Calls for the functional port only want to access + // functional memory. Therefore, directly pass these calls + // ports to physmem. assert(physmem != NULL); return physmem->getPort(if_name, idx); } + return NULL; } -RubyPort::PioPort::PioPort(const std::string &_name, +RubyPort::PioPort::PioPort(const std::string &_name, RubyPort *_port) : SimpleTimingPort(_name, _port) { @@ -98,7 +98,7 @@ RubyPort::PioPort::PioPort(const std::string &_name, ruby_port = _port; } -RubyPort::M5Port::M5Port(const std::string &_name, +RubyPort::M5Port::M5Port(const std::string &_name, RubyPort *_port) : SimpleTimingPort(_name, _port) { @@ -113,7 +113,6 @@ RubyPort::PioPort::recvAtomic(PacketPtr pkt) return 0; } - Tick RubyPort::M5Port::recvAtomic(PacketPtr pkt) { @@ -125,48 +124,39 @@ RubyPort::M5Port::recvAtomic(PacketPtr pkt) bool RubyPort::PioPort::recvTiming(PacketPtr pkt) { - // - // In FS mode, ruby memory will receive pio responses from devices and - // it must forward these responses back to the particular CPU. - // - DPRINTF(MemoryAccess, - "Pio response for address %#x\n", - pkt->getAddr()); + // In FS mode, ruby memory will receive pio responses from devices + // and it must forward these responses back to the particular CPU. + DPRINTF(MemoryAccess, "Pio response for address %#x\n", pkt->getAddr()); assert(pkt->isResponse()); - // // First we must retrieve the request port from the sender State - // - RubyPort::SenderState *senderState = + RubyPort::SenderState *senderState = safe_cast<RubyPort::SenderState *>(pkt->senderState); M5Port *port = senderState->port; assert(port != NULL); - + // pop the sender state from the packet pkt->senderState = senderState->saved; delete senderState; - + port->sendTiming(pkt); - + return true; } bool RubyPort::M5Port::recvTiming(PacketPtr pkt) { - DPRINTF(MemoryAccess, - "Timing access caught for address %#x\n", - pkt->getAddr()); + DPRINTF(MemoryAccess, + "Timing access caught for address %#x\n", pkt->getAddr()); //dsm: based on SimpleTimingPort::recvTiming(pkt); - // - // The received packets should only be M5 requests, which should never - // get nacked. There used to be code to hanldle nacks here, but - // I'm pretty sure it didn't work correctly with the drain code, + // The received packets should only be M5 requests, which should never + // get nacked. There used to be code to hanldle nacks here, but + // I'm pretty sure it didn't work correctly with the drain code, // so that would need to be fixed if we ever added it back. - // assert(pkt->isRequest()); if (pkt->memInhibitAsserted()) { @@ -177,34 +167,26 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt) return true; } - // // Save the port in the sender state object to be used later to // route the response - // pkt->senderState = new SenderState(this, pkt->senderState); - // // Check for pio requests and directly send them to the dedicated // pio port. - // if (!isPhysMemAddress(pkt->getAddr())) { assert(ruby_port->pio_port != NULL); - DPRINTF(MemoryAccess, + DPRINTF(MemoryAccess, "Request for address 0x%#x is assumed to be a pio request\n", pkt->getAddr()); return ruby_port->pio_port->sendTiming(pkt); } - // // For DMA and CPU requests, translate them to ruby requests before // sending them to our assigned ruby port. - // RubyRequestType type = RubyRequestType_NULL; - // // If valid, copy the pc to the ruby request - // Addr pc = 0; if (pkt->req->hasPC()) { pc = pkt->req->getPC(); @@ -224,47 +206,38 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt) if (pkt->req->isInstFetch()) { type = RubyRequestType_IFETCH; } else { - type = RubyRequestType_LD; + type = RubyRequestType_LD; } } else if (pkt->isWrite()) { type = RubyRequestType_ST; } else if (pkt->isReadWrite()) { - // - // Fix me. This conditional will never be executed because - // isReadWrite() is just an OR of isRead() and isWrite(). - // Furthermore, just because the packet is a read/write request does - // not necessary mean it is a read-modify-write atomic operation. - // + // Fix me. This conditional will never be executed + // because isReadWrite() is just an OR of isRead() and + // isWrite(). Furthermore, just because the packet is a + // read/write request does not necessary mean it is a + // read-modify-write atomic operation. type = RubyRequestType_RMW_Write; } else { panic("Unsupported ruby packet type\n"); } } - RubyRequest ruby_request(pkt->getAddr(), - pkt->getPtr<uint8_t>(), - pkt->getSize(), - pc, - type, - RubyAccessMode_Supervisor, - pkt); + RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(), + pkt->getSize(), pc, type, + RubyAccessMode_Supervisor, pkt); // Submit the ruby request RequestStatus requestStatus = ruby_port->makeRequest(ruby_request); - // // If the request successfully issued or the SC request completed because // exclusive permission was lost, then we should return true. // Otherwise, we need to delete the senderStatus we just created and return // false. - // if ((requestStatus == RequestStatus_Issued) || (requestStatus == RequestStatus_LlscFailed)) { - // // The communicate to M5 whether the SC command succeeded by seting the // packet's extra data. - // if (pkt->isLLSC() && pkt->isWrite()) { if (requestStatus == RequestStatus_LlscFailed) { DPRINTF(MemoryAccess, "SC failed and request completed\n"); @@ -276,11 +249,10 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt) return true; } - DPRINTF(MemoryAccess, + DPRINTF(MemoryAccess, "Request for address #x did not issue because %s\n", - pkt->getAddr(), - RequestStatus_to_string(requestStatus)); - + pkt->getAddr(), RequestStatus_to_string(requestStatus)); + SenderState* senderState = safe_cast<SenderState*>(pkt->senderState); pkt->senderState = senderState->saved; delete senderState; @@ -290,14 +262,12 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt) void RubyPort::ruby_hit_callback(PacketPtr pkt) { - // // Retrieve the request port from the sender State - // - RubyPort::SenderState *senderState = + RubyPort::SenderState *senderState = safe_cast<RubyPort::SenderState *>(pkt->senderState); M5Port *port = senderState->port; assert(port != NULL); - + // pop the sender state from the packet pkt->senderState = senderState->saved; delete senderState; @@ -308,11 +278,9 @@ RubyPort::ruby_hit_callback(PacketPtr pkt) void RubyPort::M5Port::hitCallback(PacketPtr pkt) { - bool needsResponse = pkt->needsResponse(); - DPRINTF(MemoryAccess, "Hit callback needs response %d\n", - needsResponse); + DPRINTF(MemoryAccess, "Hit callback needs response %d\n", needsResponse); ruby_port->physMemPort->sendAtomic(pkt); @@ -349,9 +317,9 @@ RubyPort::M5Port::isPhysMemAddress(Addr addr) AddrRangeList physMemAddrList; bool snoop = false; ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop); - for(AddrRangeIter iter = physMemAddrList.begin(); - iter != physMemAddrList.end(); - iter++) { + for (AddrRangeIter iter = physMemAddrList.begin(); + iter != physMemAddrList.end(); + iter++) { if (addr >= iter->start && addr <= iter->end) { DPRINTF(MemoryAccess, "Request found in %#llx - %#llx range\n", iter->start, iter->end); diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh index 3a862e068..4038c6007 100644 --- a/src/mem/ruby/system/RubyPort.hh +++ b/src/mem/ruby/system/RubyPort.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 2009 Advanced Micro Devices, Inc. * All rights reserved. @@ -27,18 +26,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef RUBYPORT_H -#define RUBYPORT_H +#ifndef __MEM_RUBY_SYSTEM_RUBYPORT_HH__ +#define __MEM_RUBY_SYSTEM_RUBYPORT_HH__ -#include "mem/ruby/libruby.hh" +#include <cassert> #include <string> -#include <assert.h> #include "mem/mem_object.hh" -#include "mem/tport.hh" #include "mem/physical.hh" #include "mem/protocol/RequestStatus.hh" - +#include "mem/ruby/libruby.hh" +#include "mem/tport.hh" #include "params/RubyPort.hh" using namespace std; @@ -46,17 +44,16 @@ using namespace std; class MessageBuffer; class AbstractController; -class RubyPort : public MemObject { -public: - +class RubyPort : public MemObject +{ + public: class M5Port : public SimpleTimingPort { - + private: RubyPort *ruby_port; public: - M5Port(const std::string &_name, - RubyPort *_port); + M5Port(const std::string &_name, RubyPort *_port); bool sendTiming(PacketPtr pkt); void hitCallback(PacketPtr pkt); @@ -72,12 +69,11 @@ public: class PioPort : public SimpleTimingPort { - + private: RubyPort *ruby_port; public: - PioPort(const std::string &_name, - RubyPort *_port); + PioPort(const std::string &_name, RubyPort *_port); bool sendTiming(PacketPtr pkt); protected: @@ -92,8 +88,7 @@ public: M5Port* port; Packet::SenderState *saved; - SenderState(M5Port* _port, - Packet::SenderState *sender_state = NULL) + SenderState(M5Port* _port, Packet::SenderState *sender_state = NULL) : port(_port), saved(sender_state) {} }; @@ -114,17 +109,17 @@ public: // void setController(AbstractController* _cntrl) { m_controller = _cntrl; } -protected: - const string m_name; - void ruby_hit_callback(PacketPtr pkt); - void hit(PacketPtr pkt); + protected: + const string m_name; + void ruby_hit_callback(PacketPtr pkt); + void hit(PacketPtr pkt); - int m_version; - AbstractController* m_controller; - MessageBuffer* m_mandatory_q_ptr; + int m_version; + AbstractController* m_controller; + MessageBuffer* m_mandatory_q_ptr; PioPort* pio_port; -private: + private: uint16_t m_port_id; uint64_t m_request_cnt; @@ -133,4 +128,4 @@ private: PhysicalMemory* physmem; }; -#endif +#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__ diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index d6dba08f9..a473ccf44 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,22 +26,21 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "mem/ruby/libruby.hh" -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/Sequencer.hh" -#include "mem/ruby/system/System.hh" -#include "mem/protocol/Protocol.hh" -#include "mem/ruby/profiler/Profiler.hh" -#include "mem/ruby/system/CacheMemory.hh" +#include "cpu/rubytest/RubyTester.hh" +#include "mem/gems_common/Map.hh" #include "mem/protocol/CacheMsg.hh" -#include "mem/ruby/recorder/Tracer.hh" -#include "mem/ruby/common/SubBlock.hh" #include "mem/protocol/Protocol.hh" -#include "mem/gems_common/Map.hh" +#include "mem/protocol/Protocol.hh" #include "mem/ruby/buffers/MessageBuffer.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/common/SubBlock.hh" +#include "mem/ruby/libruby.hh" +#include "mem/ruby/profiler/Profiler.hh" +#include "mem/ruby/recorder/Tracer.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" -#include "cpu/rubytest/RubyTester.hh" - +#include "mem/ruby/system/CacheMemory.hh" +#include "mem/ruby/system/Sequencer.hh" +#include "mem/ruby/system/System.hh" #include "params/RubySequencer.hh" Sequencer * @@ -50,7 +48,7 @@ RubySequencerParams::create() { return new Sequencer(this); } - + Sequencer::Sequencer(const Params *p) : RubyPort(p), deadlockCheckEvent(this) { @@ -58,7 +56,7 @@ Sequencer::Sequencer(const Params *p) m_store_waiting_on_store_cycles = 0; m_load_waiting_on_store_cycles = 0; m_load_waiting_on_load_cycles = 0; - + m_outstanding_count = 0; m_max_outstanding_requests = 0; @@ -78,478 +76,524 @@ Sequencer::Sequencer(const Params *p) assert(m_dataCache_ptr != NULL); } -Sequencer::~Sequencer() { - +Sequencer::~Sequencer() +{ } -void Sequencer::wakeup() { - // Check for deadlock of any of the requests - Time current_time = g_eventQueue_ptr->getTime(); - - // Check across all outstanding requests - int total_outstanding = 0; - - 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"); +void +Sequencer::wakeup() +{ + // Check for deadlock of any of the requests + Time current_time = g_eventQueue_ptr->getTime(); + + // Check across all outstanding requests + int total_outstanding = 0; + + 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"); + } } - } - - 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"); + + 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"); + } } - } - total_outstanding += m_writeRequestTable.size() + m_readRequestTable.size(); - assert(m_outstanding_count == total_outstanding); + total_outstanding += m_writeRequestTable.size(); + total_outstanding += m_readRequestTable.size(); - if (m_outstanding_count > 0) { // If there are still outstanding requests, keep checking - schedule(deadlockCheckEvent, - (m_deadlock_threshold * g_eventQueue_ptr->getClock()) + curTick); - } + assert(m_outstanding_count == total_outstanding); + + if (m_outstanding_count > 0) { + // If there are still outstanding requests, keep checking + schedule(deadlockCheckEvent, + m_deadlock_threshold * g_eventQueue_ptr->getClock() + + curTick); + } } -void Sequencer::printStats(ostream & out) const { - out << "Sequencer: " << m_name << endl; - out << " store_waiting_on_load_cycles: " << m_store_waiting_on_load_cycles << endl; - out << " store_waiting_on_store_cycles: " << m_store_waiting_on_store_cycles << endl; - out << " load_waiting_on_load_cycles: " << m_load_waiting_on_load_cycles << endl; - out << " load_waiting_on_store_cycles: " << m_load_waiting_on_store_cycles << endl; +void +Sequencer::printStats(ostream & out) const +{ + out << "Sequencer: " << m_name << endl + << " store_waiting_on_load_cycles: " + << m_store_waiting_on_load_cycles << endl + << " store_waiting_on_store_cycles: " + << m_store_waiting_on_store_cycles << endl + << " load_waiting_on_load_cycles: " + << m_load_waiting_on_load_cycles << endl + << " load_waiting_on_store_cycles: " + << m_load_waiting_on_store_cycles << endl; } -void Sequencer::printProgress(ostream& out) const{ - /* - int total_demand = 0; - out << "Sequencer Stats Version " << m_version << endl; - out << "Current time = " << g_eventQueue_ptr->getTime() << endl; - out << "---------------" << endl; - out << "outstanding requests" << endl; - - Vector<Address> rkeys = m_readRequestTable.keys(); - int read_size = rkeys.size(); - out << "proc " << m_version << " Read Requests = " << read_size << endl; - // print the request table - for(int i=0; i < read_size; ++i){ - SequencerRequest * request = m_readRequestTable.lookup(rkeys[i]); - out << "\tRequest[ " << i << " ] = " << request->type << " Address " << rkeys[i] << " Posted " << request->issue_time << " PF " << PrefetchBit_No << endl; - total_demand++; - } - - Vector<Address> wkeys = m_writeRequestTable.keys(); - int write_size = wkeys.size(); - out << "proc " << m_version << " Write Requests = " << write_size << endl; - // print the request table - for(int i=0; i < write_size; ++i){ - CacheMsg & request = m_writeRequestTable.lookup(wkeys[i]); - out << "\tRequest[ " << i << " ] = " << request.getType() << " Address " << wkeys[i] << " Posted " << request.getTime() << " PF " << request.getPrefetch() << endl; - if( request.getPrefetch() == PrefetchBit_No ){ +void +Sequencer::printProgress(ostream& out) const +{ +#if 0 + int total_demand = 0; + out << "Sequencer Stats Version " << m_version << endl; + out << "Current time = " << g_eventQueue_ptr->getTime() << endl; + out << "---------------" << endl; + out << "outstanding requests" << endl; + + Vector<Address> rkeys = m_readRequestTable.keys(); + int read_size = rkeys.size(); + out << "proc " << m_version << " Read Requests = " << read_size << endl; + + // print the request table + for (int i = 0; i < read_size; ++i) { + SequencerRequest *request = m_readRequestTable.lookup(rkeys[i]); + out << "\tRequest[ " << i << " ] = " << request->type + << " Address " << rkeys[i] + << " Posted " << request->issue_time + << " PF " << PrefetchBit_No << endl; total_demand++; - } - } + } - out << endl; + Vector<Address> wkeys = m_writeRequestTable.keys(); + int write_size = wkeys.size(); + out << "proc " << m_version << " Write Requests = " << write_size << endl; + + // print the request table + for (int i = 0; i < write_size; ++i){ + CacheMsg &request = m_writeRequestTable.lookup(wkeys[i]); + out << "\tRequest[ " << i << " ] = " << request.getType() + << " Address " << wkeys[i] + << " Posted " << request.getTime() + << " PF " << request.getPrefetch() << endl; + if (request.getPrefetch() == PrefetchBit_No) { + total_demand++; + } + } - out << "Total Number Outstanding: " << m_outstanding_count << endl; - out << "Total Number Demand : " << total_demand << endl; - out << "Total Number Prefetches : " << m_outstanding_count - total_demand << endl; - out << endl; - out << endl; - */ + out << endl; + + out << "Total Number Outstanding: " << m_outstanding_count << endl + << "Total Number Demand : " << total_demand << endl + << "Total Number Prefetches : " << m_outstanding_count - total_demand + << endl << endl << endl; +#endif } -void Sequencer::printConfig(ostream& out) const { - out << "Seqeuncer config: " << m_name << endl; - out << " controller: " << m_controller->getName() << endl; - out << " version: " << m_version << endl; - out << " max_outstanding_requests: " << m_max_outstanding_requests << endl; - out << " deadlock_threshold: " << m_deadlock_threshold << endl; +void +Sequencer::printConfig(ostream& out) const +{ + out << "Seqeuncer config: " << m_name << endl + << " controller: " << m_controller->getName() << endl + << " version: " << m_version << endl + << " max_outstanding_requests: " << m_max_outstanding_requests << endl + << " deadlock_threshold: " << m_deadlock_threshold << endl; } // Insert the request on the correct request table. Return true if // the entry was already present. -bool Sequencer::insertRequest(SequencerRequest* request) { - int total_outstanding = m_writeRequestTable.size() + m_readRequestTable.size(); - - assert(m_outstanding_count == total_outstanding); - - // See if we should schedule a deadlock check - if (deadlockCheckEvent.scheduled() == false) { - schedule(deadlockCheckEvent, m_deadlock_threshold + curTick); - } - - Address line_addr(request->ruby_request.paddr); - line_addr.makeLineAddress(); - if ((request->ruby_request.type == RubyRequestType_ST) || - (request->ruby_request.type == RubyRequestType_RMW_Read) || - (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; - // return true; - assert(0); // drh5: isn't this an error? do you lose the initial request? +bool +Sequencer::insertRequest(SequencerRequest* request) +{ + int total_outstanding = + m_writeRequestTable.size() + m_readRequestTable.size(); + + assert(m_outstanding_count == total_outstanding); + + // See if we should schedule a deadlock check + if (deadlockCheckEvent.scheduled() == false) { + schedule(deadlockCheckEvent, m_deadlock_threshold + curTick); } - m_writeRequestTable.allocate(line_addr); - m_writeRequestTable.lookup(line_addr) = request; - m_outstanding_count++; - } else { - if (m_readRequestTable.exist(line_addr)) { - m_readRequestTable.lookup(line_addr) = request; - // return true; - assert(0); // drh5: isn't this an error? do you lose the initial request? + + Address line_addr(request->ruby_request.paddr); + line_addr.makeLineAddress(); + if ((request->ruby_request.type == RubyRequestType_ST) || + (request->ruby_request.type == RubyRequestType_RMW_Read) || + (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; + // 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; + m_outstanding_count++; + } else { + if (m_readRequestTable.exist(line_addr)) { + m_readRequestTable.lookup(line_addr) = 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; + m_outstanding_count++; } - m_readRequestTable.allocate(line_addr); - m_readRequestTable.lookup(line_addr) = request; - m_outstanding_count++; - } - g_system_ptr->getProfiler()->sequencerRequests(m_outstanding_count); + g_system_ptr->getProfiler()->sequencerRequests(m_outstanding_count); - total_outstanding = m_writeRequestTable.size() + m_readRequestTable.size(); - assert(m_outstanding_count == total_outstanding); + total_outstanding = m_writeRequestTable.size() + m_readRequestTable.size(); + assert(m_outstanding_count == total_outstanding); - return false; + return false; } -void Sequencer::removeRequest(SequencerRequest* srequest) { - - assert(m_outstanding_count == m_writeRequestTable.size() + m_readRequestTable.size()); - - const RubyRequest & ruby_request = srequest->ruby_request; - Address line_addr(ruby_request.paddr); - line_addr.makeLineAddress(); - if ((ruby_request.type == RubyRequestType_ST) || - (ruby_request.type == RubyRequestType_RMW_Read) || - (ruby_request.type == RubyRequestType_RMW_Write) || - (ruby_request.type == RubyRequestType_Locked_Read) || - (ruby_request.type == RubyRequestType_Locked_Write)) { - m_writeRequestTable.deallocate(line_addr); - } else { - m_readRequestTable.deallocate(line_addr); - } - m_outstanding_count--; - - assert(m_outstanding_count == m_writeRequestTable.size() + m_readRequestTable.size()); -} +void +Sequencer::removeRequest(SequencerRequest* srequest) +{ + assert(m_outstanding_count == + m_writeRequestTable.size() + m_readRequestTable.size()); + + const RubyRequest & ruby_request = srequest->ruby_request; + Address line_addr(ruby_request.paddr); + line_addr.makeLineAddress(); + if ((ruby_request.type == RubyRequestType_ST) || + (ruby_request.type == RubyRequestType_RMW_Read) || + (ruby_request.type == RubyRequestType_RMW_Write) || + (ruby_request.type == RubyRequestType_Locked_Read) || + (ruby_request.type == RubyRequestType_Locked_Write)) { + m_writeRequestTable.deallocate(line_addr); + } else { + m_readRequestTable.deallocate(line_addr); + } + m_outstanding_count--; -void Sequencer::writeCallback(const Address& address, DataBlock& data) { + assert(m_outstanding_count == m_writeRequestTable.size() + m_readRequestTable.size()); +} - assert(address == line_address(address)); - assert(m_writeRequestTable.exist(line_address(address))); +void +Sequencer::writeCallback(const Address& address, DataBlock& data) +{ + assert(address == line_address(address)); + assert(m_writeRequestTable.exist(line_address(address))); - SequencerRequest* request = m_writeRequestTable.lookup(address); + SequencerRequest* request = m_writeRequestTable.lookup(address); - removeRequest(request); + removeRequest(request); - assert((request->ruby_request.type == RubyRequestType_ST) || - (request->ruby_request.type == RubyRequestType_RMW_Read) || - (request->ruby_request.type == RubyRequestType_RMW_Write) || - (request->ruby_request.type == RubyRequestType_Locked_Read) || - (request->ruby_request.type == RubyRequestType_Locked_Write)); + assert((request->ruby_request.type == RubyRequestType_ST) || + (request->ruby_request.type == RubyRequestType_RMW_Read) || + (request->ruby_request.type == RubyRequestType_RMW_Write) || + (request->ruby_request.type == RubyRequestType_Locked_Read) || + (request->ruby_request.type == RubyRequestType_Locked_Write)); - if (request->ruby_request.type == RubyRequestType_Locked_Read) { - m_dataCache_ptr->setLocked(address, m_version); - } - else if (request->ruby_request.type == RubyRequestType_RMW_Read) { - m_controller->blockOnQueue(address, m_mandatory_q_ptr); - } - else if (request->ruby_request.type == RubyRequestType_RMW_Write) { - m_controller->unblock(address); - } + if (request->ruby_request.type == RubyRequestType_Locked_Read) { + m_dataCache_ptr->setLocked(address, m_version); + } else if (request->ruby_request.type == RubyRequestType_RMW_Read) { + m_controller->blockOnQueue(address, m_mandatory_q_ptr); + } else if (request->ruby_request.type == RubyRequestType_RMW_Write) { + m_controller->unblock(address); + } - hitCallback(request, data); + hitCallback(request, data); } -void Sequencer::readCallback(const Address& address, DataBlock& data) { - - assert(address == line_address(address)); - assert(m_readRequestTable.exist(line_address(address))); +void +Sequencer::readCallback(const Address& address, DataBlock& data) +{ + assert(address == line_address(address)); + assert(m_readRequestTable.exist(line_address(address))); - SequencerRequest* request = m_readRequestTable.lookup(address); - removeRequest(request); + SequencerRequest* request = m_readRequestTable.lookup(address); + removeRequest(request); - assert((request->ruby_request.type == RubyRequestType_LD) || - (request->ruby_request.type == RubyRequestType_RMW_Read) || - (request->ruby_request.type == RubyRequestType_IFETCH)); + assert((request->ruby_request.type == RubyRequestType_LD) || + (request->ruby_request.type == RubyRequestType_RMW_Read) || + (request->ruby_request.type == RubyRequestType_IFETCH)); - hitCallback(request, data); + hitCallback(request, data); } -void Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data) { - const RubyRequest & ruby_request = srequest->ruby_request; - Address request_address(ruby_request.paddr); - Address request_line_address(ruby_request.paddr); - request_line_address.makeLineAddress(); - RubyRequestType type = ruby_request.type; - Time issued_time = srequest->issue_time; - - // Set this cache entry to the most recently used - if (type == RubyRequestType_IFETCH) { - if (m_instCache_ptr->isTagPresent(request_line_address) ) - m_instCache_ptr->setMRU(request_line_address); - } else { - if (m_dataCache_ptr->isTagPresent(request_line_address) ) - m_dataCache_ptr->setMRU(request_line_address); - } - - assert(g_eventQueue_ptr->getTime() >= issued_time); - Time miss_latency = g_eventQueue_ptr->getTime() - issued_time; - - // Profile the miss latency for all non-zero demand misses - if (miss_latency != 0) { - g_system_ptr->getProfiler()->missLatency(miss_latency, type); +void +Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data) +{ + const RubyRequest & ruby_request = srequest->ruby_request; + Address request_address(ruby_request.paddr); + Address request_line_address(ruby_request.paddr); + request_line_address.makeLineAddress(); + RubyRequestType type = ruby_request.type; + Time issued_time = srequest->issue_time; + + // Set this cache entry to the most recently used + if (type == RubyRequestType_IFETCH) { + if (m_instCache_ptr->isTagPresent(request_line_address)) + m_instCache_ptr->setMRU(request_line_address); + } else { + if (m_dataCache_ptr->isTagPresent(request_line_address)) + m_dataCache_ptr->setMRU(request_line_address); + } + + assert(g_eventQueue_ptr->getTime() >= issued_time); + Time miss_latency = g_eventQueue_ptr->getTime() - issued_time; - if (Debug::getProtocolTrace()) { - g_system_ptr->getProfiler()->profileTransition("Seq", m_version, Address(ruby_request.paddr), - "", "Done", "", int_to_string(miss_latency)+" cycles"); + // Profile the miss latency for all non-zero demand misses + if (miss_latency != 0) { + g_system_ptr->getProfiler()->missLatency(miss_latency, type); + + if (Debug::getProtocolTrace()) { + g_system_ptr->getProfiler()-> + profileTransition("Seq", m_version, + Address(ruby_request.paddr), "", "Done", "", + csprintf("%d cycles", miss_latency)); + } } - } - /* - if (request.getPrefetch() == PrefetchBit_Yes) { - return; // Ignore the prefetch - } - */ - - // update the data - if (ruby_request.data != NULL) { - if ((type == RubyRequestType_LD) || - (type == RubyRequestType_IFETCH) || - (type == RubyRequestType_RMW_Read) || - (type == RubyRequestType_Locked_Read)) { - - memcpy(ruby_request.data, - data.getData(request_address.getOffset(), ruby_request.len), - ruby_request.len); - - } else { +#if 0 + if (request.getPrefetch() == PrefetchBit_Yes) { + return; // Ignore the prefetch + } +#endif - data.setData(ruby_request.data, - request_address.getOffset(), - ruby_request.len); + // update the data + if (ruby_request.data != NULL) { + if ((type == RubyRequestType_LD) || + (type == RubyRequestType_IFETCH) || + (type == RubyRequestType_RMW_Read) || + (type == RubyRequestType_Locked_Read)) { + + memcpy(ruby_request.data, + data.getData(request_address.getOffset(), ruby_request.len), + ruby_request.len); + } else { + data.setData(ruby_request.data, request_address.getOffset(), + ruby_request.len); + } + } else { + DPRINTF(MemoryAccess, + "WARNING. Data not transfered from Ruby to M5 for type %s\n", + RubyRequestType_to_string(type)); + } + // If using the RubyTester, update the RubyTester sender state's + // subBlock with the recieved data. The tester will later access + // this state. + // Note: RubyPort will access it's sender state before the + // RubyTester. + if (m_usingRubyTester) { + RubyPort::SenderState *requestSenderState = + safe_cast<RubyPort::SenderState*>(ruby_request.pkt->senderState); + RubyTester::SenderState* testerSenderState = + safe_cast<RubyTester::SenderState*>(requestSenderState->saved); + testerSenderState->subBlock->mergeFrom(data); } - } else { - DPRINTF(MemoryAccess, - "WARNING. Data not transfered from Ruby to M5 for type %s\n", - RubyRequestType_to_string(type)); - } - - // - // If using the RubyTester, update the RubyTester sender state's subBlock - // with the recieved data. The tester will later access this state. - // Note: RubyPort will access it's sender state before the RubyTester. - // - if (m_usingRubyTester) { - RubyTester::SenderState* testerSenderState; - testerSenderState = safe_cast<RubyTester::SenderState*>( \ - safe_cast<RubyPort::SenderState*>(ruby_request.pkt->senderState)->saved); - testerSenderState->subBlock->mergeFrom(data); - } - - ruby_hit_callback(ruby_request.pkt); - delete srequest; + + ruby_hit_callback(ruby_request.pkt); + delete srequest; } // Returns true if the sequencer already has a load or store outstanding -RequestStatus Sequencer::getRequestStatus(const RubyRequest& request) { - bool is_outstanding_store = m_writeRequestTable.exist(line_address(Address(request.paddr))); - bool is_outstanding_load = m_readRequestTable.exist(line_address(Address(request.paddr))); - if ( is_outstanding_store ) { - if ((request.type == RubyRequestType_LD) || - (request.type == RubyRequestType_IFETCH) || - (request.type == RubyRequestType_RMW_Read)) { - m_store_waiting_on_load_cycles++; - } else { - m_store_waiting_on_store_cycles++; +RequestStatus +Sequencer::getRequestStatus(const RubyRequest& request) +{ + bool is_outstanding_store = + m_writeRequestTable.exist(line_address(Address(request.paddr))); + bool is_outstanding_load = + m_readRequestTable.exist(line_address(Address(request.paddr))); + if (is_outstanding_store) { + if ((request.type == RubyRequestType_LD) || + (request.type == RubyRequestType_IFETCH) || + (request.type == RubyRequestType_RMW_Read)) { + m_store_waiting_on_load_cycles++; + } else { + m_store_waiting_on_store_cycles++; + } + return RequestStatus_Aliased; + } else if (is_outstanding_load) { + if ((request.type == RubyRequestType_ST) || + (request.type == RubyRequestType_RMW_Write)) { + m_load_waiting_on_store_cycles++; + } else { + m_load_waiting_on_load_cycles++; + } + return RequestStatus_Aliased; } - return RequestStatus_Aliased; - } else if ( is_outstanding_load ) { - if ((request.type == RubyRequestType_ST) || - (request.type == RubyRequestType_RMW_Write) ) { - m_load_waiting_on_store_cycles++; - } else { - m_load_waiting_on_load_cycles++; + + if (m_outstanding_count >= m_max_outstanding_requests) { + return RequestStatus_BufferFull; } - return RequestStatus_Aliased; - } - - if (m_outstanding_count >= m_max_outstanding_requests) { - return RequestStatus_BufferFull; - } - - return RequestStatus_Ready; -} -bool Sequencer::empty() const { - return (m_writeRequestTable.size() == 0) && (m_readRequestTable.size() == 0); + return RequestStatus_Ready; } +bool +Sequencer::empty() const +{ + return m_writeRequestTable.size() == 0 && m_readRequestTable.size() == 0; +} -RequestStatus Sequencer::makeRequest(const RubyRequest & request) +RequestStatus +Sequencer::makeRequest(const RubyRequest &request) { - assert(Address(request.paddr).getOffset() + request.len <= - RubySystem::getBlockSizeBytes()); - RequestStatus status = getRequestStatus(request); - if (status == RequestStatus_Ready) { - SequencerRequest *srequest = new SequencerRequest(request, - g_eventQueue_ptr->getTime()); + assert(Address(request.paddr).getOffset() + request.len <= + RubySystem::getBlockSizeBytes()); + RequestStatus status = getRequestStatus(request); + if (status != RequestStatus_Ready) + return status; + + SequencerRequest *srequest = + new SequencerRequest(request, g_eventQueue_ptr->getTime()); bool found = insertRequest(srequest); - if (!found) { - if (request.type == RubyRequestType_Locked_Write) { - // - // NOTE: it is OK to check the locked flag here as the mandatory queue - // will be checked first ensuring that nothing comes between checking - // the flag and servicing the store. - // - if (!m_dataCache_ptr->isLocked(line_address(Address(request.paddr)), - m_version)) { - removeRequest(srequest); - if (Debug::getProtocolTrace()) { - - g_system_ptr->getProfiler()->profileTransition("Seq", - m_version, - Address(request.paddr), - "", - "SC Fail", - "", - RubyRequestType_to_string(request.type)); + if (found) { + panic("Sequencer::makeRequest should never be called if the " + "request is already outstanding\n"); + return RequestStatus_NULL; + } + if (request.type == RubyRequestType_Locked_Write) { + // NOTE: it is OK to check the locked flag here as the + // mandatory queue will be checked first ensuring that nothing + // comes between checking the flag and servicing the store. + + Address line_addr = line_address(Address(request.paddr)); + if (!m_dataCache_ptr->isLocked(line_addr, m_version)) { + removeRequest(srequest); + if (Debug::getProtocolTrace()) { + g_system_ptr->getProfiler()-> + profileTransition("Seq", m_version, + Address(request.paddr), + "", "SC Fail", "", + RubyRequestType_to_string(request.type)); } return RequestStatus_LlscFailed; - } - else { - m_dataCache_ptr->clearLocked(line_address(Address(request.paddr))); + } else { + m_dataCache_ptr->clearLocked(line_addr); } - } - issueRequest(request); + } + issueRequest(request); - // TODO: issue hardware prefetches here - return RequestStatus_Issued; + // TODO: issue hardware prefetches here + return RequestStatus_Issued; +} + +void +Sequencer::issueRequest(const RubyRequest& request) +{ + // TODO: get rid of CacheMsg, CacheRequestType, and + // AccessModeTYpe, & have SLICC use RubyRequest and subtypes + // natively + CacheRequestType ctype; + switch(request.type) { + case RubyRequestType_IFETCH: + ctype = CacheRequestType_IFETCH; + break; + case RubyRequestType_LD: + ctype = CacheRequestType_LD; + break; + case RubyRequestType_ST: + ctype = CacheRequestType_ST; + break; + case RubyRequestType_Locked_Read: + case RubyRequestType_Locked_Write: + ctype = CacheRequestType_ATOMIC; + break; + case RubyRequestType_RMW_Read: + ctype = CacheRequestType_ATOMIC; + break; + case RubyRequestType_RMW_Write: + ctype = CacheRequestType_ATOMIC; + break; + default: + assert(0); } - else { - panic("Sequencer::makeRequest should never be called if the request"\ - "is already outstanding\n"); - return RequestStatus_NULL; + + AccessModeType amtype; + switch(request.access_mode){ + case RubyAccessMode_User: + amtype = AccessModeType_UserMode; + break; + case RubyAccessMode_Supervisor: + amtype = AccessModeType_SupervisorMode; + break; + case RubyAccessMode_Device: + amtype = AccessModeType_UserMode; + break; + default: + assert(0); } - } else { - return status; - } -} -void Sequencer::issueRequest(const RubyRequest& request) { - - // TODO: get rid of CacheMsg, CacheRequestType, and AccessModeTYpe, & have SLICC use RubyRequest and subtypes natively - CacheRequestType ctype; - switch(request.type) { - case RubyRequestType_IFETCH: - ctype = CacheRequestType_IFETCH; - break; - case RubyRequestType_LD: - ctype = CacheRequestType_LD; - break; - case RubyRequestType_ST: - ctype = CacheRequestType_ST; - break; - case RubyRequestType_Locked_Read: - case RubyRequestType_Locked_Write: - ctype = CacheRequestType_ATOMIC; - break; - case RubyRequestType_RMW_Read: - ctype = CacheRequestType_ATOMIC; - break; - case RubyRequestType_RMW_Write: - ctype = CacheRequestType_ATOMIC; - break; - default: - assert(0); - } - AccessModeType amtype; - switch(request.access_mode){ - case RubyAccessMode_User: - amtype = AccessModeType_UserMode; - break; - case RubyAccessMode_Supervisor: - amtype = AccessModeType_SupervisorMode; - break; - case RubyAccessMode_Device: - amtype = AccessModeType_UserMode; - break; - default: - assert(0); - } - Address line_addr(request.paddr); - line_addr.makeLineAddress(); - CacheMsg msg(line_addr, Address(request.paddr), ctype, Address(request.pc), amtype, request.len, PrefetchBit_No, request.proc_id); - - if (Debug::getProtocolTrace()) { - g_system_ptr->getProfiler()->profileTransition("Seq", m_version, Address(request.paddr), - "", "Begin", "", RubyRequestType_to_string(request.type)); - } - - if (g_system_ptr->getTracer()->traceEnabled()) { - g_system_ptr->getTracer()->traceRequest(this, line_addr, Address(request.pc), - request.type, g_eventQueue_ptr->getTime()); - } - - Time latency = 0; // initialzed to an null value - - if (request.type == RubyRequestType_IFETCH) - latency = m_instCache_ptr->getLatency(); - else - latency = m_dataCache_ptr->getLatency(); - - // Send the message to the cache controller - assert(latency > 0); - - assert(m_mandatory_q_ptr != NULL); - m_mandatory_q_ptr->enqueue(msg, latency); -} -/* -bool Sequencer::tryCacheAccess(const Address& addr, CacheRequestType type, - AccessModeType access_mode, - int size, DataBlock*& data_ptr) { - if (type == CacheRequestType_IFETCH) { - return m_instCache_ptr->tryCacheAccess(line_address(addr), type, data_ptr); - } else { - return m_dataCache_ptr->tryCacheAccess(line_address(addr), type, data_ptr); - } + Address line_addr(request.paddr); + line_addr.makeLineAddress(); + CacheMsg msg(line_addr, Address(request.paddr), ctype, + Address(request.pc), amtype, request.len, PrefetchBit_No, + request.proc_id); + + if (Debug::getProtocolTrace()) { + g_system_ptr->getProfiler()-> + profileTransition("Seq", m_version, Address(request.paddr), + "", "Begin", "", + RubyRequestType_to_string(request.type)); + } + + if (g_system_ptr->getTracer()->traceEnabled()) { + g_system_ptr->getTracer()-> + traceRequest(this, line_addr, Address(request.pc), + request.type, g_eventQueue_ptr->getTime()); + } + + Time latency = 0; // initialzed to an null value + + if (request.type == RubyRequestType_IFETCH) + latency = m_instCache_ptr->getLatency(); + else + latency = m_dataCache_ptr->getLatency(); + + // Send the message to the cache controller + assert(latency > 0); + + assert(m_mandatory_q_ptr != NULL); + m_mandatory_q_ptr->enqueue(msg, latency); } -*/ -void Sequencer::print(ostream& out) const { - out << "[Sequencer: " << m_version - << ", outstanding requests: " << m_outstanding_count; +#if 0 +bool +Sequencer::tryCacheAccess(const Address& addr, CacheRequestType type, + AccessModeType access_mode, + int size, DataBlock*& data_ptr) +{ + CacheMemory *cache = + (type == CacheRequestType_IFETCH) ? m_instCache_ptr : m_dataCache_ptr; - out << ", read request table: " << m_readRequestTable - << ", write request table: " << m_writeRequestTable; - out << "]"; + return cache->tryCacheAccess(line_address(addr), type, data_ptr); +} +#endif + +void +Sequencer::print(ostream& out) const +{ + out << "[Sequencer: " << m_version + << ", outstanding requests: " << m_outstanding_count + << ", read request table: " << m_readRequestTable + << ", write request table: " << m_writeRequestTable + << "]"; } -// this can be called from setState whenever coherence permissions are upgraded -// when invoked, coherence violations will be checked for the given block -void Sequencer::checkCoherence(const Address& addr) { +// this can be called from setState whenever coherence permissions are +// upgraded when invoked, coherence violations will be checked for the +// given block +void +Sequencer::checkCoherence(const Address& addr) +{ #ifdef CHECK_COHERENCE - g_system_ptr->checkGlobalCoherenceInvariant(addr); + g_system_ptr->checkGlobalCoherenceInvariant(addr); #endif } - diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh index 333ca5f24..69fd3b771 100644 --- a/src/mem/ruby/system/Sequencer.hh +++ b/src/mem/ruby/system/Sequencer.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,25 +26,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id: Sequencer.hh 1.70 2006/09/27 14:56:41-05:00 bobba@s1-01.cs.wisc.edu $ - * - * Description: - * - */ - -#ifndef SEQUENCER_H -#define SEQUENCER_H +#ifndef __MEM_RUBY_SYSTEM_SEQUENCER_HH__ +#define __MEM_RUBY_SYSTEM_SEQUENCER_HH__ -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/common/Consumer.hh" -#include "mem/protocol/CacheRequestType.hh" +#include "mem/gems_common/Map.hh" #include "mem/protocol/AccessModeType.hh" +#include "mem/protocol/CacheRequestType.hh" #include "mem/protocol/GenericMachineType.hh" #include "mem/protocol/PrefetchBit.hh" -#include "mem/ruby/system/RubyPort.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 "mem/ruby/system/RubyPort.hh" class DataBlock; class CacheMsg; @@ -54,109 +46,100 @@ class CacheMemory; class RubySequencerParams; -struct SequencerRequest { - RubyRequest ruby_request; - Time issue_time; +struct SequencerRequest +{ + RubyRequest ruby_request; + Time issue_time; - SequencerRequest(const RubyRequest & _ruby_request, - Time _issue_time) - : ruby_request(_ruby_request), - issue_time(_issue_time) - {} + SequencerRequest(const RubyRequest & _ruby_request, Time _issue_time) + : ruby_request(_ruby_request), issue_time(_issue_time) + {} }; std::ostream& operator<<(std::ostream& out, const SequencerRequest& obj); -class Sequencer : public RubyPort, public Consumer { -public: +class Sequencer : public RubyPort, public Consumer +{ + public: typedef RubySequencerParams Params; - // Constructors - Sequencer(const Params *); - - // Destructor - ~Sequencer(); + Sequencer(const Params *); + ~Sequencer(); - // Public Methods - void wakeup(); // Used only for deadlock detection + // Public Methods + void wakeup(); // Used only for deadlock detection - void printConfig(ostream& out) const; + void printConfig(ostream& out) const; - void printProgress(ostream& out) const; + void printProgress(ostream& out) const; - void writeCallback(const Address& address, DataBlock& data); - void readCallback(const Address& address, DataBlock& data); + void writeCallback(const Address& address, DataBlock& data); + void readCallback(const Address& address, DataBlock& data); - RequestStatus makeRequest(const RubyRequest & request); - RequestStatus getRequestStatus(const RubyRequest& request); - bool empty() const; + RequestStatus makeRequest(const RubyRequest & request); + RequestStatus getRequestStatus(const RubyRequest& request); + bool empty() const; - void print(ostream& out) const; - void printStats(ostream & out) const; - void checkCoherence(const Address& address); + void print(ostream& out) const; + void printStats(ostream & out) const; + void checkCoherence(const Address& address); - // bool getRubyMemoryValue(const Address& addr, char* value, unsigned int size_in_bytes); - // bool setRubyMemoryValue(const Address& addr, char *value, unsigned int size_in_bytes); + void removeRequest(SequencerRequest* request); - void removeRequest(SequencerRequest* request); -private: - // Private Methods - bool tryCacheAccess(const Address& addr, CacheRequestType type, const Address& pc, AccessModeType access_mode, int size, DataBlock*& data_ptr); - void issueRequest(const RubyRequest& request); + private: + bool tryCacheAccess(const Address& addr, CacheRequestType type, + const Address& pc, AccessModeType access_mode, + int size, DataBlock*& data_ptr); + void issueRequest(const RubyRequest& request); - void hitCallback(SequencerRequest* request, DataBlock& data); - bool insertRequest(SequencerRequest* request); + void hitCallback(SequencerRequest* request, DataBlock& data); + bool insertRequest(SequencerRequest* request); - // Private copy constructor and assignment operator - Sequencer(const Sequencer& obj); - Sequencer& operator=(const Sequencer& obj); + // Private copy constructor and assignment operator + Sequencer(const Sequencer& obj); + Sequencer& operator=(const Sequencer& obj); -private: - int m_max_outstanding_requests; - int m_deadlock_threshold; + private: + int m_max_outstanding_requests; + int m_deadlock_threshold; - CacheMemory* m_dataCache_ptr; - CacheMemory* m_instCache_ptr; + CacheMemory* m_dataCache_ptr; + CacheMemory* m_instCache_ptr; - Map<Address, SequencerRequest*> m_writeRequestTable; - Map<Address, SequencerRequest*> m_readRequestTable; - // Global outstanding request count, across all request tables - int m_outstanding_count; - bool m_deadlock_check_scheduled; + Map<Address, SequencerRequest*> m_writeRequestTable; + Map<Address, SequencerRequest*> m_readRequestTable; + // Global outstanding request count, across all request tables + int m_outstanding_count; + bool m_deadlock_check_scheduled; - int m_store_waiting_on_load_cycles; - int m_store_waiting_on_store_cycles; - int m_load_waiting_on_store_cycles; - int m_load_waiting_on_load_cycles; + int m_store_waiting_on_load_cycles; + int m_store_waiting_on_store_cycles; + int m_load_waiting_on_store_cycles; + int m_load_waiting_on_load_cycles; - bool m_usingRubyTester; + bool m_usingRubyTester; - class SequencerWakeupEvent : public Event - { - Sequencer *m_sequencer_ptr; + class SequencerWakeupEvent : public Event + { + private: + Sequencer *m_sequencer_ptr; - public: - SequencerWakeupEvent(Sequencer *_seq) : m_sequencer_ptr(_seq) {} - void process() { m_sequencer_ptr->wakeup(); } - const char *description() const { return "Sequencer deadlock check"; } - }; + public: + SequencerWakeupEvent(Sequencer *_seq) : m_sequencer_ptr(_seq) {} + void process() { m_sequencer_ptr->wakeup(); } + const char *description() const { return "Sequencer deadlock check"; } + }; - SequencerWakeupEvent deadlockCheckEvent; + SequencerWakeupEvent deadlockCheckEvent; }; -// Output operator declaration -ostream& operator<<(ostream& out, const Sequencer& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Sequencer& obj) +inline ostream& +operator<<(ostream& out, const Sequencer& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -#endif //SEQUENCER_H +#endif // __MEM_RUBY_SYSTEM_SEQUENCER_HH__ diff --git a/src/mem/ruby/system/SparseMemory.cc b/src/mem/ruby/system/SparseMemory.cc index c351f9e60..6271d24c3 100644 --- a/src/mem/ruby/system/SparseMemory.cc +++ b/src/mem/ruby/system/SparseMemory.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 2009 Advanced Micro Devices, Inc. * All rights reserved. @@ -29,10 +28,6 @@ #include "mem/ruby/system/SparseMemory.hh" - -// **************************************************************** - - SparseMemory::SparseMemory(int number_of_bits, int number_of_levels) { int even_level_bits; @@ -81,22 +76,16 @@ SparseMemory::recursivelyRemoveTables(SparseMapType* curTable, int curLevel) SparseMapType::iterator iter; for (iter = curTable->begin(); iter != curTable->end(); iter++) { - SparseMemEntry_t* entryStruct = &((*iter).second); + SparseMemEntry* entryStruct = &((*iter).second); if (curLevel != (m_number_of_levels - 1)) { - // - // If the not at the last level, analyze those lower level tables first, - // then delete those next tables - // - SparseMapType* nextTable; - nextTable = (SparseMapType*)(entryStruct->entry); + // If the not at the last level, analyze those lower level + // tables first, then delete those next tables + SparseMapType* nextTable = (SparseMapType*)(entryStruct->entry); recursivelyRemoveTables(nextTable, (curLevel + 1)); delete nextTable; - } else { - // // If at the last level, delete the directory entry - // Directory_Entry* dirEntry; dirEntry = (Directory_Entry*)(entryStruct->entry); delete dirEntry; @@ -104,15 +93,10 @@ SparseMemory::recursivelyRemoveTables(SparseMapType* curTable, int curLevel) entryStruct->entry = NULL; } - // // Once all entries have been deleted, erase the entries - // curTable->erase(curTable->begin(), curTable->end()); } - -// PUBLIC METHODS - // tests to see if an address is present in the memory bool SparseMemory::exist(const Address& address) const @@ -120,22 +104,19 @@ SparseMemory::exist(const Address& address) const SparseMapType* curTable = m_map_head; Address curAddress; - // - // Initiallize the high bit to be the total number of bits plus the block - // offset. However the highest bit index is one less than this value. - // + // Initiallize the high bit to be the total number of bits plus + // the block offset. However the highest bit index is one less + // than this value. int highBit = m_total_number_of_bits + RubySystem::getBlockSizeBits(); int lowBit; assert(address == line_address(address)); DEBUG_EXPR(CACHE_COMP, HighPrio, address); for (int level = 0; level < m_number_of_levels; level++) { - // // Create the appropriate sub address for this level - // Note: that set Address is inclusive of the specified range, thus the - // high bit is one less than the total number of bits used to create the - // address. - // + // Note: that set Address is inclusive of the specified range, + // thus the high bit is one less than the total number of bits + // used to create the address. lowBit = highBit - m_number_of_bits_per_level[level]; curAddress.setAddress(address.bitSelect(lowBit, highBit - 1)); @@ -144,15 +125,11 @@ SparseMemory::exist(const Address& address) const DEBUG_EXPR(CACHE_COMP, HighPrio, highBit - 1); DEBUG_EXPR(CACHE_COMP, HighPrio, curAddress); - // // Adjust the highBit value for the next level - // highBit -= m_number_of_bits_per_level[level]; - // - // If the address is found, move on to the next level. Otherwise, - // return not found - // + // If the address is found, move on to the next level. + // Otherwise, return not found if (curTable->count(curAddress) != 0) { curTable = (SparseMapType*)(((*curTable)[curAddress]).entry); } else { @@ -176,43 +153,34 @@ SparseMemory::add(const Address& address) Address curAddress; SparseMapType* curTable = m_map_head; - SparseMemEntry_t* entryStruct = NULL; + SparseMemEntry* entryStruct = NULL; - // - // Initiallize the high bit to be the total number of bits plus the block - // offset. However the highest bit index is one less than this value. - // + // Initiallize the high bit to be the total number of bits plus + // the block offset. However the highest bit index is one less + // than this value. int highBit = m_total_number_of_bits + RubySystem::getBlockSizeBits(); int lowBit; void* newEntry = NULL; for (int level = 0; level < m_number_of_levels; level++) { - // // create the appropriate address for this level - // Note: that set Address is inclusive of the specified range, thus the - // high bit is one less than the total number of bits used to create the - // address. - // + // Note: that set Address is inclusive of the specified range, + // thus the high bit is one less than the total number of bits + // used to create the address. lowBit = highBit - m_number_of_bits_per_level[level]; curAddress.setAddress(address.bitSelect(lowBit, highBit - 1)); - // // Adjust the highBit value for the next level - // highBit -= m_number_of_bits_per_level[level]; - // // if the address exists in the cur table, move on. Otherwise // create a new table. - // if (curTable->count(curAddress) != 0) { curTable = (SparseMapType*)(((*curTable)[curAddress]).entry); - } else { - + } else { m_adds_per_level[level]++; - // + // if the last level, add a directory entry. Otherwise add a map. - // if (level == (m_number_of_levels - 1)) { Directory_Entry* tempDirEntry = new Directory_Entry(); tempDirEntry->getDataBlk().clear(); @@ -222,17 +190,13 @@ SparseMemory::add(const Address& address) newEntry = (void*)(tempMap); } - // - // Create the pointer container SparseMemEntry_t and add it to the - // table. - // - entryStruct = new SparseMemEntry_t; + // Create the pointer container SparseMemEntry and add it + // to the table. + entryStruct = new SparseMemEntry; entryStruct->entry = newEntry; (*curTable)[curAddress] = *entryStruct; - // // Move to the next level of the heirarchy - // curTable = (SparseMapType*)newEntry; } } @@ -244,20 +208,17 @@ SparseMemory::add(const Address& address) // recursively search table hierarchy for the lowest level table. // remove the lowest entry and any empty tables above it. int -SparseMemory::recursivelyRemoveLevels( - const Address& address, - curNextInfo& curInfo) +SparseMemory::recursivelyRemoveLevels(const Address& address, + CurNextInfo& curInfo) { Address curAddress; - curNextInfo nextInfo; - SparseMemEntry_t* entryStruct; + CurNextInfo nextInfo; + SparseMemEntry* entryStruct; - // // create the appropriate address for this level - // Note: that set Address is inclusive of the specified range, thus the - // high bit is one less than the total number of bits used to create the - // address. - // + // Note: that set Address is inclusive of the specified range, + // thus the high bit is one less than the total number of bits + // used to create the address. curAddress.setAddress(address.bitSelect(curInfo.lowBit, curInfo.highBit - 1)); @@ -272,9 +233,7 @@ SparseMemory::recursivelyRemoveLevels( entryStruct = &((*(curInfo.curTable))[curAddress]); if (curInfo.level < (m_number_of_levels - 1)) { - // // set up next level's info - // nextInfo.curTable = (SparseMapType*)(entryStruct->entry); nextInfo.level = curInfo.level + 1; @@ -284,15 +243,11 @@ SparseMemory::recursivelyRemoveLevels( nextInfo.lowBit = curInfo.lowBit - m_number_of_bits_per_level[curInfo.level + 1]; - // // recursively search the table hierarchy - // int tableSize = recursivelyRemoveLevels(address, nextInfo); - // - // If this table below is now empty, we must delete it and erase it from - // our table. - // + // If this table below is now empty, we must delete it and + // erase it from our table. if (tableSize == 0) { m_removes_per_level[curInfo.level]++; delete nextInfo.curTable; @@ -300,10 +255,9 @@ SparseMemory::recursivelyRemoveLevels( curInfo.curTable->erase(curAddress); } } else { - // - // if this is the last level, we have reached the Directory Entry and thus - // we should delete it including the SparseMemEntry container struct. - // + // if this is the last level, we have reached the Directory + // Entry and thus we should delete it including the + // SparseMemEntry container struct. Directory_Entry* dirEntry; dirEntry = (Directory_Entry*)(entryStruct->entry); entryStruct->entry = NULL; @@ -323,26 +277,21 @@ SparseMemory::remove(const Address& address) m_total_removes++; - curNextInfo nextInfo; + CurNextInfo nextInfo; - // // Initialize table pointer and level value - // nextInfo.curTable = m_map_head; nextInfo.level = 0; - // - // Initiallize the high bit to be the total number of bits plus the block - // offset. However the highest bit index is one less than this value. - // + // Initiallize the high bit to be the total number of bits plus + // the block offset. However the highest bit index is one less + // than this value. nextInfo.highBit = m_total_number_of_bits + RubySystem::getBlockSizeBits(); nextInfo.lowBit = nextInfo.highBit - m_number_of_bits_per_level[0];; - // - // recursively search the table hierarchy for empty tables starting from the - // level 0. Note we do not check the return value because the head table is - // never deleted; - // + // recursively search the table hierarchy for empty tables + // starting from the level 0. Note we do not check the return + // value because the head table is never deleted; recursivelyRemoveLevels(address, nextInfo); assert(!exist(address)); @@ -362,20 +311,17 @@ SparseMemory::lookup(const Address& address) SparseMapType* curTable = m_map_head; Directory_Entry* entry = NULL; - // - // Initiallize the high bit to be the total number of bits plus the block - // offset. However the highest bit index is one less than this value. - // + // Initiallize the high bit to be the total number of bits plus + // the block offset. However the highest bit index is one less + // than this value. int highBit = m_total_number_of_bits + RubySystem::getBlockSizeBits(); int lowBit; for (int level = 0; level < m_number_of_levels; level++) { - // // create the appropriate address for this level - // Note: that set Address is inclusive of the specified range, thus the - // high bit is one less than the total number of bits used to create the - // address. - // + // Note: that set Address is inclusive of the specified range, + // thus the high bit is one less than the total number of bits + // used to create the address. lowBit = highBit - m_number_of_bits_per_level[level]; curAddress.setAddress(address.bitSelect(lowBit, highBit - 1)); @@ -384,21 +330,15 @@ SparseMemory::lookup(const Address& address) DEBUG_EXPR(CACHE_COMP, HighPrio, highBit - 1); DEBUG_EXPR(CACHE_COMP, HighPrio, curAddress); - // // Adjust the highBit value for the next level - // highBit -= m_number_of_bits_per_level[level]; - // // The entry should be in the table and valid - // curTable = (SparseMapType*)(((*curTable)[curAddress]).entry); assert(curTable != NULL); } - // // The last entry actually points to the Directory entry not a table - // entry = (Directory_Entry*)curTable; return entry; diff --git a/src/mem/ruby/system/SparseMemory.hh b/src/mem/ruby/system/SparseMemory.hh index 4a7ac98c2..6e3c8f926 100644 --- a/src/mem/ruby/system/SparseMemory.hh +++ b/src/mem/ruby/system/SparseMemory.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 2009 Advanced Micro Devices, Inc. * All rights reserved. @@ -27,39 +26,35 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef __MEM_RUBY_SYSTEM_SPARSEMEMORY_HH__ +#define __MEM_RUBY_SYSTEM_SPARSEMEMORY_HH__ -#ifndef SPARSEMEMORY_H -#define SPARSEMEMORY_H - -#include "mem/ruby/common/Global.hh" #include "base/hashmap.hh" -#include "mem/ruby/common/Address.hh" #include "mem/protocol/Directory_Entry.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" -typedef struct SparseMemEntry { +struct SparseMemEntry +{ void* entry; -} SparseMemEntry_t; +}; -typedef m5::hash_map<Address, SparseMemEntry_t> SparseMapType; +typedef m5::hash_map<Address, SparseMemEntry> SparseMapType; -typedef struct curNextInfo { +struct CurNextInfo +{ SparseMapType* curTable; int level; int highBit; int lowBit; }; -class SparseMemory { +class SparseMemory +{ public: - - // Constructors SparseMemory(int number_of_bits, int number_of_levels); - - // Destructor ~SparseMemory(); - // Public Methods - void printConfig(ostream& out) { } bool exist(const Address& address) const; @@ -83,7 +78,7 @@ class SparseMemory { void recursivelyRemoveTables(SparseMapType* currentTable, int level); // recursive search for address and remove associated entries - int recursivelyRemoveLevels(const Address& address, curNextInfo& curInfo); + int recursivelyRemoveLevels(const Address& address, CurNextInfo& curInfo); // Data Members (m_prefix) SparseMapType* m_map_head; @@ -98,17 +93,12 @@ class SparseMemory { uint64_t* m_removes_per_level; }; -// Output operator declaration -ostream& operator<<(ostream& out, const SparseMemEntry& obj); - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const SparseMemEntry& obj) +inline ostream& +operator<<(ostream& out, const SparseMemEntry& obj) { out << "SparseMemEntry"; out << flush; return out; } - -#endif //SPARSEMEMORY_H +#endif // __MEM_RUBY_SYSTEM_SPARSEMEMORY_HH__ diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc index 69dbf69c4..ef4b66290 100644 --- a/src/mem/ruby/system/System.cc +++ b/src/mem/ruby/system/System.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,25 +26,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * RubySystem.cc - * - * Description: See System.hh - * - * $Id$ - * - */ - - -#include "mem/ruby/system/System.hh" +#include "base/output.hh" +#include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/common/Address.hh" -#include "mem/ruby/profiler/Profiler.hh" #include "mem/ruby/network/Network.hh" +#include "mem/ruby/profiler/Profiler.hh" #include "mem/ruby/recorder/Tracer.hh" -#include "mem/ruby/buffers/MessageBuffer.hh" -#include "mem/ruby/system/MemoryVector.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" -#include "base/output.hh" +#include "mem/ruby/system/MemoryVector.hh" +#include "mem/ruby/system/System.hh" int RubySystem::m_random_seed; bool RubySystem::m_randomization; @@ -103,68 +92,68 @@ RubySystem::RubySystem(const Params *p) registerExitCallback(rubyExitCB); } - -void RubySystem::init() +void +RubySystem::init() { - m_profiler_ptr->clearStats(); + m_profiler_ptr->clearStats(); } - RubySystem::~RubySystem() { - delete m_network_ptr; - delete m_profiler_ptr; - delete m_tracer_ptr; - if (m_mem_vec_ptr != NULL) { - delete m_mem_vec_ptr; - } + delete m_network_ptr; + delete m_profiler_ptr; + delete m_tracer_ptr; + if (m_mem_vec_ptr) + delete m_mem_vec_ptr; } -void RubySystem::printSystemConfig(ostream & out) +void +RubySystem::printSystemConfig(ostream & out) { - out << "RubySystem config:" << endl; - out << " random_seed: " << m_random_seed << endl; - out << " randomization: " << m_randomization << endl; - out << " cycle_period: " << m_clock << endl; - out << " block_size_bytes: " << m_block_size_bytes << endl; - out << " block_size_bits: " << m_block_size_bits << endl; - out << " memory_size_bytes: " << m_memory_size_bytes << endl; - out << " memory_size_bits: " << m_memory_size_bits << endl; - + out << "RubySystem config:" << endl + << " random_seed: " << m_random_seed << endl + << " randomization: " << m_randomization << endl + << " cycle_period: " << m_clock << endl + << " block_size_bytes: " << m_block_size_bytes << endl + << " block_size_bits: " << m_block_size_bits << endl + << " memory_size_bytes: " << m_memory_size_bytes << endl + << " memory_size_bits: " << m_memory_size_bits << endl; } -void RubySystem::printConfig(ostream& out) +void +RubySystem::printConfig(ostream& out) { - out << "\n================ Begin RubySystem Configuration Print ================\n\n"; - printSystemConfig(out); - m_network_ptr->printConfig(out); - m_profiler_ptr->printConfig(out); - out << "\n================ End RubySystem Configuration Print ================\n\n"; + out << "\n================ Begin RubySystem Configuration Print ================\n\n"; + printSystemConfig(out); + m_network_ptr->printConfig(out); + m_profiler_ptr->printConfig(out); + out << "\n================ End RubySystem Configuration Print ================\n\n"; } -void RubySystem::printStats(ostream& out) +void +RubySystem::printStats(ostream& out) { + const time_t T = time(NULL); + tm *localTime = localtime(&T); + char buf[100]; + strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime); - const time_t T = time(NULL); - tm *localTime = localtime(&T); - char buf[100]; - strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime); - - out << "Real time: " << buf << endl; + out << "Real time: " << buf << endl; - m_profiler_ptr->printStats(out); - m_network_ptr->printStats(out); + m_profiler_ptr->printStats(out); + m_network_ptr->printStats(out); } -void RubySystem::clearStats() const +void +RubySystem::clearStats() const { - m_profiler_ptr->clearStats(); - m_network_ptr->clearStats(); + m_profiler_ptr->clearStats(); + m_network_ptr->clearStats(); } -void RubySystem::recordCacheContents(CacheRecorder& tr) const +void +RubySystem::recordCacheContents(CacheRecorder& tr) const { - } #ifdef CHECK_COHERENCE @@ -176,48 +165,46 @@ void RubySystem::recordCacheContents(CacheRecorder& tr) const // in setState. The SLICC spec must also define methods "isBlockShared" // and "isBlockExclusive" that are specific to that protocol // -void RubySystem::checkGlobalCoherenceInvariant(const Address& addr ) { - /* - NodeID exclusive = -1; - bool sharedDetected = false; - NodeID lastShared = -1; - - for (int i = 0; i < m_chip_vector.size(); i++) { - - if (m_chip_vector[i]->isBlockExclusive(addr)) { - if (exclusive != -1) { - // coherence violation - WARN_EXPR(exclusive); - WARN_EXPR(m_chip_vector[i]->getID()); - WARN_EXPR(addr); - WARN_EXPR(g_eventQueue_ptr->getTime()); - ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips"); - } - else if (sharedDetected) { - WARN_EXPR(lastShared); - WARN_EXPR(m_chip_vector[i]->getID()); - WARN_EXPR(addr); - WARN_EXPR(g_eventQueue_ptr->getTime()); - ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); - } - else { - exclusive = m_chip_vector[i]->getID(); - } - } - else if (m_chip_vector[i]->isBlockShared(addr)) { - sharedDetected = true; - lastShared = m_chip_vector[i]->getID(); - - if (exclusive != -1) { - WARN_EXPR(lastShared); - WARN_EXPR(exclusive); - WARN_EXPR(addr); - WARN_EXPR(g_eventQueue_ptr->getTime()); - ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); - } +void +RubySystem::checkGlobalCoherenceInvariant(const Address& addr) +{ +#if 0 + NodeID exclusive = -1; + bool sharedDetected = false; + NodeID lastShared = -1; + + for (int i = 0; i < m_chip_vector.size(); i++) { + if (m_chip_vector[i]->isBlockExclusive(addr)) { + if (exclusive != -1) { + // coherence violation + WARN_EXPR(exclusive); + WARN_EXPR(m_chip_vector[i]->getID()); + WARN_EXPR(addr); + WARN_EXPR(g_eventQueue_ptr->getTime()); + ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips"); + } else if (sharedDetected) { + WARN_EXPR(lastShared); + WARN_EXPR(m_chip_vector[i]->getID()); + WARN_EXPR(addr); + WARN_EXPR(g_eventQueue_ptr->getTime()); + ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); + } else { + exclusive = m_chip_vector[i]->getID(); + } + } else if (m_chip_vector[i]->isBlockShared(addr)) { + sharedDetected = true; + lastShared = m_chip_vector[i]->getID(); + + if (exclusive != -1) { + WARN_EXPR(lastShared); + WARN_EXPR(exclusive); + WARN_EXPR(addr); + WARN_EXPR(g_eventQueue_ptr->getTime()); + ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared"); + } + } } - } - */ +#endif } #endif @@ -231,7 +218,8 @@ RubySystemParams::create() * virtual process function that is invoked when the callback * queue is executed. */ -void RubyExitCallback::process() +void +RubyExitCallback::process() { std::ostream *os = simout.create(stats_filename); RubySystem::printConfig(*os); diff --git a/src/mem/ruby/system/System.hh b/src/mem/ruby/system/System.hh index 7868da4b6..ccec2d61c 100644 --- a/src/mem/ruby/system/System.hh +++ b/src/mem/ruby/system/System.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -28,32 +27,27 @@ */ /* - * System.hh - * - * Description: Contains all of the various parts of the system we are - * simulating. Performs allocation, deallocation, and setup of all - * the major components of the system - * - * $Id$ - * + * Contains all of the various parts of the system we are simulating. + * Performs allocation, deallocation, and setup of all the major + * components of the system */ -#ifndef SYSTEM_H -#define SYSTEM_H +#ifndef __MEM_RUBY_SYSTEM_SYSTEM_HH__ +#define __MEM_RUBY_SYSTEM_SYSTEM_HH__ -#include "mem/ruby/system/RubyPort.hh" -#include "mem/ruby/common/Global.hh" +#include "base/callback.hh" #include "mem/gems_common/Vector.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" -#include "sim/sim_object.hh" +#include "mem/ruby/system/RubyPort.hh" #include "params/RubySystem.hh" -#include "base/callback.hh" +#include "sim/sim_object.hh" -class Profiler; -class Network; class CacheRecorder; -class Tracer; class MemoryVector; +class Network; +class Profiler; +class Tracer; /* * This defines the number of longs (32-bits on 32 bit machines, @@ -68,83 +62,103 @@ class MemoryVector; */ const int NUMBER_WORDS_PER_SET = 1; -class RubySystem : public SimObject { -public: +class RubySystem : public SimObject +{ + public: typedef RubySystemParams Params; RubySystem(const Params *p); - // Destructor - ~RubySystem(); - - // config accessors - static int getRandomSeed() { return m_random_seed; } - static int getRandomization() { return m_randomization; } - static int getBlockSizeBytes() { return m_block_size_bytes; } - static int getBlockSizeBits() { return m_block_size_bits; } - static uint64 getMemorySizeBytes() { return m_memory_size_bytes; } - static int getMemorySizeBits() { return m_memory_size_bits; } - - // Public Methods - static Network* getNetwork() { assert(m_network_ptr != NULL); return m_network_ptr; } - static RubyEventQueue* getEventQueue() { return g_eventQueue_ptr; } - Profiler* getProfiler() {assert(m_profiler_ptr != NULL); return m_profiler_ptr; } - static Tracer* getTracer() { assert(m_tracer_ptr != NULL); return m_tracer_ptr; } - static MemoryVector* getMemoryVector() { assert(m_mem_vec_ptr != NULL); return m_mem_vec_ptr;} - - void recordCacheContents(CacheRecorder& tr) const; - static void printConfig(ostream& out); - static void printStats(ostream& out); - void clearStats() const; - - uint64 getInstructionCount(int thread) { return 1; } - static uint64 getCycleCount(int thread) { return g_eventQueue_ptr->getTime(); } - - void print(ostream& out) const; - /* -#ifdef CHECK_COHERENCE - void checkGlobalCoherenceInvariant(const Address& addr); -#endif - */ - -private: - // Private copy constructor and assignment operator - RubySystem(const RubySystem& obj); - RubySystem& operator=(const RubySystem& obj); - - void init(); - - static void printSystemConfig(ostream& out); - -private: - // configuration parameters - static int m_random_seed; - static bool m_randomization; - static Tick m_clock; - static int m_block_size_bytes; - static int m_block_size_bits; - static uint64 m_memory_size_bytes; - static int m_memory_size_bits; - - // Data Members (m_ prefix) - static Network* m_network_ptr; - -public: - static Profiler* m_profiler_ptr; - static Tracer* m_tracer_ptr; - static MemoryVector* m_mem_vec_ptr; -}; + ~RubySystem(); + + // config accessors + static int getRandomSeed() { return m_random_seed; } + static int getRandomization() { return m_randomization; } + static int getBlockSizeBytes() { return m_block_size_bytes; } + static int getBlockSizeBits() { return m_block_size_bits; } + static uint64 getMemorySizeBytes() { return m_memory_size_bytes; } + static int getMemorySizeBits() { return m_memory_size_bits; } + + // Public Methods + static Network* + getNetwork() + { + assert(m_network_ptr != NULL); + return m_network_ptr; + } -// Output operator declaration -ostream& operator<<(ostream& out, const RubySystem& obj); + static RubyEventQueue* + getEventQueue() + { + return g_eventQueue_ptr; + } -// ******************* Definitions ******************* + Profiler* + getProfiler() + { + assert(m_profiler_ptr != NULL); + return m_profiler_ptr; + } + + static Tracer* + getTracer() + { + assert(m_tracer_ptr != NULL); + return m_tracer_ptr; + } + + static MemoryVector* + getMemoryVector() + { + assert(m_mem_vec_ptr != NULL); + return m_mem_vec_ptr; + } + + void recordCacheContents(CacheRecorder& tr) const; + static void printConfig(ostream& out); + static void printStats(ostream& out); + void clearStats() const; + + uint64 getInstructionCount(int thread) { return 1; } + static uint64 + getCycleCount(int thread) + { + return g_eventQueue_ptr->getTime(); + } -// Output operator definition -inline -ostream& operator<<(ostream& out, const RubySystem& obj) + void print(ostream& out) const; + + private: + // Private copy constructor and assignment operator + RubySystem(const RubySystem& obj); + RubySystem& operator=(const RubySystem& obj); + + void init(); + + static void printSystemConfig(ostream& out); + + private: + // configuration parameters + static int m_random_seed; + static bool m_randomization; + static Tick m_clock; + static int m_block_size_bytes; + static int m_block_size_bits; + static uint64 m_memory_size_bytes; + static int m_memory_size_bits; + + static Network* m_network_ptr; + + public: + static Profiler* m_profiler_ptr; + static Tracer* m_tracer_ptr; + static MemoryVector* m_mem_vec_ptr; +}; + +inline ostream& +operator<<(ostream& out, const RubySystem& obj) { -// obj.print(out); - out << flush; - return out; + //obj.print(out); + out << flush; + return out; } class RubyExitCallback : public Callback @@ -153,22 +167,17 @@ class RubyExitCallback : public Callback string stats_filename; public: - /** - * virtualize the destructor to make sure that the correct one - * gets called. - */ - virtual ~RubyExitCallback() {} RubyExitCallback(const string& _stats_filename) { - stats_filename = _stats_filename; + stats_filename = _stats_filename; } virtual void process(); }; -#endif //SYSTEM_H +#endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__ diff --git a/src/mem/ruby/system/TBETable.hh b/src/mem/ruby/system/TBETable.hh index 2b00f7a06..d21946abd 100644 --- a/src/mem/ruby/system/TBETable.hh +++ b/src/mem/ruby/system/TBETable.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,141 +26,115 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * TBETable.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef TBETABLE_H -#define TBETABLE_H +#ifndef __MEM_RUBY_SYSTEM_TBETABLE_HH__ +#define __MEM_RUBY_SYSTEM_TBETABLE_HH__ -#include "mem/ruby/common/Global.hh" #include "mem/gems_common/Map.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/profiler/Profiler.hh" #include "mem/ruby/system/System.hh" template<class ENTRY> -class TBETable { -public: - - // Constructors - TBETable(int number_of_TBEs); - - - // Destructor - //~TBETable(); - - // Public Methods - - void printConfig(ostream& out) { out << "TBEs_per_TBETable: " << m_number_of_TBEs << endl; } - - bool isPresent(const Address& address) const; - void allocate(const Address& address); - void deallocate(const Address& address); - bool areNSlotsAvailable(int n) const { return (m_number_of_TBEs - m_map.size()) >= n; } - - ENTRY& lookup(const Address& address); - const ENTRY& lookup(const Address& address) const; - - // Print cache contents - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - TBETable(const TBETable& obj); - TBETable& operator=(const TBETable& obj); - - // Data Members (m_prefix) - Map<Address, ENTRY> m_map; - -private: - int m_number_of_TBEs; -}; - -// Output operator declaration -//ostream& operator<<(ostream& out, const TBETable<ENTRY>& obj); - -// ******************* Definitions ******************* - -// Output operator definition -template<class ENTRY> -extern inline -ostream& operator<<(ostream& out, const TBETable<ENTRY>& obj) +class TBETable { - obj.print(out); - out << flush; - return out; -} - - -// **************************************************************** - + public: + TBETable(int number_of_TBEs) + : m_number_of_TBEs(number_of_TBEs) + { + } + + void + printConfig(ostream& out) + { + out << "TBEs_per_TBETable: " << m_number_of_TBEs << endl; + } + + bool isPresent(const Address& address) const; + void allocate(const Address& address); + void deallocate(const Address& address); + bool + areNSlotsAvailable(int n) const + { + return (m_number_of_TBEs - m_map.size()) >= n; + } + + ENTRY& lookup(const Address& address); + const ENTRY& lookup(const Address& address) const; + + // Print cache contents + void print(ostream& out) const; + + private: + // Private copy constructor and assignment operator + TBETable(const TBETable& obj); + TBETable& operator=(const TBETable& obj); + + // Data Members (m_prefix) + Map<Address, ENTRY> m_map; + + private: + int m_number_of_TBEs; +}; template<class ENTRY> -extern inline -TBETable<ENTRY>::TBETable(int number_of_TBEs) +inline ostream& +operator<<(ostream& out, const TBETable<ENTRY>& obj) { - m_number_of_TBEs = number_of_TBEs; + obj.print(out); + out << flush; + return out; } -// PUBLIC METHODS - -// tests to see if an address is present in the cache template<class ENTRY> -extern inline -bool TBETable<ENTRY>::isPresent(const Address& address) const +inline bool +TBETable<ENTRY>::isPresent(const Address& address) const { - assert(address == line_address(address)); - assert(m_map.size() <= m_number_of_TBEs); - return m_map.exist(address); + assert(address == line_address(address)); + assert(m_map.size() <= m_number_of_TBEs); + return m_map.exist(address); } template<class ENTRY> -extern inline -void TBETable<ENTRY>::allocate(const Address& address) +inline void +TBETable<ENTRY>::allocate(const Address& address) { - assert(isPresent(address) == false); - assert(m_map.size() < m_number_of_TBEs); - m_map.add(address, ENTRY()); + assert(isPresent(address) == false); + assert(m_map.size() < m_number_of_TBEs); + m_map.add(address, ENTRY()); } template<class ENTRY> -extern inline -void TBETable<ENTRY>::deallocate(const Address& address) +inline void +TBETable<ENTRY>::deallocate(const Address& address) { - assert(isPresent(address) == true); - assert(m_map.size() > 0); - m_map.erase(address); + assert(isPresent(address) == true); + assert(m_map.size() > 0); + m_map.erase(address); } // looks an address up in the cache template<class ENTRY> -extern inline -ENTRY& TBETable<ENTRY>::lookup(const Address& address) +inline ENTRY& +TBETable<ENTRY>::lookup(const Address& address) { - assert(isPresent(address) == true); - return m_map.lookup(address); + assert(isPresent(address) == true); + return m_map.lookup(address); } // looks an address up in the cache template<class ENTRY> -extern inline -const ENTRY& TBETable<ENTRY>::lookup(const Address& address) const +inline const ENTRY& +TBETable<ENTRY>::lookup(const Address& address) const { - assert(isPresent(address) == true); - return m_map.lookup(address); + assert(isPresent(address) == true); + return m_map.lookup(address); } template<class ENTRY> -extern inline -void TBETable<ENTRY>::print(ostream& out) const +inline void +TBETable<ENTRY>::print(ostream& out) const { } -#endif //TBETABLE_H +#endif // __MEM_RUBY_SYSTEM_TBETABLE_HH__ diff --git a/src/mem/ruby/system/TimerTable.cc b/src/mem/ruby/system/TimerTable.cc index 5d496da04..eba04e3e3 100644 --- a/src/mem/ruby/system/TimerTable.cc +++ b/src/mem/ruby/system/TimerTable.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,101 +26,101 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - */ - #include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/TimerTable.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" +#include "mem/ruby/system/TimerTable.hh" TimerTable::TimerTable() { - m_consumer_ptr = NULL; - m_next_valid = false; - m_next_address = Address(0); - m_next_time = 0; + m_consumer_ptr = NULL; + m_next_valid = false; + m_next_address = Address(0); + m_next_time = 0; } - -bool TimerTable::isReady() const +bool +TimerTable::isReady() const { - if (m_map.size() == 0) { - return false; - } + if (m_map.size() == 0) { + return false; + } - if (!m_next_valid) { - updateNext(); - } - assert(m_next_valid); - return (g_eventQueue_ptr->getTime() >= m_next_time); + if (!m_next_valid) { + updateNext(); + } + assert(m_next_valid); + return (g_eventQueue_ptr->getTime() >= m_next_time); } -const Address& TimerTable::readyAddress() const +const Address& +TimerTable::readyAddress() const { - assert(isReady()); + assert(isReady()); - if (!m_next_valid) { - updateNext(); - } - assert(m_next_valid); - return m_next_address; + if (!m_next_valid) { + updateNext(); + } + assert(m_next_valid); + return m_next_address; } -void TimerTable::set(const Address& address, Time relative_latency) +void +TimerTable::set(const Address& address, Time relative_latency) { - assert(address == line_address(address)); - assert(relative_latency > 0); - assert(m_map.exist(address) == false); - Time ready_time = g_eventQueue_ptr->getTime() + relative_latency; - m_map.add(address, ready_time); - assert(m_consumer_ptr != NULL); - g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, ready_time); - m_next_valid = false; - - // Don't always recalculate the next ready address - if (ready_time <= m_next_time) { + assert(address == line_address(address)); + assert(relative_latency > 0); + assert(m_map.exist(address) == false); + Time ready_time = g_eventQueue_ptr->getTime() + relative_latency; + m_map.add(address, ready_time); + assert(m_consumer_ptr != NULL); + g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, ready_time); m_next_valid = false; - } + + // Don't always recalculate the next ready address + if (ready_time <= m_next_time) { + m_next_valid = false; + } } -void TimerTable::unset(const Address& address) +void +TimerTable::unset(const Address& address) { - assert(address == line_address(address)); - assert(m_map.exist(address) == true); - m_map.remove(address); + assert(address == line_address(address)); + assert(m_map.exist(address) == true); + m_map.remove(address); - // Don't always recalculate the next ready address - if (address == m_next_address) { - m_next_valid = false; - } + // Don't always recalculate the next ready address + if (address == m_next_address) { + m_next_valid = false; + } } -void TimerTable::print(ostream& out) const +void +TimerTable::print(ostream& out) const { } - -void TimerTable::updateNext() const +void +TimerTable::updateNext() const { - if (m_map.size() == 0) { - assert(m_next_valid == false); - return; - } - - Vector<Address> addresses = m_map.keys(); - m_next_address = addresses[0]; - m_next_time = m_map.lookup(m_next_address); + if (m_map.size() == 0) { + assert(m_next_valid == false); + return; + } - // 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; + 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; + } } - } - m_next_valid = true; + m_next_valid = true; } diff --git a/src/mem/ruby/system/TimerTable.hh b/src/mem/ruby/system/TimerTable.hh index eda84069d..96b4b0b15 100644 --- a/src/mem/ruby/system/TimerTable.hh +++ b/src/mem/ruby/system/TimerTable.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -27,70 +26,69 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * TimerTable.hh - * - * Description: - * - * $Id$ - * - */ +#ifndef __MEM_RUBY_SYSTEM_TIMERTABLE_HH__ +#define __MEM_RUBY_SYSTEM_TIMERTABLE_HH__ -#ifndef TIMERTABLE_H -#define TIMERTABLE_H +#include <cassert> -#include "mem/ruby/common/Global.hh" #include "mem/gems_common/Map.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" + class Consumer; -class TimerTable { -public: +class TimerTable +{ + public: + TimerTable(); - // Constructors - TimerTable(); + static void printConfig(ostream& out) {} - // Destructor - //~TimerTable(); + void + setConsumer(Consumer* consumer_ptr) + { + assert(m_consumer_ptr == NULL); + m_consumer_ptr = consumer_ptr; + } - // Class Methods - static void printConfig(ostream& out) {} + void + setDescription(const string& name) + { + m_name = name; + } - // Public Methods - void setConsumer(Consumer* consumer_ptr) { ASSERT(m_consumer_ptr==NULL); m_consumer_ptr = consumer_ptr; } - void setDescription(const string& name) { m_name = name; } + bool isReady() const; + const Address& readyAddress() const; + bool isSet(const Address& address) const { return m_map.exist(address); } + void set(const Address& address, Time relative_latency); + void unset(const Address& address); + void print(ostream& out) const; - bool isReady() const; - const Address& readyAddress() const; - bool isSet(const Address& address) const { return m_map.exist(address); } - void set(const Address& address, Time relative_latency); - void unset(const Address& address); - void print(ostream& out) const; -private: - // Private Methods - void updateNext() const; + private: + void updateNext() const; - // Private copy constructor and assignment operator - TimerTable(const TimerTable& obj); - TimerTable& operator=(const TimerTable& obj); + // Private copy constructor and assignment operator + TimerTable(const TimerTable& obj); + TimerTable& operator=(const TimerTable& obj); - // Data Members (m_prefix) - Map<Address, Time> 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 - Consumer* m_consumer_ptr; // Consumer to signal a wakeup() - string m_name; + // Data Members (m_prefix) + Map<Address, Time> 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 + Consumer* m_consumer_ptr; // Consumer to signal a wakeup() + string m_name; }; // ******************* Definitions ******************* // Output operator definition -extern inline -ostream& operator<<(ostream& out, const TimerTable& obj) +inline ostream& +operator<<(ostream& out, const TimerTable& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -#endif //TIMERTABLE_H + +#endif // __MEM_RUBY_SYSTEM_TIMERTABLE_HH__ |