replace priority queue with vector of lists(1 list per stage) and place inside a class
so that we have more control of when an instruction uses a particular schedule entry
...
also, this is the 1st step toward making the InOrderCPU fully parameterizable. See the
wiki for details on this process
        Source('resources/fetch_seq_unit.cc')
        Source('resources/mult_div_unit.cc')
        Source('resource_pool.cc')
+       Source('resource_sked.cc')      
        Source('reg_dep_map.cc')
        Source('thread_state.cc')
        Source('thread_context.cc')
 
         // Make Sure Resource Schedule Is Emptied Out
         ThePipeline::ResSchedule *inst_sched = &inst->resSched;
         while (!inst_sched->empty()) {
-            ThePipeline::ScheduleEntry* sch_entry = inst_sched->top();
+            ScheduleEntry* sch_entry = inst_sched->top();
             inst_sched->pop();
             delete sch_entry;
         }
 
 #include "cpu/inorder/inorder_trace.hh"
 #include "cpu/inorder/pipeline_traits.hh"
 #include "cpu/inorder/resource.hh"
+#include "cpu/inorder/resource_sked.hh"
 #include "cpu/inorder/thread_state.hh"
 #include "cpu/inst_seq.hh"
 #include "cpu/op_class.hh"
     void deleteStages();
 
     /** Add A Entry To Reource Schedule */
-    void addToSched(ThePipeline::ScheduleEntry* sched_entry)
+    void addToSched(ScheduleEntry* sched_entry)
     { resSched.push(sched_entry); }
 
 
     void popSchedEntry()
     {
         if (!resSched.empty()) {
-            ThePipeline::ScheduleEntry* sked = resSched.top();
+            ScheduleEntry* sked = resSched.top();
             resSched.pop();
             if (sked != 0) {
                 delete sked;
 
     D->needs(Decode, DecodeUnit::DecodeInst);
     D->needs(BPred, BranchPredictor::PredictBranch);
     D->needs(FetchSeq, FetchSeqUnit::UpdateTargetPC);
+
+    inst->resSched.init();
 }
 
 bool createBackEndSchedule(DynInstPtr &inst)
     instSched = &inst->resSched;
 }
 
+void
+InstStage::needs(int unit, int request) {
+    instSched->push( new ScheduleEntry(
+                         stageNum, nextTaskPriority++, unit, request
+                         ));
+}
+
+void
+InstStage::needs(int unit, int request, int param) {
+    instSched->push( new ScheduleEntry(
+                         stageNum, nextTaskPriority++, unit, request, param
+                         ));
+}
+
 };
 
 #include "params/InOrderCPU.hh"
 
 class InOrderDynInst;
+class ScheduleEntry;
+class ResourceSked;
 
 /* This Namespace contains constants, typedefs, functions and
  * objects specific to the Pipeline Implementation.
     //////////////////////////
     // RESOURCE SCHEDULING
     //////////////////////////
-    struct ScheduleEntry {
-        ScheduleEntry(int stage_num, int _priority, int res_num, int _cmd = 0,
-                      int _idx = 0) :
-            stageNum(stage_num), resNum(res_num), cmd(_cmd),
-            idx(_idx), priority(_priority)
-        { }
-
-        // Stage number to perform this service.
-        int stageNum;
-
-        // Resource ID to access
-        int resNum;
-
-        // See specific resource for meaning
-        unsigned cmd;
-
-        // See specific resource for meaning
-        unsigned idx;
-
-        // Some Resources May Need Priority?
-        int priority;
-    };
-
-    struct entryCompare {
-        bool operator()(const ScheduleEntry* lhs, const ScheduleEntry* rhs) 
-            const
-        {
-            // Prioritize first by stage number that the resource is needed
-            if (lhs->stageNum > rhs->stageNum) {
-                return true;
-            } else if (lhs->stageNum == rhs->stageNum) {
-                if (lhs->priority > rhs->priority) {
-                  return true;
-                } else {
-                  return false;
-                }
-            } else {
-                return false;
-            }
-        }
-    };
-
-
-    typedef std::priority_queue<ScheduleEntry*, std::vector<ScheduleEntry*>,
-                                         entryCompare> ResSchedule;
+    typedef ResourceSked ResSchedule;
 
     void createFrontEndSchedule(DynInstPtr &inst);
     bool createBackEndSchedule(DynInstPtr &inst);
       public:
         InstStage(DynInstPtr inst, int stage_num);
 
-        void needs(int unit, int request) {
-            instSched->push( new ScheduleEntry(
-                stageNum, nextTaskPriority++, unit, request
-            ));
-        }
-
-        void needs(int unit, int request, int param) {
-            instSched->push( new ScheduleEntry(
-                stageNum, nextTaskPriority++, unit, request, param
-            ));
-        }
+        void needs(int unit, int request);
+        void needs(int unit, int request, int param);
     };
 };
 
 
--- /dev/null
+/*
+ * 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 "cpu/inorder/resource_sked.hh"
+#include "cpu/inorder/pipeline_traits.hh"
+
+#include <vector>
+#include <list>
+#include <stdio.h>
+
+using namespace std;
+using namespace ThePipeline;
+
+ResourceSked::ResourceSked()
+{
+    sked.resize(NumStages);
+}
+
+void
+ResourceSked::init()
+{
+    assert(!sked[0].empty());
+
+    curSkedEntry = sked[0].begin();
+}
+
+int
+ResourceSked::size()
+{
+    int total = 0;
+    for (int i = 0; i < sked.size(); i++) {
+        total += sked[i].size();
+    }
+
+    return total;
+}
+
+bool
+ResourceSked::empty()
+{
+    return size() == 0;
+}
+
+ScheduleEntry*
+ResourceSked::top()
+{
+    assert(size() > 0);
+
+    return *curSkedEntry;
+}
+
+void
+ResourceSked::pop()
+{
+    int stage_num = (*curSkedEntry)->stageNum;
+
+    sked[stage_num].erase(curSkedEntry);
+
+    if (!sked[stage_num].empty()) {
+        curSkedEntry = sked[stage_num].begin();
+    } else {
+        int next_stage = stage_num + 1;
+
+        while (next_stage < NumStages) {
+            if (sked[next_stage].empty()) {
+                next_stage++;
+            } else {
+                curSkedEntry = sked[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);
+
+    sked[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 != sked[stage_num].end() &&
+           "Could not find command to insert in front of.");
+
+    sked[stage_num].insert(pri_iter, sked_entry);
+}
+
+ResourceSked::SkedIt
+ResourceSked::findIterByPriority(ScheduleEntry* sked_entry, int stage_num)
+{
+    if (sked[stage_num].empty()) {
+        return sked[stage_num].end();
+    }
+
+    int priority = sked_entry->priority;
+
+    SkedIt sked_it = sked[stage_num].begin();
+    SkedIt sked_end = sked[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 (sked[stage_num].empty()) {
+        return sked[stage_num].end();
+    }
+
+    SkedIt sked_it = sked[stage_num].begin();
+    SkedIt sked_end = sked[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 < sked.size(); i++) {
+        cprintf("Stage %i\n====\n", i);
+        SkedIt sked_it = sked[i].begin();
+        SkedIt sked_end = sked[i].end();
+        while (sked_it != sked_end) {
+            cprintf("\t res:%i cmd:%i idx:%i\n", (*sked_it)->resNum, (*sked_it)->cmd, (*sked_it)->idx);
+            sked_it++;
+        }
+    }
+}
 
--- /dev/null
+/*
+ * 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
+ *
+ */
+
+#ifndef __CPU_INORDER_RESOURCE_SKED_HH__
+#define __CPU_INORDER_RESOURCE_SKED_HH__
+
+#include <vector>
+#include <list>
+
+class ScheduleEntry {
+  public:
+    ScheduleEntry(int stage_num, int _priority, int res_num, int _cmd = 0,
+                  int _idx = 0) :
+        stageNum(stage_num), resNum(res_num), cmd(_cmd),
+        idx(_idx), priority(_priority)
+    { }
+
+    // Stage number to perform this service.
+    int stageNum;
+
+    // Resource ID to access
+    int resNum;
+
+    // See specific resource for meaning
+    unsigned cmd;
+
+    // See specific resource for meaning
+    unsigned idx;
+
+    // Some Resources May Need Priority
+    int priority;
+};
+
+class ResourceSked {
+  public:
+    typedef std::list<ScheduleEntry*>::iterator SkedIt;
+
+    ResourceSked();
+
+    void init();
+
+    int size();
+    bool empty();
+    ScheduleEntry* top();
+    void pop();
+    void push(ScheduleEntry* sked_entry);
+    void pushBefore(ScheduleEntry* sked_entry, int sked_cmd, int sked_cmd_idx);
+    void print();
+
+  private:
+    SkedIt curSkedEntry;
+    std::vector<std::list<ScheduleEntry*> > sked;
+
+    SkedIt findIterByPriority(ScheduleEntry *sked_entry, int stage_num);
+    SkedIt findIterByCommand(ScheduleEntry *sked_entry, int stage_num,
+                             int sked_cmd, int sked_cmd_idx = -1);
+};
+
+#endif //__CPU_INORDER_RESOURCE_SKED_HH__