public void ScheduleEDF()
{
// Timeline 만들고 Job release 목록 생성
List<JobEvent> listReleaseEvent = GetAllJobRelease();
Queue<double> queueTimeline = BuildTimeline();
List<KeyValuePair<int, int>> listSoftDeadlineMissedJobs = new List<KeyValuePair<int, int>>();
List<KeyValuePair<int, int>> listHardDeadlineMissedJobs = new List<KeyValuePair<int, int>>();
// 시간 진행
while(queueTimeline.Count != 0)
{
double presentTime = queueTimeline.Dequeue();
// 주어진 time interval 안에서
if (presentTime > _endTime)
break;
// 해당 시각에 큐에 있는 이벤트들 목록
List<JobEvent> nextEvents = GetSameTimeEvents(listReleaseEvent, presentTime);
if (nextEvents.Count == 0)
continue;
else if (nextEvents.Count >= 2)
{
// Swap point
Console.WriteLine("Swap point: " + presentTime);
}
// 큐에 있는 것들 중 hardDeadline 이 가장 먼저인 것
//nextEvents.Sort(compareHardDeadline);
nextEvents.Sort(compareSoftDeadline);
//if (presentTime == 0 || presentTime == 6)
// nextEvents.Reverse();
Queue<JobEvent> queueJob = new Queue<JobEvent>();
foreach (JobEvent job in nextEvents)
queueJob.Enqueue(job);
double nextTime = _endTime;
if (queueTimeline.Count != 0)
nextTime = queueTimeline.First();
while(queueJob.Count != 0)
{
// Dequeue the job
JobEvent job = queueJob.Dequeue();
job.AbsStartTime = presentTime;
job.AbsCompleteTime = presentTime + job.RemainExecution;
// Soft deadline miss 검사
if (job.AbsSoftDeadline < job.AbsCompleteTime)
{
KeyValuePair<int, int> pair = new KeyValuePair<int, int>(job.ParentTask.TaskNumber, job.JobNumber);
if (listSoftDeadlineMissedJobs.Contains(pair) == false)
listSoftDeadlineMissedJobs.Add(pair);
job.ParentTask.MissCount++;
}
// Hard deadline 을 넘어갔다면, 해당 Job의 실행을 포기
if (job.AbsHardDeadline < job.AbsCompleteTime)
{
KeyValuePair<int, int> pair = new KeyValuePair<int, int>(job.ParentTask.TaskNumber, job.JobNumber);
if (listHardDeadlineMissedJobs.Contains(pair) == false)
listHardDeadlineMissedJobs.Add(pair);
continue;
}
// 다음 Job의 릴리즈에도 완료하지 못하였다면
if (nextTime < job.AbsCompleteTime)
{
job.AbsCompleteTime = nextTime;
// 남은 수행시간을 가진 새로운 이벤트를 생성
// 이 이벤트를 어떻게 할 것인지는 다음 time 에게 맡긴다.
JobEvent newEvent = new JobEvent(job.ParentTask);
newEvent.JobNumber = job.JobNumber;
newEvent.AbsStartTime = nextTime;
newEvent.AbsReleaseTime = job.AbsReleaseTime;
newEvent.AbsSoftDeadline = job.AbsSoftDeadline;
newEvent.AbsHardDeadline = job.AbsHardDeadline;
newEvent.RemainExecution = job.RemainExecution - (nextTime - presentTime);
newEvent.AbsCompleteTime = nextTime + newEvent.RemainExecution;
if (newEvent.AbsStartTime < _endTime)
{
listReleaseEvent.Add(newEvent);
if (false == queueTimeline.Contains(nextTime))
{
queueTimeline.Enqueue(nextTime);
List<double> temp = queueTimeline.ToList();
temp.Sort();
queueTimeline.Clear();
foreach (double d in temp)
queueTimeline.Enqueue(d);
}
}
}
_listListEventOutput[job.ParentTask.TaskNumber].Add(job);
presentTime = job.AbsCompleteTime;
}
}
// Soft deadline miss 한 Job 처리
foreach (KeyValuePair<int, int> pair in listSoftDeadlineMissedJobs)
{
foreach (JobEvent e in _listListEventOutput[pair.Key])
{
if (e.JobNumber == pair.Value)
e.IsSoftDeadlineMissed = true;
}
}
// Hard deadline miss 한 Job 처리
foreach (KeyValuePair<int, int> pair in listHardDeadlineMissedJobs)
{
foreach (JobEvent e in _listListEventOutput[pair.Key])
{
if (e.JobNumber == pair.Value)
e.IsHardDeadlineMissed = true;
}
}
}