summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/examples/FaultTolerance/FLARe/DeCoRAM/src/FTRMFF_Bestfit.cpp
blob: 9fc4c83ba2e44a8e6cdd2a2a8a6386ed514827b8 (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
// -*- C++ -*-

//=============================================================================
/**
 *  @file    FTRMFF_Bestfit.cpp
 *
 *  $Id$
 *
 *  @author  Friedhelm Wolf (fwolf@dre.vanderbilt.edu)
 */
//=============================================================================

#include <sstream>
#include "FTRMFF_Bestfit.h"

#include "Forward_Ranking_Scheduler.h"
#include "Packing_Scheduler.h"

FTRMFF_Bestfit::~FTRMFF_Bestfit ()
{
}

FTRMFF_Output
FTRMFF_Bestfit::operator () (const FTRMFF_Input & input)
{
  FTRMFF_Bestfit_Algorithm algorithm (input.processors,
                                      input.backup_count);

  FTRMFF_Output output;
  output.schedule = algorithm (input.tasks);
  output.unscheduled_tasks = algorithm.get_unschedulable ();

  DBG_OUT (algorithm.schedule ());

  return output;
}

FTRMFF_Bestfit_Algorithm::FTRMFF_Bestfit_Algorithm (
  const PROCESSOR_LIST & processors,
  unsigned int consistency_level)
  : consistency_level_ (consistency_level),
    scheduler_ (processors,
                consistency_level_)
{
  // fill last_results data structure
  ScheduleResult result = { {"NoTask", .0, .0, .0, PRIMARY, 0}, 
                            "NO PROCESSOR", 
                            .0};

  for (PROCESSOR_LIST::const_iterator it = processors.begin ();
       it != processors.end ();
       ++it)
    {
      result.processor = *it;
      last_results_[*it] = result;
    }
}

FTRMFF_Bestfit_Algorithm::~FTRMFF_Bestfit_Algorithm ()
{
}

SCHEDULING_MAP
FTRMFF_Bestfit_Algorithm::operator () (const TASK_LIST & tasks)
{  
  // sort tasks based on their periods, which results in a priority
  // ordered list since we do rate monotonic scheduling
  TASK_LIST sorted_input = tasks;

  std::sort (sorted_input.begin (), 
	     sorted_input.end (), 
	     PeriodComparison <Task> ());

  for (TASK_LIST::iterator it = sorted_input.begin ();
       it != sorted_input.end ();
       ++it)
    {
      // create the right amount of backup replica tasks
      TASK_LIST task_group = create_ranked_tasks (*it,
                                                  consistency_level_);

      // schedule the tasks of one application
      for (TASK_LIST::iterator task_it = task_group.begin ();
           task_it != task_group.end ();
           ++task_it)
        {
          std::cout << *task_it << std::endl;

          PROCESSOR_LIST processors = this->best_processors ();

          ScheduleResult schedule_result;
          for (PROCESSOR_LIST::iterator p_it = processors.begin ();
               p_it != processors.end ();
               ++p_it)
            {
              TRACE (*task_it << " on " << *p_it);

              schedule_result = scheduler_ (*task_it, *p_it);
              if (schedule_result.wcrt > .0)
                {
                  break;
                }
            }

          if (schedule_result.wcrt <= .0)
            {
              ScheduleProgress pg = {*task_it, 
                                     task_it->rank - consistency_level_ + 1};
              unschedulable_.push_back (pg);
              break;
            }
          else
            {
              scheduler_.update_schedule (schedule_result);
              last_results_[schedule_result.processor] = schedule_result;
            }
          
          
          TRACE (*task_it << " -> " << schedule_result.processor);
        }
    }

  return transform_schedule (scheduler_.schedule ());
}

SCHEDULE_PROGRESS_LIST
FTRMFF_Bestfit_Algorithm::get_unschedulable ()
{
  return unschedulable_;
}

const SCHEDULE &
FTRMFF_Bestfit_Algorithm::schedule () const
{
  return scheduler_.schedule ();
}

struct ScheduleResultComparison : public std::binary_function <
  RESULT_MAP::value_type, 
  RESULT_MAP::value_type,
  bool>
{
  bool operator () (const RESULT_MAP::value_type & r1, 
                    const RESULT_MAP::value_type & r2)
  {
    return (r1.second.wcrt < r2.second.wcrt);
  }
};

struct ProcessorAccumulator : public std::unary_function <
  RESULT_MAP::value_type,
  Processor>
{
public:
  Processor operator () (const RESULT_MAP::value_type & entry)
  {
    return entry.second.processor;
  }
};

typedef std::pair <Processor, ScheduleResult> RESULT_PAIR;

PROCESSOR_LIST 
FTRMFF_Bestfit_Algorithm::best_processors (void)
{
  TRACE ("last_results: " << last_results_.size ());

  std::vector <RESULT_PAIR> entries;
  std::copy (last_results_.begin (),
             last_results_.end (),
             std::inserter (entries,
                            entries.begin ()));

  std::sort (entries.begin (),
             entries.end (),
             ScheduleResultComparison ());

  TRACE ("entries : " << entries.size ());

  PROCESSOR_LIST result;
  std::transform (entries.begin (),
                  entries.end (),
                  std::inserter (result,
                                 result.begin ()),
                  ProcessorAccumulator ());

  return result;
}