Commit b00f2d0e by Michael Schmid

Simulator now works

parent 36080fd3
...@@ -7,6 +7,8 @@ import mvd.jester.model.SystemManager; ...@@ -7,6 +7,8 @@ import mvd.jester.model.SystemManager;
import mvd.jester.model.SystemManager.DagTaskBuilder; import mvd.jester.model.SystemManager.DagTaskBuilder;
import mvd.jester.priority.RateMonotonic; import mvd.jester.priority.RateMonotonic;
import mvd.jester.simulator.GlobalScheduler; import mvd.jester.simulator.GlobalScheduler;
import mvd.jester.simulator.model.ExtendedSubtaskContext;
import mvd.jester.simulator.model.JobContext;
import mvd.jester.tests.AbstractTest; import mvd.jester.tests.AbstractTest;
import mvd.jester.tests.FonsecaNelis; import mvd.jester.tests.FonsecaNelis;
import mvd.jester.tests.MelaniButtazzo; import mvd.jester.tests.MelaniButtazzo;
...@@ -25,7 +27,8 @@ public class App { ...@@ -25,7 +27,8 @@ public class App {
GlobalScheduler scheduler = new GlobalScheduler(new RateMonotonic(), 4); GlobalScheduler scheduler = new GlobalScheduler(new RateMonotonic(), 4);
DagTaskBuilder builder = new DagTaskBuilder().setNumberOfProcessors(4); DagTaskBuilder builder = new DagTaskBuilder().setNumberOfProcessors(4);
scheduler.schedule(builder.generateTaskSet(3), 10000); scheduler.schedule(builder.generateTaskSet(1.0), 10000);
// { // {
// SystemManager manager = new SystemManager(8); // SystemManager manager = new SystemManager(8);
// DagTaskBuilder builder = new DagTaskBuilder(); // DagTaskBuilder builder = new DagTaskBuilder();
......
...@@ -98,4 +98,9 @@ public class DagTask implements Task { ...@@ -98,4 +98,9 @@ public class DagTask implements Task {
return numberOfThreads; return numberOfThreads;
} }
@Override
public String toString() {
return "(P=" + period + ", D=" + deadline + ")";
}
} }
...@@ -27,4 +27,10 @@ public class Subtask { ...@@ -27,4 +27,10 @@ public class Subtask {
public void setRelativeCompletionTime(long relativeCompletionTime) { public void setRelativeCompletionTime(long relativeCompletionTime) {
this.relativeCompletionTime = relativeCompletionTime; this.relativeCompletionTime = relativeCompletionTime;
} }
@Override
public String toString() {
return "(C=" + wcet + ")";
}
} }
...@@ -160,10 +160,10 @@ public class SystemManager { ...@@ -160,10 +160,10 @@ public class SystemManager {
private long numberOfProcessors = 8; private long numberOfProcessors = 8;
private long minimumWcet = 1; private long minimumWcet = 1;
private long maximumWcet = 100; private long maximumWcet = 100;
private long maxNumberOfBranches = 5; private long maxNumberOfBranches = 3; // TODO: Change back to 5
private long depth = 2; private long depth = 1; // TODO: Change back to 2
private long p_par = 80; private long p_par = 80;
private long p_add = 20; private long p_add = 10; // TODO: Change back to 20
public DagTaskBuilder() { public DagTaskBuilder() {
} }
...@@ -252,8 +252,8 @@ public class SystemManager { ...@@ -252,8 +252,8 @@ public class SystemManager {
return new DagTask(jobDag, period, numberOfProcessors); return new DagTask(jobDag, period, numberOfProcessors);
} }
private Subtask join(final DirectedAcyclicGraph<Subtask, DefaultEdge> jobDag, final Subtask current, private Subtask join(final DirectedAcyclicGraph<Subtask, DefaultEdge> jobDag,
final Set<Subtask> childs) { final Subtask current, final Set<Subtask> childs) {
if (childs.size() > 0) { if (childs.size() > 0) {
final Subtask job = new Subtask(randomWcet()); final Subtask job = new Subtask(randomWcet());
jobDag.addVertex(job); jobDag.addVertex(job);
......
...@@ -4,37 +4,43 @@ import java.util.HashSet; ...@@ -4,37 +4,43 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import org.jgrapht.Graphs; import org.jgrapht.Graphs;
import mvd.jester.model.DagTask; import mvd.jester.model.DagTask;
import mvd.jester.model.Subtask; import mvd.jester.model.Subtask;
import mvd.jester.priority.PriorityManager; import mvd.jester.priority.PriorityManager;
import mvd.jester.simulator.events.*; import mvd.jester.simulator.events.*;
import mvd.jester.simulator.exceptions.DeadlineMissedException;
import mvd.jester.simulator.exceptions.SchedulingException; import mvd.jester.simulator.exceptions.SchedulingException;
import mvd.jester.simulator.model.ExtendedSubtaskContext; import mvd.jester.simulator.model.ExtendedSubtaskContext;
import mvd.jester.simulator.model.JobContext; import mvd.jester.simulator.model.JobContext;
import mvd.jester.simulator.model.ProcessorContext; import mvd.jester.simulator.model.ProcessorContext;
import mvd.jester.simulator.model.ProcessorContext.ProcessorComparator;
public class GlobalScheduler { public class GlobalScheduler {
private final int nbProcessors; private final int nbProcessors;
private final PriorityManager priorityManager; private final PriorityManager priorityManager;
public GlobalScheduler(PriorityManager priorityManager, int nbProcessors) { public GlobalScheduler(final PriorityManager priorityManager, final int nbProcessors) {
this.priorityManager = priorityManager; this.priorityManager = priorityManager;
this.nbProcessors = nbProcessors; this.nbProcessors = nbProcessors;
} }
public void schedule(Set<DagTask> taskSet, long duration) { public void schedule(final Set<DagTask> taskSet, final long duration) {
SchedulingContext sc = new SchedulingContext(priorityManager, nbProcessors, duration); final SchedulingContext sc = new SchedulingContext(priorityManager, nbProcessors, duration);
taskSet.forEach(t -> sc.events.offer(new TaskReleasedEvent(0, t))); taskSet.forEach(t -> sc.events.offer(new TaskReleasedEvent(0, t)));
while (!sc.events.isEmpty()) { while (!sc.events.isEmpty()) {
IEvent event = sc.events.poll(); final IEvent event = sc.events.poll();
updateExecution(sc, event.getTime()); updateExecution(sc, event.getTime());
handle(event, sc); handle(event, sc);
} }
} }
private void handle(IEvent event, SchedulingContext sc) { private void handle(final IEvent event, final SchedulingContext sc) {
event.log(); event.log();
switch (event.getType()) { switch (event.getType()) {
case SUBTASK_ACTIVATED: case SUBTASK_ACTIVATED:
...@@ -58,6 +64,9 @@ public class GlobalScheduler { ...@@ -58,6 +64,9 @@ public class GlobalScheduler {
case JOB_ACTIVATED: case JOB_ACTIVATED:
handleJobActivated((JobActivatedEvent) event, sc); handleJobActivated((JobActivatedEvent) event, sc);
break; break;
case JOB_COMPLETED:
handleJobCompleted((JobCompletedEvent) event, sc);
break;
case TASK_RELEASED: case TASK_RELEASED:
handleTaskReleased((TaskReleasedEvent) event, sc); handleTaskReleased((TaskReleasedEvent) event, sc);
break; break;
...@@ -67,62 +76,78 @@ public class GlobalScheduler { ...@@ -67,62 +76,78 @@ public class GlobalScheduler {
} }
} }
private void handleSubtaskActivated(SubtaskActivatedEvent event, SchedulingContext sc) { private void handleJobCompleted(final JobCompletedEvent event, final SchedulingContext sc) {
Subtask subtask = event.getSubtask(); if (event.getTime() > event.getJobContext().getDeadline()) {
JobContext job = event.getJobContext(); throw new DeadlineMissedException(event.getJobContext() + " misses its deadline");
}
}
private void handleSubtaskActivated(final SubtaskActivatedEvent event,
final SchedulingContext sc) {
final Subtask subtask = event.getSubtask();
final JobContext job = event.getJobContext();
sc.waitingQueue.offer(new ExtendedSubtaskContext(job, subtask)); sc.waitingQueue.offer(new ExtendedSubtaskContext(job, subtask));
updateAdmission(sc, event.getTime()); updateAdmission(sc, event.getTime());
} }
private void handleSubtaskCheckCompleted(SubtaskCheckCompletedEvent event, private void handleSubtaskCheckCompleted(final SubtaskCheckCompletedEvent event,
SchedulingContext sc) { final SchedulingContext sc) {
ProcessorContext processor = event.getProcessor(); final ProcessorContext processor = event.getProcessor();
if (processor.isIdle() || !processor.getSubtask().get().equals(event.getSubtaskContext())) { if (processor.isIdle()) {
throw new SchedulingException( throw new SchedulingException(
processor + " should execute " + event.getSubtaskContext()); processor + " should execute " + event.getSubtaskContext());
} }
Optional<ExtendedSubtaskContext> context = processor.getSubtask(); final Optional<ExtendedSubtaskContext> context = processor.getSubtask();
if (context.isPresent() && context.get().getRemainingExecutionTime() == 0) { if (context.isPresent() && context.get().getRemainingExecutionTime() == 0) {
sc.events.offer(new SubtaskStoppedEvent(event.getTime(), context.get(), processor)); sc.events.offer(new SubtaskStoppedEvent(event.getTime(), context.get(), processor));
} }
} }
private void handleSubtaskCompleted(SubtaskCompletedEvent event, SchedulingContext sc) { private void handleSubtaskCompleted(final SubtaskCompletedEvent event,
ExtendedSubtaskContext subtask = event.getSubtaskContext(); final SchedulingContext sc) {
JobContext job = subtask.getJobContext(); final ExtendedSubtaskContext subtask = event.getSubtaskContext();
final JobContext job = subtask.getJobContext();
DagTask task = subtask.getJobContext().getTask(); job.registerFinishedSubtask(subtask);
List<Subtask> successor = Graphs.successorListOf(task.getJobDag(), subtask.getSubtask()); final DagTask task = subtask.getJobContext().getTask();
final List<Subtask> successor =
Graphs.successorListOf(task.getJobDag(), subtask.getSubtask());
if (successor.isEmpty()) { if (successor.isEmpty()) {
sc.events.offer(new JobCompletedEvent(event.getTime(), job)); sc.events.offer(new JobCompletedEvent(event.getTime(), job));
updateAdmission(sc, event.getTime()); updateAdmission(sc, event.getTime());
} else { } else {
for (Subtask s : successor) { final List<Subtask> finishedSubtasks = job.getFinishedSubtasks().stream()
.map(esc -> esc.getSubtask()).collect(Collectors.toList());
for (final Subtask s : successor) {
final List<Subtask> predecessors = Graphs.predecessorListOf(task.getJobDag(), s);
if (finishedSubtasks.containsAll(predecessors)) {
sc.events.offer(new SubtaskActivatedEvent(event.getTime(), job, s)); sc.events.offer(new SubtaskActivatedEvent(event.getTime(), job, s));
} }
} }
} }
}
private void handleSubtaskPreempted(SubtaskPreemptedEvent event, SchedulingContext sc) { private void handleSubtaskPreempted(final SubtaskPreemptedEvent event,
ProcessorContext processor = event.getProcessor(); final SchedulingContext sc) {
long time = event.getTime(); final ProcessorContext processor = event.getProcessor();
sc.events.offer(new SubtaskStoppedEvent(time, event.getNextSubtask(), processor)); final long time = event.getTime();
sc.events.offer(new SubtaskStartedEvent(time, event.getSubtaskContext(), processor)); sc.events.offer(new SubtaskStartedEvent(time, event.getNextSubtask(), processor));
sc.events.offer(new SubtaskStoppedEvent(time, event.getSubtaskContext(), processor));
} }
private void handleSubtaskStarted(SubtaskStartedEvent event, SchedulingContext sc) { private void handleSubtaskStarted(final SubtaskStartedEvent event, final SchedulingContext sc) {
long time = event.getTime(); final long time = event.getTime();
ProcessorContext processor = event.getProcessor(); final ProcessorContext processor = event.getProcessor();
ExtendedSubtaskContext context = event.getSubtaskContext(); final ExtendedSubtaskContext context = event.getSubtaskContext();
if (processor.accept(context, time)) { if (processor.accept(context, time)) {
sc.events.offer(new SubtaskCheckCompletedEvent( sc.events.offer(new SubtaskCheckCompletedEvent(
time + context.getRemainingExecutionTime(), context, processor)); time + context.getRemainingExecutionTime(), context, processor));
} }
} }
private void handleSubtaskStopped(SubtaskStoppedEvent event, SchedulingContext sc) { private void handleSubtaskStopped(final SubtaskStoppedEvent event, final SchedulingContext sc) {
ExtendedSubtaskContext context = event.getSubtaskContext(); final ExtendedSubtaskContext context = event.getSubtaskContext();
ProcessorContext processor = event.getProcessor(); final ProcessorContext processor = event.getProcessor();
if (context.getRemainingExecutionTime() > 0) { if (context.getRemainingExecutionTime() > 0) {
sc.waitingQueue.offer(context); sc.waitingQueue.offer(context);
} else { } else {
...@@ -131,30 +156,33 @@ public class GlobalScheduler { ...@@ -131,30 +156,33 @@ public class GlobalScheduler {
processor.free(); processor.free();
} }
private void handleJobActivated(JobActivatedEvent event, SchedulingContext sc) { private void handleJobActivated(final JobActivatedEvent event, final SchedulingContext sc) {
JobContext job = event.getJobContext(); final JobContext job = event.getJobContext();
DagTask task = job.getTask(); final DagTask task = job.getTask();
long nextRelease = event.getTime() + task.getPeriod(); final long nextRelease = event.getTime() + task.getPeriod();
if (nextRelease < sc.duration) { if (nextRelease < sc.duration) {
JobContext nextJob = new JobContext(task, nextRelease); final JobContext nextJob = new JobContext(task, nextRelease);
sc.events.offer(new JobActivatedEvent(nextRelease, nextJob)); sc.events.offer(new JobActivatedEvent(nextRelease, nextJob));
} }
sc.events.offer(new SubtaskActivatedEvent(event.getTime(), job, job.getSource())); sc.events.offer(new SubtaskActivatedEvent(event.getTime(), job, job.getSource()));
} }
private void handleTaskReleased(TaskReleasedEvent event, SchedulingContext sc) { private void handleTaskReleased(final TaskReleasedEvent event, final SchedulingContext sc) {
DagTask task = event.getTask(); final DagTask task = event.getTask();
long release = event.getTime(); final long release = event.getTime();
JobContext job = new JobContext(task, release); final JobContext job = new JobContext(task, release);
sc.events.offer(new JobActivatedEvent(release, job)); sc.events.offer(new JobActivatedEvent(release, job));
} }
private void updateAdmission(SchedulingContext sc, long time) { private void updateAdmission(final SchedulingContext sc, final long time) {
for (ProcessorContext processor : sc.processors) { Set<ProcessorContext> sortedProcessors =
new TreeSet<>(new ProcessorComparator(priorityManager));
sortedProcessors.addAll(sc.processors);
for (final ProcessorContext processor : sortedProcessors) {
if (processor.canAccept(sc.waitingQueue.peek(), priorityManager)) { if (processor.canAccept(sc.waitingQueue.peek(), priorityManager)) {
ExtendedSubtaskContext context = sc.waitingQueue.poll(); final ExtendedSubtaskContext context = sc.waitingQueue.poll();
if (processor.isIdle()) { if (processor.isIdle()) {
sc.events.offer(new SubtaskStartedEvent(time, context, processor)); sc.events.offer(new SubtaskStartedEvent(time, context, processor));
} else { } else {
...@@ -165,8 +193,8 @@ public class GlobalScheduler { ...@@ -165,8 +193,8 @@ public class GlobalScheduler {
} }
} }
private void updateExecution(SchedulingContext sc, long time) { private void updateExecution(final SchedulingContext sc, final long time) {
for (ProcessorContext processor : sc.processors) { for (final ProcessorContext processor : sc.processors) {
processor.update(time); processor.update(time);
} }
} }
...@@ -178,8 +206,8 @@ public class GlobalScheduler { ...@@ -178,8 +206,8 @@ public class GlobalScheduler {
private final WaitQueue waitingQueue; private final WaitQueue waitingQueue;
private final long duration; private final long duration;
private SchedulingContext(PriorityManager priorityManager, int nbProcessors, private SchedulingContext(final PriorityManager priorityManager, final int nbProcessors,
long duration) { final long duration) {
this.events = new EventQueue(priorityManager); this.events = new EventQueue(priorityManager);
this.waitingQueue = new WaitQueue(priorityManager); this.waitingQueue = new WaitQueue(priorityManager);
this.processors = new HashSet<>(); this.processors = new HashSet<>();
......
...@@ -3,7 +3,7 @@ package mvd.jester.simulator.events; ...@@ -3,7 +3,7 @@ package mvd.jester.simulator.events;
import mvd.jester.simulator.model.ExtendedSubtaskContext; import mvd.jester.simulator.model.ExtendedSubtaskContext;
import mvd.jester.simulator.model.JobContext; import mvd.jester.simulator.model.JobContext;
public abstract class AbstractContextEvent extends AbstractSubtaskEvent implements ISubtaskEvent { public abstract class AbstractContextEvent extends AbstractSubtaskEvent {
private final ExtendedSubtaskContext subtask; private final ExtendedSubtaskContext subtask;
...@@ -13,7 +13,7 @@ public abstract class AbstractContextEvent extends AbstractSubtaskEvent implemen ...@@ -13,7 +13,7 @@ public abstract class AbstractContextEvent extends AbstractSubtaskEvent implemen
this.subtask = subtask; this.subtask = subtask;
} }
@Override // @Override
public ExtendedSubtaskContext getSubtaskContext() { public ExtendedSubtaskContext getSubtaskContext() {
return subtask; return subtask;
} }
......
...@@ -2,7 +2,7 @@ package mvd.jester.simulator.events; ...@@ -2,7 +2,7 @@ package mvd.jester.simulator.events;
import mvd.jester.simulator.model.JobContext; import mvd.jester.simulator.model.JobContext;
public abstract class AbstractSubtaskEvent extends AbstractEvent { public abstract class AbstractSubtaskEvent extends AbstractEvent implements ISubtaskEvent {
private final JobContext jobContext; private final JobContext jobContext;
......
...@@ -5,7 +5,7 @@ import mvd.jester.simulator.model.JobContext; ...@@ -5,7 +5,7 @@ import mvd.jester.simulator.model.JobContext;
public interface ISubtaskEvent extends IEvent { public interface ISubtaskEvent extends IEvent {
public ExtendedSubtaskContext getSubtaskContext(); // public ExtendedSubtaskContext getSubtaskContext();
public JobContext getJobContext(); public JobContext getJobContext();
......
...@@ -3,25 +3,15 @@ package mvd.jester.simulator.events; ...@@ -3,25 +3,15 @@ package mvd.jester.simulator.events;
import mvd.jester.model.Subtask; import mvd.jester.model.Subtask;
import mvd.jester.simulator.model.JobContext; import mvd.jester.simulator.model.JobContext;
public class SubtaskActivatedEvent extends AbstractEvent { public class SubtaskActivatedEvent extends AbstractSubtaskEvent {
private final JobContext job;
private final Subtask subtask; private final Subtask subtask;
public SubtaskActivatedEvent(final long time, final JobContext job, final Subtask subtask) { public SubtaskActivatedEvent(final long time, final JobContext job, final Subtask subtask) {
super(EventType.SUBTASK_ACTIVATED, time); super(EventType.SUBTASK_ACTIVATED, time, job);
this.job = job;
this.subtask = subtask; this.subtask = subtask;
} }
/**
* @return the job
*/
public JobContext getJobContext() {
return job;
}
/** /**
* @return the subtask * @return the subtask
*/ */
...@@ -31,7 +21,7 @@ public class SubtaskActivatedEvent extends AbstractEvent { ...@@ -31,7 +21,7 @@ public class SubtaskActivatedEvent extends AbstractEvent {
@Override @Override
protected String getLoggingMessage() { protected String getLoggingMessage() {
return "Subtask " + getSubtask() + " released"; return "Subtask " + getSubtask() + " of task " + getJobContext().getTask() + " released";
} }
} }
...@@ -10,7 +10,8 @@ public class SubtaskCompletedEvent extends AbstractContextEvent { ...@@ -10,7 +10,8 @@ public class SubtaskCompletedEvent extends AbstractContextEvent {
@Override @Override
protected String getLoggingMessage() { protected String getLoggingMessage() {
return "Subtask " + getSubtaskContext() + " completed"; return "Subtask " + getSubtaskContext() + " of task " + getJobContext().getTask()
+ " completed";
} }
} }
...@@ -16,6 +16,6 @@ public class TaskReleasedEvent extends AbstractEvent { ...@@ -16,6 +16,6 @@ public class TaskReleasedEvent extends AbstractEvent {
@Override @Override
public String getLoggingMessage() { public String getLoggingMessage() {
return "task " + getTask() + " started"; return "Task " + getTask() + " started";
} }
} }
...@@ -15,4 +15,9 @@ public class ExtendedSubtaskContext extends SubtaskContext { ...@@ -15,4 +15,9 @@ public class ExtendedSubtaskContext extends SubtaskContext {
public JobContext getJobContext() { public JobContext getJobContext() {
return jobContext; return jobContext;
} }
@Override
public String toString() {
return getSubtask() + " of task " + getJobContext().getTask();
}
} }
package mvd.jester.simulator.model; package mvd.jester.simulator.model;
import java.util.HashSet;
import java.util.Set;
import org.jgrapht.experimental.dag.DirectedAcyclicGraph; import org.jgrapht.experimental.dag.DirectedAcyclicGraph;
import org.jgrapht.graph.DefaultEdge; import org.jgrapht.graph.DefaultEdge;
import mvd.jester.model.DagTask; import mvd.jester.model.DagTask;
...@@ -11,6 +13,7 @@ public class JobContext { ...@@ -11,6 +13,7 @@ public class JobContext {
private final long releaseTime; private final long releaseTime;
private final long deadline; private final long deadline;
private final Subtask source; private final Subtask source;
private final Set<ExtendedSubtaskContext> finishedSubtasks;
// private long activeThreads; // TODO: Use threads // private long activeThreads; // TODO: Use threads
public JobContext(DagTask task, long releaseTime) { public JobContext(DagTask task, long releaseTime) {
...@@ -18,6 +21,7 @@ public class JobContext { ...@@ -18,6 +21,7 @@ public class JobContext {
this.releaseTime = releaseTime; this.releaseTime = releaseTime;
this.deadline = releaseTime + task.getDeadline(); this.deadline = releaseTime + task.getDeadline();
this.source = findSource(task); this.source = findSource(task);
this.finishedSubtasks = new HashSet<>();
// this.activeThreads = task.getNumberOfThreads(); // this.activeThreads = task.getNumberOfThreads();
} }
...@@ -59,8 +63,26 @@ public class JobContext { ...@@ -59,8 +63,26 @@ public class JobContext {
return releaseTime; return releaseTime;
} }
/**
* @return the finishedSubtasks
*/
public Set<ExtendedSubtaskContext> getFinishedSubtasks() {
return finishedSubtasks;
}
public void registerFinishedSubtask(ExtendedSubtaskContext subtaskContext) {
if (!finishedSubtasks.add(subtaskContext)) {
throw new RuntimeException(
"Subtask could not be added to finished subtask which means it was executed twice!");
}
}
public boolean checkRemainingThreads() { public boolean checkRemainingThreads() {
return false; return true; // TODO: implement check in future
}
public String toString() {
return "of task " + getTask();
} }
} }
package mvd.jester.simulator.model; package mvd.jester.simulator.model;
import java.util.Comparator;
import java.util.Optional; import java.util.Optional;
import mvd.jester.priority.PriorityManager; import mvd.jester.priority.PriorityManager;
import mvd.jester.simulator.exceptions.DeadlineMissedException; import mvd.jester.simulator.exceptions.DeadlineMissedException;
...@@ -96,4 +97,28 @@ public class ProcessorContext { ...@@ -96,4 +97,28 @@ public class ProcessorContext {
return "Processor " + processorId; return "Processor " + processorId;
} }
public static class ProcessorComparator implements Comparator<ProcessorContext> {
private final PriorityManager priorityManager;
public ProcessorComparator(PriorityManager priorityManager) {
this.priorityManager = priorityManager;
}
@Override
public int compare(ProcessorContext p1, ProcessorContext p2) {
if (!p1.getSubtask().isPresent()) {
return -1;
} else if (!p2.getSubtask().isPresent()) {
return 1;
} else {
// Sort in reverse
return priorityManager.compare(p2.currentSubtask.get().getJobContext(),
p1.currentSubtask.get().getJobContext());
}
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment