MessageBuffer.hh revision 10096
114184Sgabeblack@google.com/* 214184Sgabeblack@google.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 314184Sgabeblack@google.com * All rights reserved. 414184Sgabeblack@google.com * 514184Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 614184Sgabeblack@google.com * modification, are permitted provided that the following conditions are 714184Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 814184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 914184Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1014184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1114184Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1214184Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1314184Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1414184Sgabeblack@google.com * this software without specific prior written permission. 1514184Sgabeblack@google.com * 1614184Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1714184Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1814184Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1914184Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2014184Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2114184Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2214184Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2314184Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2414184Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2514184Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2614184Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2714184Sgabeblack@google.com */ 2814184Sgabeblack@google.com 2914184Sgabeblack@google.com/* 3014184Sgabeblack@google.com * Unordered buffer of messages that can be inserted such 3114184Sgabeblack@google.com * that they can be dequeued after a given delta time has expired. 3214184Sgabeblack@google.com */ 3314184Sgabeblack@google.com 3414184Sgabeblack@google.com#ifndef __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__ 3514184Sgabeblack@google.com#define __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__ 3614184Sgabeblack@google.com 3714184Sgabeblack@google.com#include <algorithm> 3814184Sgabeblack@google.com#include <cassert> 3914184Sgabeblack@google.com#include <functional> 4014184Sgabeblack@google.com#include <iostream> 4114184Sgabeblack@google.com#include <string> 4214184Sgabeblack@google.com#include <vector> 4314184Sgabeblack@google.com 4414184Sgabeblack@google.com#include "mem/packet.hh" 4514184Sgabeblack@google.com#include "mem/ruby/buffers/MessageBufferNode.hh" 4614184Sgabeblack@google.com#include "mem/ruby/common/Address.hh" 4714184Sgabeblack@google.com#include "mem/ruby/common/Consumer.hh" 4814184Sgabeblack@google.com#include "mem/ruby/slicc_interface/Message.hh" 4914184Sgabeblack@google.com 5014184Sgabeblack@google.comclass MessageBuffer 5114184Sgabeblack@google.com{ 5214184Sgabeblack@google.com public: 5314184Sgabeblack@google.com MessageBuffer(const std::string &name = ""); 5414184Sgabeblack@google.com 5514184Sgabeblack@google.com std::string name() const { return m_name; } 5614184Sgabeblack@google.com 5714184Sgabeblack@google.com void setRecycleLatency(Cycles recycle_latency) 5814184Sgabeblack@google.com { m_recycle_latency = recycle_latency; } 5914184Sgabeblack@google.com 6014184Sgabeblack@google.com void reanalyzeMessages(const Address& addr); 6114184Sgabeblack@google.com void reanalyzeAllMessages(); 6214184Sgabeblack@google.com void stallMessage(const Address& addr); 6314184Sgabeblack@google.com 6414184Sgabeblack@google.com // TRUE if head of queue timestamp <= SystemTime 6514184Sgabeblack@google.com bool isReady() const; 6614184Sgabeblack@google.com 6714184Sgabeblack@google.com void 6814184Sgabeblack@google.com delayHead() 6914184Sgabeblack@google.com { 7014184Sgabeblack@google.com MessageBufferNode node = m_prio_heap.front(); 7114184Sgabeblack@google.com std::pop_heap(m_prio_heap.begin(), m_prio_heap.end(), 7214184Sgabeblack@google.com std::greater<MessageBufferNode>()); 7314184Sgabeblack@google.com m_prio_heap.pop_back(); 7414184Sgabeblack@google.com enqueue(node.m_msgptr, Cycles(1)); 7514184Sgabeblack@google.com } 7614184Sgabeblack@google.com 7714184Sgabeblack@google.com bool areNSlotsAvailable(unsigned int n); 7814184Sgabeblack@google.com int getPriority() { return m_priority_rank; } 7914184Sgabeblack@google.com void setPriority(int rank) { m_priority_rank = rank; } 8014184Sgabeblack@google.com void setConsumer(Consumer* consumer) 8114184Sgabeblack@google.com { 8214184Sgabeblack@google.com if (m_consumer != NULL) { 8314184Sgabeblack@google.com fatal("Trying to connect %s to MessageBuffer %s. \ 8414184Sgabeblack@google.com \n%s already connected. Check the cntrl_id's.\n", 8514184Sgabeblack@google.com *consumer, *this, *m_consumer); 8614184Sgabeblack@google.com } 8714184Sgabeblack@google.com m_consumer = consumer; 8814184Sgabeblack@google.com } 8914184Sgabeblack@google.com 9014184Sgabeblack@google.com void setSender(ClockedObject* obj) 9114184Sgabeblack@google.com { 9214184Sgabeblack@google.com assert(m_sender == NULL || m_sender == obj); 9314184Sgabeblack@google.com m_sender = obj; 9414184Sgabeblack@google.com } 9514184Sgabeblack@google.com 9614184Sgabeblack@google.com void setReceiver(ClockedObject* obj) 9714184Sgabeblack@google.com { 9814184Sgabeblack@google.com assert(m_receiver == NULL || m_receiver == obj); 9914184Sgabeblack@google.com m_receiver = obj; 10014184Sgabeblack@google.com } 10114184Sgabeblack@google.com 10214184Sgabeblack@google.com void setDescription(const std::string& name) { m_name = name; } 10314184Sgabeblack@google.com std::string getDescription() { return m_name;} 10414184Sgabeblack@google.com 10514184Sgabeblack@google.com Consumer* getConsumer() { return m_consumer; } 10614184Sgabeblack@google.com 10714184Sgabeblack@google.com //! Function for extracting the message at the head of the 10814184Sgabeblack@google.com //! message queue. The function assumes that the queue is nonempty. 10914184Sgabeblack@google.com const Message* peek() const; 11014184Sgabeblack@google.com 11114184Sgabeblack@google.com const MsgPtr& 11214184Sgabeblack@google.com peekMsgPtr() const 11314184Sgabeblack@google.com { 11414184Sgabeblack@google.com assert(isReady()); 11514184Sgabeblack@google.com return m_prio_heap.front().m_msgptr; 11614184Sgabeblack@google.com } 11714184Sgabeblack@google.com 11814184Sgabeblack@google.com void enqueue(MsgPtr message) { enqueue(message, Cycles(1)); } 11914184Sgabeblack@google.com void enqueue(MsgPtr message, Cycles delta); 12014184Sgabeblack@google.com 12114184Sgabeblack@google.com //! Updates the delay cycles of the message at the of the queue, 12214184Sgabeblack@google.com //! removes it from the queue and returns its total delay. 12314184Sgabeblack@google.com Cycles dequeue_getDelayCycles(); 12414184Sgabeblack@google.com 12514184Sgabeblack@google.com void dequeue(); 12614184Sgabeblack@google.com 12714184Sgabeblack@google.com void recycle(); 12814184Sgabeblack@google.com bool isEmpty() const { return m_prio_heap.size() == 0; } 12914184Sgabeblack@google.com 13014184Sgabeblack@google.com void 13114184Sgabeblack@google.com setOrdering(bool order) 13214184Sgabeblack@google.com { 13314184Sgabeblack@google.com m_strict_fifo = order; 13414184Sgabeblack@google.com m_ordering_set = true; 13514184Sgabeblack@google.com } 13614184Sgabeblack@google.com 13714184Sgabeblack@google.com void resize(unsigned int size) { m_max_size = size; } 13814184Sgabeblack@google.com unsigned int getSize(); 13914184Sgabeblack@google.com void setRandomization(bool random_flag) { m_randomization = random_flag; } 14014184Sgabeblack@google.com 14114184Sgabeblack@google.com void clear(); 14214184Sgabeblack@google.com void print(std::ostream& out) const; 14314184Sgabeblack@google.com void clearStats() { m_not_avail_count = 0; m_msg_counter = 0; } 14414184Sgabeblack@google.com 14514184Sgabeblack@google.com void setIncomingLink(int link_id) { m_input_link_id = link_id; } 14614184Sgabeblack@google.com void setVnet(int net) { m_vnet_id = net; } 14714184Sgabeblack@google.com 14814184Sgabeblack@google.com // Function for figuring out if any of the messages in the buffer can 14914184Sgabeblack@google.com // satisfy the read request for the address in the packet. 15014184Sgabeblack@google.com // Return value, if true, indicates that the request was fulfilled. 15114184Sgabeblack@google.com bool functionalRead(Packet *pkt); 15214184Sgabeblack@google.com 15314184Sgabeblack@google.com // Function for figuring out if any of the messages in the buffer need 15414184Sgabeblack@google.com // to be updated with the data from the packet. 15514184Sgabeblack@google.com // Return value indicates the number of messages that were updated. 15614184Sgabeblack@google.com // This required for debugging the code. 15714184Sgabeblack@google.com uint32_t functionalWrite(Packet *pkt); 15814184Sgabeblack@google.com 15914184Sgabeblack@google.com private: 16014184Sgabeblack@google.com void reanalyzeList(std::list<MsgPtr> &, Tick); 16114184Sgabeblack@google.com 16214184Sgabeblack@google.com private: 16314184Sgabeblack@google.com //added by SS 16414184Sgabeblack@google.com Cycles m_recycle_latency; 16514184Sgabeblack@google.com 16614184Sgabeblack@google.com // Data Members (m_ prefix) 16714184Sgabeblack@google.com //! The two ends of the buffer. 16814184Sgabeblack@google.com ClockedObject* m_sender; 16914184Sgabeblack@google.com ClockedObject* m_receiver; 17014184Sgabeblack@google.com 17114184Sgabeblack@google.com //! Consumer to signal a wakeup(), can be NULL 17214184Sgabeblack@google.com Consumer* m_consumer; 17314184Sgabeblack@google.com std::vector<MessageBufferNode> m_prio_heap; 17414184Sgabeblack@google.com 17514184Sgabeblack@google.com // use a std::map for the stalled messages as this container is 17614184Sgabeblack@google.com // sorted and ensures a well-defined iteration order 17714184Sgabeblack@google.com typedef std::map< Address, std::list<MsgPtr> > StallMsgMapType; 17814184Sgabeblack@google.com 17914184Sgabeblack@google.com StallMsgMapType m_stall_msg_map; 18014184Sgabeblack@google.com std::string m_name; 18114184Sgabeblack@google.com 18214184Sgabeblack@google.com unsigned int m_max_size; 18314184Sgabeblack@google.com Cycles m_time_last_time_size_checked; 18414184Sgabeblack@google.com unsigned int m_size_last_time_size_checked; 18514184Sgabeblack@google.com 18614184Sgabeblack@google.com // variables used so enqueues appear to happen imediately, while 18714184Sgabeblack@google.com // pop happen the next cycle 18814184Sgabeblack@google.com Cycles m_time_last_time_enqueue; 18914184Sgabeblack@google.com Cycles m_time_last_time_pop; 19014184Sgabeblack@google.com unsigned int m_size_at_cycle_start; 19114184Sgabeblack@google.com unsigned int m_msgs_this_cycle; 19214184Sgabeblack@google.com 19314184Sgabeblack@google.com int m_not_avail_count; // count the # of times I didn't have N 19414184Sgabeblack@google.com // slots available 19514184Sgabeblack@google.com uint64 m_msg_counter; 19614184Sgabeblack@google.com int m_priority_rank; 19714184Sgabeblack@google.com bool m_strict_fifo; 19814184Sgabeblack@google.com bool m_ordering_set; 19914184Sgabeblack@google.com bool m_randomization; 20014184Sgabeblack@google.com 20114184Sgabeblack@google.com Tick m_last_arrival_time; 20214184Sgabeblack@google.com 20314184Sgabeblack@google.com int m_input_link_id; 20414184Sgabeblack@google.com int m_vnet_id; 20514184Sgabeblack@google.com}; 20614184Sgabeblack@google.com 20714184Sgabeblack@google.comCycles random_time(); 20814184Sgabeblack@google.com 20914184Sgabeblack@google.cominline std::ostream& 21014184Sgabeblack@google.comoperator<<(std::ostream& out, const MessageBuffer& obj) 21114184Sgabeblack@google.com{ 21214184Sgabeblack@google.com obj.print(out); 21314184Sgabeblack@google.com out << std::flush; 21414184Sgabeblack@google.com return out; 21514184Sgabeblack@google.com} 21614184Sgabeblack@google.com 21714184Sgabeblack@google.com#endif // __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__ 21814184Sgabeblack@google.com