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;
                }
            }
        }
 private int compareStartTime(JobEvent e1, JobEvent e2)
 {
     return e1.AbsStartTime.CompareTo(e2.AbsStartTime);
 }
 private int compareHardDeadline(JobEvent x, JobEvent y)
 {
     return x.AbsHardDeadline.CompareTo(y.AbsHardDeadline);
 }
 private int compareSoftDeadline(JobEvent x, JobEvent y)
 {
     return x.AbsSoftDeadline.CompareTo(y.AbsSoftDeadline);
 }
        public List<JobEvent> GetEventList(double startTime, double endTime)
        {
            List<JobEvent> listEvent = new List<JobEvent>();

            double max = endTime / Period;
            for (int i = 0; i < max; i++)
            {
                double value = i * Period;
                if (value < startTime)
                    continue;

                JobEvent e = new JobEvent(this);
                e.AbsReleaseTime = value;
                e.AbsStartTime = value;
                e.AbsSoftDeadline = value + SoftDeadline;
                e.AbsHardDeadline = value + HardDeadline;
                e.AbsCompleteTime = value + ExecutionTime;
                e.RemainExecution = ExecutionTime;
                e.JobNumber = i;

                listEvent.Add(e);
            }

            return listEvent;
        }