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