summaryrefslogtreecommitdiff
path: root/src/mem/cache/miss/mshr_queue.hh
blob: 02b6a026d9c510f949150c32b0a740a899293078 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Erik Hallnor
 */

/** @file
 * Declaration of a structure to manage MSHRs.
 */

#ifndef __MSHR_QUEUE_HH__
#define __MSHR_QUEUE_HH__

#include <vector>
#include "mem/cache/miss/mshr.hh"

/**
 * A Class for maintaining a list of pending and allocated memory pktuests.
 */
class MSHRQueue {
  private:
    /**  MSHR storage. */
    MSHR* registers;
    /** Holds pointers to all allocated MSHRs. */
    MSHR::List allocatedList;
    /** Holds pointers to MSHRs that haven't been sent to the bus. */
    MSHR::List pendingList;
    /** Holds non allocated MSHRs. */
    MSHR::List freeList;

    // Parameters
    /**
     * The total number of MSHRs in this queue. This number is set as the
     * number of MSHRs pktuested plus (numReserve - 1). This allows for
     * the same number of effective MSHRs while still maintaining the reserve.
     */
    const int numMSHRs;

    /**
     * The number of MSHRs to hold in reserve. This is needed because copy
     * operations can allocate upto 4 MSHRs at one time.
     */
    const int numReserve;

  public:
    /** The number of allocated MSHRs. */
    int allocated;
    /** The number of MSHRs that have been forwarded to the bus. */
    int inServiceMSHRs;
    /** The number of targets waiting for response. */
    int allocatedTargets;

    /**
     * Create a queue with a given number of MSHRs.
     * @param num_mshrs The number of MSHRs in this queue.
     * @param reserve The minimum number of MSHRs needed to satisfy any access.
     */
    MSHRQueue(int num_mshrs, int reserve = 1);

    /** Destructor */
    ~MSHRQueue();

    /**
     * Find the first MSHR that matches the provide address and asid.
     * @param addr The address to find.
     * @param asid The address space id.
     * @return Pointer to the matching MSHR, null if not found.
     */
    MSHR* findMatch(Addr addr, int asid) const;

    /**
     * Find and return all the matching MSHRs in the provided vector.
     * @param addr The address to find.
     * @param asid The address space ID.
     * @param matches The vector to return pointers to the matching MSHRs.
     * @return True if any matches are found, false otherwise.
     * @todo Typedef the vector??
     */
    bool findMatches(Addr addr, int asid, std::vector<MSHR*>& matches) const;

    /**
     * Find any pending pktuests that overlap the given request.
     * @param pkt The request to find.
     * @return A pointer to the earliest matching MSHR.
     */
    MSHR* findPending(Packet * &pkt) const;

    /**
     * Allocates a new MSHR for the pktuest 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.
     * @return The a pointer to the MSHR allocated.
     *
     * @pre There are free MSHRs.
     */
    MSHR* allocate(Packet * &pkt, int size = 0);

    /**
     * Allocate a read pktuest for the given address, and places the given
     * target on the target list.
     * @param addr The address to fetch.
     * @param asid The address space for the fetch.
     * @param size The number of bytes to pktuest.
     * @param target The first target for the pktuest.
     * @return Pointer to the new MSHR.
     */
    MSHR* allocateFetch(Addr addr, int asid, int size, Packet * &target);

    /**
     * Allocate a target list for the given address.
     * @param addr The address to fetch.
     * @param asid The address space for the fetch.
     * @param size The number of bytes to pktuest.
     * @return Pointer to the new MSHR.
     */
    MSHR* allocateTargetList(Addr addr, int asid, int size);

    /**
     * Removes the given MSHR from the queue. This places the MSHR on the
     * free list.
     * @param mshr
     */
    void deallocate(MSHR* mshr);

    /**
     * Allocates a target to the given MSHR. Used to keep track of the number
     * of outstanding targets.
     * @param mshr The MSHR to allocate the target to.
     * @param pkt The target request.
     */
    void allocateTarget(MSHR* mshr, Packet * &pkt)
    {
        mshr->allocateTarget(pkt);
        allocatedTargets += 1;
    }

    /**
     * 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);

    /**
     * Moves the MSHR to the front of the pending list if it is not in service.
     * @param mshr The mshr to move.
     */
    void moveToFront(MSHR *mshr);

    /**
     * Mark the given MSHR as in service. This removes the MSHR from the
     * pendingList. Deallocates the MSHR if it does not expect a response.
     * @param mshr The MSHR to mark in service.
     */
    void markInService(MSHR* mshr);

    /**
     * Mark an in service mshr as pending, used to resend a pktuest.
     * @param mshr The MSHR to resend.
     * @param cmd The command to resend.
     */
    void markPending(MSHR* mshr, Packet::Command cmd);

    /**
     * Squash outstanding pktuests with the given thread number. If a request
     * is in service, just squashes the targets.
     * @param threadNum The thread to squash.
     */
    void squash(int threadNum);

    /**
     * Returns true if the pending list is not empty.
     * @return True if there are outstanding pktuests.
     */
    bool havePending() const
    {
        return !pendingList.empty();
    }

    /**
     * Returns true if there are no free MSHRs.
     * @return True if this queue is full.
     */
    bool isFull() const
    {
        return (allocated > numMSHRs - numReserve);
    }

    /**
     * Returns the pktuest at the head of the pendingList.
     * @return The next pktuest to service.
     */
    Packet * getReq() const
    {
        if (pendingList.empty()) {
            return NULL;
        }
        MSHR* mshr = pendingList.front();
        return mshr->pkt;
    }

    /**
     * Returns the number of outstanding targets.
     * @return the number of allocated targets.
     */
    int getAllocatedTargets() const
    {
        return allocatedTargets;
    }

};

#endif //__MSHR_QUEUE_HH__