MessageBuffer.hh revision 8229
14524Sgblack@eecs.umich.edu/* 24524Sgblack@eecs.umich.edu * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 34524Sgblack@eecs.umich.edu * All rights reserved. 44524Sgblack@eecs.umich.edu * 54524Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 64524Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 74524Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 84524Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 94524Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 104524Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 114524Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 124524Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 134524Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 144524Sgblack@eecs.umich.edu * this software without specific prior written permission. 154524Sgblack@eecs.umich.edu * 164524Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174524Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184524Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194524Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204524Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214524Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224524Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234524Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244524Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254524Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264524Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274524Sgblack@eecs.umich.edu */ 284524Sgblack@eecs.umich.edu 294524Sgblack@eecs.umich.edu/* 304524Sgblack@eecs.umich.edu * Unordered buffer of messages that can be inserted such 314524Sgblack@eecs.umich.edu * that they can be dequeued after a given delta time has expired. 324524Sgblack@eecs.umich.edu */ 334524Sgblack@eecs.umich.edu 344524Sgblack@eecs.umich.edu#ifndef __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__ 354524Sgblack@eecs.umich.edu#define __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__ 364524Sgblack@eecs.umich.edu 374524Sgblack@eecs.umich.edu#include <algorithm> 384524Sgblack@eecs.umich.edu#include <cassert> 394524Sgblack@eecs.umich.edu#include <functional> 404524Sgblack@eecs.umich.edu#include <iostream> 414524Sgblack@eecs.umich.edu#include <string> 424524Sgblack@eecs.umich.edu#include <vector> 434524Sgblack@eecs.umich.edu 444524Sgblack@eecs.umich.edu#include "mem/ruby/buffers/MessageBufferNode.hh" 454524Sgblack@eecs.umich.edu#include "mem/ruby/common/Address.hh" 464524Sgblack@eecs.umich.edu#include "mem/ruby/common/Consumer.hh" 474524Sgblack@eecs.umich.edu#include "mem/ruby/common/Global.hh" 484524Sgblack@eecs.umich.edu#include "mem/ruby/eventqueue/RubyEventQueue.hh" 494524Sgblack@eecs.umich.edu#include "mem/ruby/slicc_interface/Message.hh" 504524Sgblack@eecs.umich.edu 514524Sgblack@eecs.umich.educlass MessageBuffer 524524Sgblack@eecs.umich.edu{ 534524Sgblack@eecs.umich.edu public: 544524Sgblack@eecs.umich.edu MessageBuffer(const std::string &name = ""); 554524Sgblack@eecs.umich.edu 564524Sgblack@eecs.umich.edu std::string name() const { return m_name; } 574524Sgblack@eecs.umich.edu 584524Sgblack@eecs.umich.edu static void printConfig(std::ostream& out) {} 594524Sgblack@eecs.umich.edu void 604524Sgblack@eecs.umich.edu setRecycleLatency(int recycle_latency) 614524Sgblack@eecs.umich.edu { 624524Sgblack@eecs.umich.edu m_recycle_latency = recycle_latency; 634524Sgblack@eecs.umich.edu } 644524Sgblack@eecs.umich.edu 654524Sgblack@eecs.umich.edu void reanalyzeMessages(const Address& addr); 664524Sgblack@eecs.umich.edu void reanalyzeAllMessages(); 674524Sgblack@eecs.umich.edu void stallMessage(const Address& addr); 684524Sgblack@eecs.umich.edu 694524Sgblack@eecs.umich.edu // TRUE if head of queue timestamp <= SystemTime 704524Sgblack@eecs.umich.edu bool 714524Sgblack@eecs.umich.edu isReady() const 724524Sgblack@eecs.umich.edu { 734524Sgblack@eecs.umich.edu return ((m_prio_heap.size() > 0) && 744524Sgblack@eecs.umich.edu (m_prio_heap.front().m_time <= g_eventQueue_ptr->getTime())); 754539Sgblack@eecs.umich.edu } 764524Sgblack@eecs.umich.edu 774524Sgblack@eecs.umich.edu void 784524Sgblack@eecs.umich.edu delayHead() 794524Sgblack@eecs.umich.edu { 804524Sgblack@eecs.umich.edu MessageBufferNode node = m_prio_heap.front(); 814524Sgblack@eecs.umich.edu std::pop_heap(m_prio_heap.begin(), m_prio_heap.end(), 824581Sgblack@eecs.umich.edu std::greater<MessageBufferNode>()); 834581Sgblack@eecs.umich.edu m_prio_heap.pop_back(); 844581Sgblack@eecs.umich.edu enqueue(node.m_msgptr, 1); 854524Sgblack@eecs.umich.edu } 864524Sgblack@eecs.umich.edu 874524Sgblack@eecs.umich.edu bool areNSlotsAvailable(int n); 884524Sgblack@eecs.umich.edu int getPriority() { return m_priority_rank; } 894524Sgblack@eecs.umich.edu void setPriority(int rank) { m_priority_rank = rank; } 904524Sgblack@eecs.umich.edu void setConsumer(Consumer* consumer_ptr) 914524Sgblack@eecs.umich.edu { 924524Sgblack@eecs.umich.edu assert(m_consumer_ptr == NULL); 934524Sgblack@eecs.umich.edu m_consumer_ptr = consumer_ptr; 944524Sgblack@eecs.umich.edu } 954524Sgblack@eecs.umich.edu 964524Sgblack@eecs.umich.edu void setDescription(const std::string& name) { m_name = name; } 974524Sgblack@eecs.umich.edu std::string getDescription() { return m_name;} 984524Sgblack@eecs.umich.edu 994581Sgblack@eecs.umich.edu Consumer* getConsumer() { return m_consumer_ptr; } 1004581Sgblack@eecs.umich.edu 1014581Sgblack@eecs.umich.edu const Message* peekAtHeadOfQueue() const; 1024581Sgblack@eecs.umich.edu const Message* peek() const { return peekAtHeadOfQueue(); } 1034581Sgblack@eecs.umich.edu const MsgPtr getMsgPtrCopy() const; 1044581Sgblack@eecs.umich.edu 1054581Sgblack@eecs.umich.edu const MsgPtr& 1064581Sgblack@eecs.umich.edu peekMsgPtr() const 1074581Sgblack@eecs.umich.edu { 1084581Sgblack@eecs.umich.edu assert(isReady()); 1094581Sgblack@eecs.umich.edu return m_prio_heap.front().m_msgptr; 1104581Sgblack@eecs.umich.edu } 1114581Sgblack@eecs.umich.edu 1124581Sgblack@eecs.umich.edu const MsgPtr& 1134524Sgblack@eecs.umich.edu peekMsgPtrEvenIfNotReady() const 1144524Sgblack@eecs.umich.edu { 1154524Sgblack@eecs.umich.edu return m_prio_heap.front().m_msgptr; 1164524Sgblack@eecs.umich.edu } 1174524Sgblack@eecs.umich.edu 1184524Sgblack@eecs.umich.edu void enqueue(MsgPtr message) { enqueue(message, 1); } 1194524Sgblack@eecs.umich.edu void enqueue(MsgPtr message, Time delta); 1204524Sgblack@eecs.umich.edu // void enqueueAbsolute(const MsgPtr& message, Time absolute_time); 1214524Sgblack@eecs.umich.edu int dequeue_getDelayCycles(MsgPtr& message); // returns delay 1224524Sgblack@eecs.umich.edu // cycles of the 1234524Sgblack@eecs.umich.edu // message 1244524Sgblack@eecs.umich.edu void dequeue(MsgPtr& message); 1254524Sgblack@eecs.umich.edu int dequeue_getDelayCycles(); // returns delay cycles of the message 1264524Sgblack@eecs.umich.edu void dequeue() { pop(); } 1274524Sgblack@eecs.umich.edu void pop(); 1284524Sgblack@eecs.umich.edu void recycle(); 1294524Sgblack@eecs.umich.edu bool isEmpty() const { return m_prio_heap.size() == 0; } 1304524Sgblack@eecs.umich.edu 1314524Sgblack@eecs.umich.edu void 1324524Sgblack@eecs.umich.edu setOrdering(bool order) 1334524Sgblack@eecs.umich.edu { 1344524Sgblack@eecs.umich.edu m_strict_fifo = order; 1354524Sgblack@eecs.umich.edu m_ordering_set = true; 1364524Sgblack@eecs.umich.edu } 1374524Sgblack@eecs.umich.edu void resize(int size) { m_max_size = size; } 1384524Sgblack@eecs.umich.edu int getSize(); 1394524Sgblack@eecs.umich.edu void setRandomization(bool random_flag) { m_randomization = random_flag; } 1404524Sgblack@eecs.umich.edu 1414524Sgblack@eecs.umich.edu void clear(); 1424524Sgblack@eecs.umich.edu 1434576Sgblack@eecs.umich.edu void print(std::ostream& out) const; 1444524Sgblack@eecs.umich.edu void printStats(std::ostream& out); 1454576Sgblack@eecs.umich.edu void clearStats() { m_not_avail_count = 0; m_msg_counter = 0; } 1464576Sgblack@eecs.umich.edu 1474524Sgblack@eecs.umich.edu void setIncomingLink(int link_id) { m_input_link_id = link_id; } 1484524Sgblack@eecs.umich.edu void setVnet(int net) { m_vnet_id = net; } 1494524Sgblack@eecs.umich.edu 1504524Sgblack@eecs.umich.edu private: 1514576Sgblack@eecs.umich.edu //added by SS 1524576Sgblack@eecs.umich.edu int m_recycle_latency; 1534524Sgblack@eecs.umich.edu 1544524Sgblack@eecs.umich.edu // Private Methods 1554524Sgblack@eecs.umich.edu int setAndReturnDelayCycles(MsgPtr message); 1564524Sgblack@eecs.umich.edu 1574576Sgblack@eecs.umich.edu // Private copy constructor and assignment operator 1584524Sgblack@eecs.umich.edu MessageBuffer(const MessageBuffer& obj); 1594524Sgblack@eecs.umich.edu MessageBuffer& operator=(const MessageBuffer& obj); 1604524Sgblack@eecs.umich.edu 1614524Sgblack@eecs.umich.edu // Data Members (m_ prefix) 1624524Sgblack@eecs.umich.edu Consumer* m_consumer_ptr; // Consumer to signal a wakeup(), can be NULL 1634524Sgblack@eecs.umich.edu std::vector<MessageBufferNode> m_prio_heap; 1644539Sgblack@eecs.umich.edu 1654524Sgblack@eecs.umich.edu typedef m5::hash_map< Address, std::list<MsgPtr> > StallMsgMapType; 1664524Sgblack@eecs.umich.edu typedef std::vector<MsgPtr>::iterator MsgListIter; 1674524Sgblack@eecs.umich.edu 1684581Sgblack@eecs.umich.edu StallMsgMapType m_stall_msg_map; 1694524Sgblack@eecs.umich.edu std::string m_name; 1704524Sgblack@eecs.umich.edu 171 int m_max_size; 172 int m_size; 173 174 Time m_time_last_time_size_checked; 175 int m_size_last_time_size_checked; 176 177 // variables used so enqueues appear to happen imediately, while 178 // pop happen the next cycle 179 Time m_time_last_time_enqueue; 180 Time m_time_last_time_pop; 181 int m_size_at_cycle_start; 182 int m_msgs_this_cycle; 183 184 int m_not_avail_count; // count the # of times I didn't have N 185 // slots available 186 uint64 m_msg_counter; 187 int m_priority_rank; 188 bool m_strict_fifo; 189 bool m_ordering_set; 190 bool m_randomization; 191 Time m_last_arrival_time; 192 193 int m_input_link_id; 194 int m_vnet_id; 195}; 196 197inline std::ostream& 198operator<<(std::ostream& out, const MessageBuffer& obj) 199{ 200 obj.print(out); 201 out << std::flush; 202 return out; 203} 204 205#endif // __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__ 206