O3: Track if the RAS has been pushed or not to pop the RAS if neccessary.
[gem5.git] / src / cpu / inorder / resource_sked.cc
1 /*
2 * Copyright (c) 2010 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Korey Sewell
29 *
30 */
31
32 #include <cstdio>
33 #include <list>
34 #include <vector>
35
36 #include "cpu/inorder/pipeline_traits.hh"
37 #include "cpu/inorder/resource_sked.hh"
38 #include "debug/SkedCache.hh"
39
40 using namespace std;
41 using namespace ThePipeline;
42
43 ResourceSked::ResourceSked()
44 {
45 stages.resize(NumStages);
46 }
47
48 void
49 ResourceSked::init()
50 {
51 assert(!stages[0].empty());
52
53 curSkedEntry = stages[0].begin();
54 }
55
56 int
57 ResourceSked::size()
58 {
59 int total = 0;
60 for (int i = 0; i < stages.size(); i++) {
61 total += stages[i].size();
62 }
63
64 return total;
65 }
66
67 bool
68 ResourceSked::empty()
69 {
70 return size() == 0;
71 }
72
73
74 ResourceSked::SkedIt
75 ResourceSked::begin()
76 {
77 int num_stages = stages.size();
78 for (int i = 0; i < num_stages; i++) {
79 if (stages[i].size() > 0)
80 return stages[i].begin();
81 }
82
83 return stages[num_stages - 1].end();
84 }
85
86 ResourceSked::SkedIt
87 ResourceSked::end()
88 {
89 int num_stages = stages.size();
90 return stages[num_stages - 1].end();
91 }
92
93 ResourceSked::SkedIt
94 ResourceSked::end(int stage_num)
95 {
96 return stages[stage_num].end();
97 }
98
99 ResourceSked::SkedIt
100 ResourceSked::find(int stage_num, int cmd)
101 {
102 SkedIt stage_it = stages[stage_num].begin();
103 SkedIt stage_end = stages[stage_num].end();
104
105 while (stage_it != stage_end) {
106 if ((*stage_it)->cmd == cmd)
107 return stage_it;
108 stage_it++;
109 }
110
111 return stages[stage_num].end();
112 }
113
114 ScheduleEntry*
115 ResourceSked::top()
116 {
117 assert(size() > 0);
118
119 return *curSkedEntry;
120 }
121
122 void
123 ResourceSked::pop()
124 {
125 int stage_num = (*curSkedEntry)->stageNum;
126
127 stages[stage_num].erase(curSkedEntry);
128
129 if (!stages[stage_num].empty()) {
130 curSkedEntry = stages[stage_num].begin();
131 } else {
132 int next_stage = stage_num + 1;
133
134 while (next_stage < NumStages) {
135 if (stages[next_stage].empty()) {
136 next_stage++;
137 } else {
138 curSkedEntry = stages[next_stage].begin();
139 break;
140 }
141 }
142 }
143 }
144
145 void
146 ResourceSked::push(ScheduleEntry* sked_entry)
147 {
148 int stage_num = sked_entry->stageNum;
149 assert(stage_num < NumStages);
150
151 SkedIt pri_iter = findIterByPriority(sked_entry, stage_num);
152
153 stages[stage_num].insert(pri_iter, sked_entry);
154 }
155
156 void
157 ResourceSked::pushBefore(ScheduleEntry* sked_entry, int sked_cmd,
158 int sked_cmd_idx)
159 {
160
161 int stage_num = sked_entry->stageNum;
162 assert(stage_num < NumStages);
163
164 SkedIt pri_iter = findIterByCommand(sked_entry, stage_num,
165 sked_cmd, sked_cmd_idx);
166
167 assert(pri_iter != stages[stage_num].end() &&
168 "Could not find command to insert in front of.");
169
170 stages[stage_num].insert(pri_iter, sked_entry);
171 }
172
173 ResourceSked::SkedIt
174 ResourceSked::findIterByPriority(ScheduleEntry* sked_entry, int stage_num)
175 {
176 if (stages[stage_num].empty()) {
177 return stages[stage_num].end();
178 }
179
180 int priority = sked_entry->priority;
181
182 SkedIt sked_it = stages[stage_num].begin();
183 SkedIt sked_end = stages[stage_num].end();
184
185 while (sked_it != sked_end) {
186 if ((*sked_it)->priority > priority)
187 break;
188
189 sked_it++;
190 }
191
192 return sked_it;
193 }
194
195 ResourceSked::SkedIt
196 ResourceSked::findIterByCommand(ScheduleEntry* sked_entry, int stage_num,
197 int sked_cmd, int sked_cmd_idx)
198 {
199 if (stages[stage_num].empty()) {
200 return stages[stage_num].end();
201 }
202
203 SkedIt sked_it = stages[stage_num].begin();
204 SkedIt sked_end = stages[stage_num].end();
205
206 while (sked_it != sked_end) {
207 if ((*sked_it)->cmd == sked_cmd &&
208 (sked_cmd_idx != -1) ? (*sked_it)->idx == sked_cmd_idx : true)
209 break;
210
211 sked_it++;
212 }
213
214 return sked_it;
215 }
216
217 void
218 ResourceSked::print()
219 {
220 for (int i = 0; i < stages.size(); i++) {
221 //ccprintf(cerr, "Stage %i\n====\n", i);
222 SkedIt sked_it = stages[i].begin();
223 SkedIt sked_end = stages[i].end();
224 while (sked_it != sked_end) {
225 DPRINTF(SkedCache, "\t stage:%i res:%i cmd:%i idx:%i\n",
226 (*sked_it)->stageNum,
227 (*sked_it)->resNum,
228 (*sked_it)->cmd,
229 (*sked_it)->idx);
230 sked_it++;
231 }
232 }
233 }