blob: e52ed8ff0294fdad989eabb5fed18662a3544c68 [file] [log] [blame]
/*
* Copyright (c) 2010 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: Korey Sewell
*
*/
#include <cstdio>
#include <list>
#include <vector>
#include "cpu/inorder/pipeline_traits.hh"
#include "cpu/inorder/resource_sked.hh"
#include "debug/SkedCache.hh"
using namespace std;
using namespace ThePipeline;
ResourceSked::ResourceSked()
{
stages.resize(NumStages);
}
void
ResourceSked::init()
{
assert(!stages[0].empty());
curSkedEntry = stages[0].begin();
}
int
ResourceSked::size()
{
int total = 0;
for (int i = 0; i < stages.size(); i++) {
total += stages[i].size();
}
return total;
}
bool
ResourceSked::empty()
{
return size() == 0;
}
ResourceSked::SkedIt
ResourceSked::begin()
{
int num_stages = stages.size();
for (int i = 0; i < num_stages; i++) {
if (stages[i].size() > 0)
return stages[i].begin();
}
return stages[num_stages - 1].end();
}
ResourceSked::SkedIt
ResourceSked::end()
{
int num_stages = stages.size();
return stages[num_stages - 1].end();
}
ResourceSked::SkedIt
ResourceSked::end(int stage_num)
{
return stages[stage_num].end();
}
ResourceSked::SkedIt
ResourceSked::find(int stage_num, int cmd)
{
SkedIt stage_it = stages[stage_num].begin();
SkedIt stage_end = stages[stage_num].end();
while (stage_it != stage_end) {
if ((*stage_it)->cmd == cmd)
return stage_it;
stage_it++;
}
return stages[stage_num].end();
}
ScheduleEntry*
ResourceSked::top()
{
assert(size() > 0);
return *curSkedEntry;
}
void
ResourceSked::pop()
{
int stage_num = (*curSkedEntry)->stageNum;
stages[stage_num].erase(curSkedEntry);
if (!stages[stage_num].empty()) {
curSkedEntry = stages[stage_num].begin();
} else {
int next_stage = stage_num + 1;
while (next_stage < NumStages) {
if (stages[next_stage].empty()) {
next_stage++;
} else {
curSkedEntry = stages[next_stage].begin();
break;
}
}
}
}
void
ResourceSked::push(ScheduleEntry* sked_entry)
{
int stage_num = sked_entry->stageNum;
assert(stage_num < NumStages);
SkedIt pri_iter = findIterByPriority(sked_entry, stage_num);
stages[stage_num].insert(pri_iter, sked_entry);
}
void
ResourceSked::pushBefore(ScheduleEntry* sked_entry, int sked_cmd,
int sked_cmd_idx)
{
int stage_num = sked_entry->stageNum;
assert(stage_num < NumStages);
SkedIt pri_iter = findIterByCommand(sked_entry, stage_num,
sked_cmd, sked_cmd_idx);
assert(pri_iter != stages[stage_num].end() &&
"Could not find command to insert in front of.");
stages[stage_num].insert(pri_iter, sked_entry);
}
ResourceSked::SkedIt
ResourceSked::findIterByPriority(ScheduleEntry* sked_entry, int stage_num)
{
if (stages[stage_num].empty()) {
return stages[stage_num].end();
}
int priority = sked_entry->priority;
SkedIt sked_it = stages[stage_num].begin();
SkedIt sked_end = stages[stage_num].end();
while (sked_it != sked_end) {
if ((*sked_it)->priority > priority)
break;
sked_it++;
}
return sked_it;
}
ResourceSked::SkedIt
ResourceSked::findIterByCommand(ScheduleEntry* sked_entry, int stage_num,
int sked_cmd, int sked_cmd_idx)
{
if (stages[stage_num].empty()) {
return stages[stage_num].end();
}
SkedIt sked_it = stages[stage_num].begin();
SkedIt sked_end = stages[stage_num].end();
while (sked_it != sked_end) {
if ((*sked_it)->cmd == sked_cmd &&
(sked_cmd_idx != -1) ? (*sked_it)->idx == sked_cmd_idx : true)
break;
sked_it++;
}
return sked_it;
}
void
ResourceSked::print()
{
for (int i = 0; i < stages.size(); i++) {
//ccprintf(cerr, "Stage %i\n====\n", i);
SkedIt sked_it = stages[i].begin();
SkedIt sked_end = stages[i].end();
while (sked_it != sked_end) {
DPRINTF(SkedCache, "\t stage:%i res:%i cmd:%i idx:%i\n",
(*sked_it)->stageNum,
(*sked_it)->resNum,
(*sked_it)->cmd,
(*sked_it)->idx);
sked_it++;
}
}
}