/*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012-2013, 2015-2016, 2018 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
* Declaration of a structure to manage MSHRs.
*/
-#ifndef __MEM__CACHE__MISS__MSHR_QUEUE_HH__
-#define __MEM__CACHE__MISS__MSHR_QUEUE_HH__
+#ifndef __MEM_CACHE_MSHR_QUEUE_HH__
+#define __MEM_CACHE_MSHR_QUEUE_HH__
-#include <vector>
+#include <string>
+#include "base/types.hh"
#include "mem/cache/mshr.hh"
+#include "mem/cache/queue.hh"
#include "mem/packet.hh"
-#include "sim/drain.hh"
/**
* A Class for maintaining a list of pending and allocated memory requests.
*/
-class MSHRQueue : public Drainable
+class MSHRQueue : public Queue<MSHR>
{
private:
- /** Local label (for functional print requests) */
- const std::string label;
-
- /** MSHR storage. */
- MSHR *registers;
- /** Holds pointers to all allocated entries. */
- MSHR::List allocatedList;
- /** Holds pointers to entries that haven't been sent to the bus. */
- MSHR::List readyList;
- /** Holds non allocated entries. */
- MSHR::List freeList;
-
- // Parameters
- /**
- * The total number of entries in this queue. This number is set as the
- * number of entries requested plus (numReserve - 1). This allows for
- * the same number of effective entries while still maintaining the reserve.
- */
- const int numEntries;
/**
- * The number of entries to hold in reserve. This is needed because copy
- * operations can allocate upto 4 entries at one time.
+ * The number of entries to reserve for future demand accesses.
+ * Prevent prefetcher from taking all mshr entries
*/
- const int numReserve;
-
- /** Drain manager to inform of a completed drain */
- DrainManager *drainManager;
-
- MSHR::Iterator addToReadyList(MSHR *mshr);
-
+ const int demandReserve;
public:
- /** The number of allocated entries. */
- int allocated;
- /** The number of entries that have been forwarded to the bus. */
- int inServiceEntries;
- /** The index of this queue within the cache (MSHR queue vs. write
- * buffer). */
- const int index;
/**
* Create a queue with a given number of entries.
* @param num_entrys The number of entries in this queue.
* @param reserve The minimum number of entries needed to satisfy
* any access.
+ * @param demand_reserve The minimum number of entries needed to satisfy
+ * demand accesses.
*/
MSHRQueue(const std::string &_label, int num_entries, int reserve,
- int index);
-
- /** Destructor */
- ~MSHRQueue();
-
- /**
- * Find the first MSHR that matches the provided address.
- * @param addr The address to find.
- * @return Pointer to the matching MSHR, null if not found.
- */
- MSHR *findMatch(Addr addr) const;
-
- /**
- * Find and return all the matching entries in the provided vector.
- * @param addr The address to find.
- * @param matches The vector to return pointers to the matching entries.
- * @return True if any matches are found, false otherwise.
- * @todo Typedef the vector??
- */
- bool findMatches(Addr addr, std::vector<MSHR*>& matches) const;
-
- /**
- * Find any pending requests that overlap the given request.
- * @param pkt The request to find.
- * @return A pointer to the earliest matching MSHR.
- */
- MSHR *findPending(Addr addr, int size) const;
-
- bool checkFunctional(PacketPtr pkt, Addr blk_addr);
+ int demand_reserve);
/**
* Allocates a new MSHR for the request and size. This places the request
* as the first target in the MSHR.
- * @param pkt The request to handle.
- * @param size The number in bytes to fetch from memory.
+ *
+ * @param blk_addr The address of the block.
+ * @param blk_size The number of bytes to request.
+ * @param pkt The original miss.
+ * @param when_ready When should the MSHR be ready to act upon.
+ * @param order The logical order of this MSHR
+ * @param alloc_on_fill Should the cache allocate a block on fill
+ *
* @return The a pointer to the MSHR allocated.
*
* @pre There are free entries.
*/
- MSHR *allocate(Addr addr, int size, PacketPtr &pkt,
- Tick when, Counter order);
-
- /**
- * Removes the given MSHR from the queue. This places the MSHR on the
- * free list.
- * @param mshr
- */
- void deallocate(MSHR *mshr);
-
- /**
- * Remove a MSHR from the queue. Returns an iterator into the
- * allocatedList for faster squash implementation.
- * @param mshr The MSHR to remove.
- * @return An iterator to the next entry in the allocatedList.
- */
- MSHR::Iterator deallocateOne(MSHR *mshr);
+ MSHR *allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
+ Tick when_ready, Counter order, bool alloc_on_fill);
/**
* Moves the MSHR to the front of the pending list if it is not
*/
void moveToFront(MSHR *mshr);
+ /**
+ * Adds a delay to the provided MSHR and moves MSHRs that will be
+ * ready earlier than this entry to the top of the list
+ *
+ * @param mshr that needs to be delayed
+ * @param delay_ticks ticks of the desired delay
+ */
+ void delay(MSHR *mshr, Tick delay_ticks);
+
/**
* Mark the given MSHR as in service. This removes the MSHR from the
- * readyList. Deallocates the MSHR if it does not expect a response.
+ * readyList or deallocates the MSHR if it does not expect a response.
+ *
* @param mshr The MSHR to mark in service.
+ * @param pending_modified_resp Whether we expect a modified response
+ * from another cache
*/
- void markInService(MSHR *mshr, PacketPtr pkt);
+ void markInService(MSHR *mshr, bool pending_modified_resp);
/**
* Mark an in service entry as pending, used to resend a request.
void markPending(MSHR *mshr);
/**
- * Squash outstanding requests with the given thread number. If a request
- * is in service, just squashes the targets.
- * @param threadNum The thread to squash.
+ * Deallocate top target, possibly freeing the MSHR
+ * @return if MSHR queue is no longer full
*/
- void squash(int threadNum);
+ bool forceDeallocateTarget(MSHR *mshr);
/**
* Returns true if the pending list is not empty.
}
/**
- * Returns true if there are no free entries.
- * @return True if this queue is full.
+ * Returns true if sufficient mshrs for prefetch.
+ * @return True if sufficient mshrs for prefetch.
*/
- bool isFull() const
+ bool canPrefetch() const
{
- return (allocated > numEntries - numReserve);
+ // @todo we may want to revisit the +1, currently added to
+ // keep regressions unchanged
+ return (allocated < numEntries - (numReserve + 1 + demandReserve));
}
-
- /**
- * Returns the MSHR at the head of the readyList.
- * @return The next request to service.
- */
- MSHR *getNextMSHR() const
- {
- if (readyList.empty() || readyList.front()->readyTime > curTick()) {
- return NULL;
- }
- return readyList.front();
- }
-
- Tick nextMSHRReadyTime() const
- {
- return readyList.empty() ? MaxTick : readyList.front()->readyTime;
- }
-
- unsigned int drain(DrainManager *dm);
};
-#endif //__MEM__CACHE__MISS__MSHR_QUEUE_HH__
+#endif //__MEM_CACHE_MSHR_QUEUE_HH__