MessageBuffer.hh revision 7456
12SN/A/* 21762SN/A * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A */ 282665SN/A 292SN/A/* 302SN/A * Unordered buffer of messages that can be inserted such 312SN/A * that they can be dequeued after a given delta time has expired. 322SN/A */ 336214Snate@binkert.org 342SN/A#ifndef __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__ 352SN/A#define __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__ 362SN/A 376214Snate@binkert.org#include <algorithm> 386214Snate@binkert.org#include <functional> 392SN/A#include <iostream> 402SN/A#include <vector> 412SN/A#include <string> 429180Sandreas.hansson@arm.com 4310474Sandreas.hansson@arm.com#include "mem/ruby/buffers/MessageBufferNode.hh" 449500Snilay@cs.wisc.edu#include "mem/ruby/common/Consumer.hh" 459180Sandreas.hansson@arm.com#include "mem/ruby/common/Global.hh" 4610276SAndreas.Sandberg@ARM.com#include "mem/ruby/eventqueue/RubyEventQueue.hh" 4710276SAndreas.Sandberg@ARM.com#include "mem/ruby/slicc_interface/Message.hh" 482SN/A 495543SN/Aclass MessageBuffer 502SN/A{ 515543SN/A public: 522SN/A MessageBuffer(const std::string &name = ""); 532SN/A 542SN/A static void printConfig(std::ostream& out) {} 552SN/A void 562SN/A setRecycleLatency(int recycle_latency) 572SN/A { 582SN/A m_recycle_latency = recycle_latency; 592SN/A } 609158Sandreas.hansson@arm.com 612SN/A // TRUE if head of queue timestamp <= SystemTime 629158Sandreas.hansson@arm.com bool 632SN/A isReady() const 649158Sandreas.hansson@arm.com { 652667SN/A return ((m_prio_heap.size() > 0) && 662130SN/A (m_prio_heap.front().m_time <= g_eventQueue_ptr->getTime())); 679180Sandreas.hansson@arm.com } 689180Sandreas.hansson@arm.com 699180Sandreas.hansson@arm.com void 709180Sandreas.hansson@arm.com delayHead() 719180Sandreas.hansson@arm.com { 729180Sandreas.hansson@arm.com MessageBufferNode node = m_prio_heap.front(); 739180Sandreas.hansson@arm.com std::pop_heap(m_prio_heap.begin(), m_prio_heap.end(), 749180Sandreas.hansson@arm.com std::greater<MessageBufferNode>()); 759180Sandreas.hansson@arm.com m_prio_heap.pop_back(); 769180Sandreas.hansson@arm.com enqueue(node.m_msgptr, 1); 779180Sandreas.hansson@arm.com } 789180Sandreas.hansson@arm.com 799180Sandreas.hansson@arm.com bool areNSlotsAvailable(int n); 809180Sandreas.hansson@arm.com int getPriority() { return m_priority_rank; } 819180Sandreas.hansson@arm.com void setPriority(int rank) { m_priority_rank = rank; } 829180Sandreas.hansson@arm.com void setConsumer(Consumer* consumer_ptr) 839180Sandreas.hansson@arm.com { 849180Sandreas.hansson@arm.com ASSERT(m_consumer_ptr == NULL); 859180Sandreas.hansson@arm.com m_consumer_ptr = consumer_ptr; 869180Sandreas.hansson@arm.com } 879180Sandreas.hansson@arm.com 889180Sandreas.hansson@arm.com void setDescription(const std::string& name) { m_name = name; } 899180Sandreas.hansson@arm.com std::string getDescription() { return m_name;} 909180Sandreas.hansson@arm.com 919180Sandreas.hansson@arm.com Consumer* getConsumer() { return m_consumer_ptr; } 929180Sandreas.hansson@arm.com 939180Sandreas.hansson@arm.com const Message* peekAtHeadOfQueue() const; 949180Sandreas.hansson@arm.com const Message* peek() const { return peekAtHeadOfQueue(); } 959180Sandreas.hansson@arm.com const MsgPtr getMsgPtrCopy() const; 969184Sandreas.hansson@arm.com 979184Sandreas.hansson@arm.com const MsgPtr& 989184Sandreas.hansson@arm.com peekMsgPtr() const 999180Sandreas.hansson@arm.com { 1009180Sandreas.hansson@arm.com assert(isReady()); 1019180Sandreas.hansson@arm.com return m_prio_heap.front().m_msgptr; 1029180Sandreas.hansson@arm.com } 1039180Sandreas.hansson@arm.com 1049180Sandreas.hansson@arm.com const MsgPtr& 1059180Sandreas.hansson@arm.com peekMsgPtrEvenIfNotReady() const 1069180Sandreas.hansson@arm.com { 1079180Sandreas.hansson@arm.com return m_prio_heap.front().m_msgptr; 1089180Sandreas.hansson@arm.com } 1099180Sandreas.hansson@arm.com 1109180Sandreas.hansson@arm.com void enqueue(MsgPtr message) { enqueue(message, 1); } 1119180Sandreas.hansson@arm.com void enqueue(MsgPtr message, Time delta); 1129180Sandreas.hansson@arm.com // void enqueueAbsolute(const MsgPtr& message, Time absolute_time); 1139180Sandreas.hansson@arm.com int dequeue_getDelayCycles(MsgPtr& message); // returns delay 1149180Sandreas.hansson@arm.com // cycles of the 1159180Sandreas.hansson@arm.com // message 1169180Sandreas.hansson@arm.com void dequeue(MsgPtr& message); 1179180Sandreas.hansson@arm.com int dequeue_getDelayCycles(); // returns delay cycles of the message 1189180Sandreas.hansson@arm.com void dequeue() { pop(); } 1199180Sandreas.hansson@arm.com void pop(); 1209498Snilay@cs.wisc.edu void recycle(); 1219498Snilay@cs.wisc.edu bool isEmpty() const { return m_prio_heap.size() == 0; } 1229498Snilay@cs.wisc.edu 1239498Snilay@cs.wisc.edu void 1249498Snilay@cs.wisc.edu setOrdering(bool order) 1259498Snilay@cs.wisc.edu { 1269498Snilay@cs.wisc.edu m_strict_fifo = order; 1279498Snilay@cs.wisc.edu m_ordering_set = true; 1289498Snilay@cs.wisc.edu } 1299498Snilay@cs.wisc.edu void resize(int size) { m_max_size = size; } 1309498Snilay@cs.wisc.edu int getSize(); 1319498Snilay@cs.wisc.edu void setRandomization(bool random_flag) { m_randomization = random_flag; } 1329500Snilay@cs.wisc.edu 1339500Snilay@cs.wisc.edu void clear(); 1349180Sandreas.hansson@arm.com 1359180Sandreas.hansson@arm.com void print(std::ostream& out) const; 1369180Sandreas.hansson@arm.com void printStats(std::ostream& out); 1379180Sandreas.hansson@arm.com void clearStats() { m_not_avail_count = 0; m_msg_counter = 0; } 1389180Sandreas.hansson@arm.com 1392130SN/A private: 1402130SN/A //added by SS 1412130SN/A int m_recycle_latency; 1422130SN/A 1432130SN/A // Private Methods 1442130SN/A int setAndReturnDelayCycles(MsgPtr message); 1452130SN/A 1467720Sgblack@eecs.umich.edu // Private copy constructor and assignment operator 1477720Sgblack@eecs.umich.edu MessageBuffer(const MessageBuffer& obj); 1487720Sgblack@eecs.umich.edu MessageBuffer& operator=(const MessageBuffer& obj); 1497720Sgblack@eecs.umich.edu 1507720Sgblack@eecs.umich.edu // Data Members (m_ prefix) 1517720Sgblack@eecs.umich.edu Consumer* m_consumer_ptr; // Consumer to signal a wakeup(), can be NULL 1527720Sgblack@eecs.umich.edu std::vector<MessageBufferNode> m_prio_heap; 1537720Sgblack@eecs.umich.edu std::string m_name; 1547720Sgblack@eecs.umich.edu 1557720Sgblack@eecs.umich.edu int m_max_size; 1567720Sgblack@eecs.umich.edu int m_size; 1577720Sgblack@eecs.umich.edu 1587720Sgblack@eecs.umich.edu Time m_time_last_time_size_checked; 1597720Sgblack@eecs.umich.edu int m_size_last_time_size_checked; 1607720Sgblack@eecs.umich.edu 1617720Sgblack@eecs.umich.edu // variables used so enqueues appear to happen imediately, while 1627720Sgblack@eecs.umich.edu // pop happen the next cycle 1637720Sgblack@eecs.umich.edu Time m_time_last_time_enqueue; 1647720Sgblack@eecs.umich.edu Time m_time_last_time_pop; 1657720Sgblack@eecs.umich.edu int m_size_at_cycle_start; 1667720Sgblack@eecs.umich.edu int m_msgs_this_cycle; 1677720Sgblack@eecs.umich.edu 1682438SN/A int m_not_avail_count; // count the # of times I didn't have N 1692438SN/A // slots available 1706221Snate@binkert.org int m_msg_counter; 1716221Snate@binkert.org int m_priority_rank; 1726221Snate@binkert.org bool m_strict_fifo; 1736221Snate@binkert.org bool m_ordering_set; 1746221Snate@binkert.org bool m_randomization; 1756221Snate@binkert.org Time m_last_arrival_time; 1769031Sandreas.hansson@arm.com}; 1779031Sandreas.hansson@arm.com 1789031Sandreas.hansson@arm.cominline std::ostream& 1799031Sandreas.hansson@arm.comoperator<<(std::ostream& out, const MessageBuffer& obj) 1809031Sandreas.hansson@arm.com{ 1819031Sandreas.hansson@arm.com obj.print(out); 1827678Sgblack@eecs.umich.edu out << std::flush; 18310474Sandreas.hansson@arm.com return out; 18410474Sandreas.hansson@arm.com} 18510474Sandreas.hansson@arm.com 18610474Sandreas.hansson@arm.com#endif // __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__ 18710474Sandreas.hansson@arm.com