Go to the documentation of this file.
49 #include "debug/RubyQueue.hh"
58 using stl_helpers::operator<<;
61 :
SimObject(
p), m_stall_map_size(0), m_max_size(
p.buffer_size),
62 m_max_dequeue_rate(
p.max_dequeue_rate), m_dequeues_this_cy(0),
63 m_time_last_time_size_checked(0),
64 m_time_last_time_enqueue(0), m_time_last_time_pop(0),
65 m_last_arrival_time(0), m_strict_fifo(
p.ordered),
66 m_randomization(
p.randomization),
67 m_allow_zero_latency(
p.allow_zero_latency),
68 m_routing_priority(
p.routing_priority),
70 "Number of times this buffer did not have N slots available"),
72 "Number of messages passed the buffer"),
73 ADD_STAT(m_buf_msgs, statistics::units::Rate<
74 statistics::units::
Count, statistics::units::
Tick>::get(),
75 "Average number of messages in buffer"),
77 "Total number of ticks messages were stalled in this buffer"),
79 "Number of times messages were stalled"),
80 ADD_STAT(m_avg_stall_time, statistics::units::Rate<
81 statistics::units::
Tick, statistics::units::
Count>::get(),
82 "Average stall ticks per message"),
83 ADD_STAT(m_occupancy, statistics::units::Rate<
84 statistics::units::Ratio, statistics::units::
Tick>::get(),
85 "Average occupancy of buffer capacity")
159 unsigned int current_size = 0;
160 unsigned int current_stall_size = 0;
181 if (current_size + current_stall_size +
n <=
m_max_size) {
184 DPRINTF(RubyQueue,
"n: %d, current_size: %d, heap size: %d, "
186 n, current_size + current_stall_size,
196 DPRINTF(RubyQueue,
"Peeking at head of queue.\n");
200 DPRINTF(RubyQueue,
"Message: %s\n", (*msg_ptr));
231 "Delta equals zero and allow_zero_latency is false during enqueue");
232 Tick arrival_time = 0;
240 arrival_time = current_time + delta;
254 assert(arrival_time >= current_time);
257 panic(
"FIFO ordering violated: %s name: %s current time: %d "
258 "delta: %d arrival_time: %d last arrival_time: %d\n",
259 *
this,
name(), current_time, delta, arrival_time,
270 Message* msg_ptr = message.get();
271 assert(msg_ptr != NULL);
274 "ensure we aren't dequeued early");
289 DPRINTF(RubyQueue,
"Enqueue arrival_time: %lld, Message: %s\n",
290 arrival_time, *(message.get()));
301 DPRINTF(RubyQueue,
"Popping\n");
308 message->updateDelayedTicks(current_time);
309 Tick delay = message->getDelayedTicks();
323 if (decrement_messages) {
369 DPRINTF(RubyQueue,
"Recycling.\n");
374 Tick future_time = current_time + recycle_latency;
375 node->setLastEnqueueTime(future_time);
385 while (!
lt.empty()) {
387 assert(
m->getLastEnqueueTime() <= schdTick);
391 std::greater<MsgPtr>());
395 DPRINTF(RubyQueue,
"Requeue arrival_time: %lld, Message: %s\n",
396 schdTick, *(
m.get()));
405 DPRINTF(RubyQueue,
"ReanalyzeMessages %#x\n",
addr);
423 DPRINTF(RubyQueue,
"ReanalyzeAllMessages\n");
471 DPRINTF(RubyQueue,
"Deferring enqueueing message: %s, Address %#x\n",
472 *(message.get()),
addr);
481 assert(msg_vec.size() > 0);
507 std::sort_heap(copy.begin(), copy.end(), std::greater<MsgPtr>());
519 (
m_prio_heap.front()->getLastEnqueueTime() <= current_time);
520 if (!can_dequeue && is_ready) {
524 return can_dequeue && is_ready;
539 DPRINTF(RubyQueue,
"functional %s for %#x\n",
540 is_read ?
"read" :
"write", pkt->
getAddr());
542 uint32_t num_functional_accesses = 0;
551 num_functional_accesses++;
553 num_functional_accesses++;
563 it != (map_iter->second).end(); ++it) {
569 num_functional_accesses++;
571 num_functional_accesses++;
575 return num_functional_accesses;
Tick curTick()
The universal simulation clock.
void recycle(Tick current_time, Tick recycle_latency)
void unregisterDequeueCallback()
std::shared_ptr< Message > MsgPtr
Tick m_time_last_time_size_checked
statistics::Formula m_avg_stall_time
void enqueueDeferredMessages(Addr addr, Tick curTime, Tick delay)
Consumer * m_consumer
Consumer to signal a wakeup(), can be NULL.
MessageBufferParams Params
void reanalyzeList(std::list< MsgPtr > &, Tick)
const FlagsType nozero
Don't print if this is zero.
DeferredMsgMapType m_deferred_msg_map
void enqueue(MsgPtr message, Tick curTime, Tick delta)
MessageBuffer(const Params &p)
statistics::Scalar m_stall_time
const unsigned int m_max_dequeue_rate
When != 0, isReady returns false once m_max_dequeue_rate messages have been dequeued in the same cycl...
const FlagsType nonan
Don't print if this is NAN.
Tick dequeue(Tick current_time, bool decrement_messages=true)
Updates the delay cycles of the message at the head of the queue, removes it from the queue and retur...
Tick getLastEnqueueTime() const
void stallMessage(Addr addr, Tick current_time)
statistics::Formula m_occupancy
void reanalyzeMessages(Addr addr, Tick current_time)
void ccprintf(cp::Print &print)
std::enable_if_t< std::is_integral_v< T >, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
const Message * peek() const
Function for extracting the message at the head of the message queue.
Cycles is a wrapper class for representing cycle counts, i.e.
unsigned int m_size_last_time_size_checked
unsigned int m_stalled_at_cycle_start
unsigned int m_msgs_this_cycle
void setMsgCounter(uint64_t c)
uint32_t functionalAccess(Packet *pkt, bool is_read, WriteMask *mask)
virtual void storeEventInfo(int info)
unsigned int m_size_at_cycle_start
virtual std::string name() const
void print(std::ostream &out) const
void scheduleEvent(Cycles timeDelta)
statistics::Scalar m_not_avail_count
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
uint64_t Tick
Tick count type.
virtual bool functionalWrite(Packet *pkt)
Addr getOffset(Addr addr)
static int getRandomization()
const MessageRandomization m_randomization
StallMsgMapType m_stall_msg_map
A map from line addresses to lists of stalled messages for that line.
Abstract superclass for simulation objects.
const unsigned int m_max_size
The maximum capacity.
virtual bool functionalRead(Packet *pkt)
The two functions below are used for reading / writing the message functionally.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
void updateDelayedTicks(Tick curTime)
Update the delay this message has experienced so far.
bool isDeferredMsgMapEmpty(Addr addr) const
bool isReady(Tick current_time) const
std::vector< MsgPtr > m_prio_heap
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
void registerDequeueCallback(std::function< void()> callback)
static bool getWarmupEnabled()
Tick m_time_last_time_pop
bool areNSlotsAvailable(unsigned int n, Tick curTime)
int m_stall_map_size
Current size of the stall map.
void setLastEnqueueTime(const Tick &time)
std::function< void()> m_dequeue_callback
statistics::Average m_buf_msgs
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
statistics::Scalar m_msg_count
bool hasStalledMsg(Addr addr) const
statistics::Scalar m_stall_count
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
unsigned int m_dequeues_this_cy
const bool m_allow_zero_latency
void deferEnqueueingMessage(Addr addr, MsgPtr message)
void scheduleEventAbsolute(Tick timeAbs)
void reanalyzeAllMessages(Tick current_time)
unsigned int getSize(Tick curTime)
Tick m_time_last_time_enqueue
#define panic(...)
This implements a cprintf based panic() function.
Generated on Sun Jul 30 2023 01:56:58 for gem5 by doxygen 1.8.17