Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
las3_pub
/
jester
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
36080fd3
authored
4 years ago
by
Michael Schmid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
first commit of scheduler
parent
cfdd3254
Hide whitespace changes
Inline
Side-by-side
Showing
50 changed files
with
2131 additions
and
1340 deletions
+2131
-1340
src/main/java/mvd/jester/App.java
+40
-33
src/main/java/mvd/jester/model/SubtaskContext.java
+22
-11
src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java
+12
-15
src/main/java/mvd/jester/priority/PriorityManager.java
+5
-5
src/main/java/mvd/jester/priority/RateMonotonic.java
+22
-14
src/main/java/mvd/jester/simulator/AbstractSimulator.java
+129
-129
src/main/java/mvd/jester/simulator/DynamicForkJoin.java
+37
-37
src/main/java/mvd/jester/simulator/GlobalScheduler.java
+193
-0
src/main/java/mvd/jester/simulator/ParallelSynchronous.java
+29
-29
src/main/java/mvd/jester/simulator/WaitQueue.java
+14
-0
src/main/java/mvd/jester/simulator/events/AbstractContextEvent.java
+20
-0
src/main/java/mvd/jester/simulator/events/AbstractEvent.java
+28
-0
src/main/java/mvd/jester/simulator/events/AbstractSubtaskEvent.java
+20
-0
src/main/java/mvd/jester/simulator/events/EventQueue.java
+55
-0
src/main/java/mvd/jester/simulator/events/EventType.java
+22
-0
src/main/java/mvd/jester/simulator/events/IEvent.java
+11
-0
src/main/java/mvd/jester/simulator/events/ISubtaskEvent.java
+12
-0
src/main/java/mvd/jester/simulator/events/JobActivatedEvent.java
+26
-0
src/main/java/mvd/jester/simulator/events/JobCompletedEvent.java
+26
-0
src/main/java/mvd/jester/simulator/events/SubtaskActivatedEvent.java
+37
-0
src/main/java/mvd/jester/simulator/events/SubtaskCheckCompletedEvent.java
+28
-0
src/main/java/mvd/jester/simulator/events/SubtaskCompletedEvent.java
+16
-0
src/main/java/mvd/jester/simulator/events/SubtaskPreemptedEvent.java
+37
-0
src/main/java/mvd/jester/simulator/events/SubtaskStartedEvent.java
+29
-0
src/main/java/mvd/jester/simulator/events/SubtaskStoppedEvent.java
+28
-0
src/main/java/mvd/jester/simulator/events/TaskReleasedEvent.java
+21
-0
src/main/java/mvd/jester/simulator/exceptions/DeadlineMissedException.java
+11
-0
src/main/java/mvd/jester/simulator/exceptions/ExecutionOverrunException.java
+10
-0
src/main/java/mvd/jester/simulator/exceptions/SchedulingException.java
+10
-0
src/main/java/mvd/jester/simulator/internals/JobContextInterface.java
+0
-21
src/main/java/mvd/jester/simulator/internals/ProcessorContext.java
+0
-68
src/main/java/mvd/jester/simulator/internals/SortedTaskContextSet.java
+12
-12
src/main/java/mvd/jester/simulator/internals/dynamicforkjoin/JobContext.java
+129
-129
src/main/java/mvd/jester/simulator/internals/dynamicforkjoin/SegmentContext.java
+79
-79
src/main/java/mvd/jester/simulator/internals/dynamicforkjoin/TaskContext.java
+88
-88
src/main/java/mvd/jester/simulator/internals/dynamicforkjoin/TaskletContext.java
+62
-62
src/main/java/mvd/jester/simulator/internals/parallelsynchronous/JobContext.java
+97
-97
src/main/java/mvd/jester/simulator/internals/parallelsynchronous/SegmentContext.java
+43
-43
src/main/java/mvd/jester/simulator/internals/parallelsynchronous/TaskContext.java
+86
-86
src/main/java/mvd/jester/simulator/model/ExtendedSubtaskContext.java
+18
-0
src/main/java/mvd/jester/simulator/model/ISubtaskContext.java
+13
-0
src/main/java/mvd/jester/simulator/model/ITaskContext.java
+8
-6
src/main/java/mvd/jester/simulator/model/JobContext.java
+66
-0
src/main/java/mvd/jester/simulator/model/ProcessorContext.java
+99
-0
src/main/java/mvd/jester/tests/FonsecaNelis.java
+15
-10
src/test/java/mvd/jester/priority/TestEarliestDeadlineFirst.java
+57
-57
src/test/java/mvd/jester/priority/TestRateMonotonic.java
+57
-57
src/test/java/mvd/jester/simulator/TestProcessorContext.java
+107
-107
src/test/java/mvd/jester/simulator/dynamicforkjoin/TestJobContext.java
+84
-84
src/test/java/mvd/jester/simulator/parallelsynchronous/TestJobContext.java
+61
-61
No files found.
src/main/java/mvd/jester/App.java
View file @
36080fd3
...
...
@@ -5,6 +5,8 @@ import java.util.List;
import
mvd.jester.model.DagTask
;
import
mvd.jester.model.SystemManager
;
import
mvd.jester.model.SystemManager.DagTaskBuilder
;
import
mvd.jester.priority.RateMonotonic
;
import
mvd.jester.simulator.GlobalScheduler
;
import
mvd.jester.tests.AbstractTest
;
import
mvd.jester.tests.FonsecaNelis
;
import
mvd.jester.tests.MelaniButtazzo
;
...
...
@@ -19,52 +21,57 @@ import mvd.jester.tests.TypeFunction.UnkownStructure;
*/
public
class
App
{
public
static
void
main
(
String
[]
args
)
{
GlobalScheduler
scheduler
=
new
GlobalScheduler
(
new
RateMonotonic
(),
4
);
DagTaskBuilder
builder
=
new
DagTaskBuilder
().
setNumberOfProcessors
(
4
);
scheduler
.
schedule
(
builder
.
generateTaskSet
(
3
),
10000
);
// {
//
SystemManager manager = new SystemManager(8);
//
DagTaskBuilder builder = new DagTaskBuilder();
//
TestEnvironment te = new TestEnvironment();
// SystemManager manager = new SystemManager(8);
// DagTaskBuilder builder = new DagTaskBuilder();
// TestEnvironment te = new TestEnvironment();
//
List<AbstractTest<DagTask>> tests =
//
te.registerTests(Arrays.asList(new SchmidMottok(new UnkownStructure(), manager),
//
new SchmidMottok(new KownStructure(), manager),
//
new MelaniButtazzo(manager), new FonsecaNelis(manager)));
// List<AbstractTest<DagTask>> tests =
//
te.registerTests(Arrays.asList(new SchmidMottok(new UnkownStructure(), manager),
// new SchmidMottok(new KownStructure(), manager),
// new MelaniButtazzo(manager), new FonsecaNelis(manager)));
//
te.varyUtilization(builder, tests, 8, 500);
// te.varyUtilization(builder, tests, 8, 500);
// }
// {
//
SystemManager manager = new SystemManager(8);
//
DagTaskBuilder builder = new DagTaskBuilder();
//
TestEnvironment te = new TestEnvironment();
// SystemManager manager = new SystemManager(8);
// DagTaskBuilder builder = new DagTaskBuilder();
// TestEnvironment te = new TestEnvironment();
//
List<AbstractTest<DagTask>> tests =
//
te.registerTests(Arrays.asList(new SchmidMottok(new UnkownStructure(), manager),
//
new SchmidMottok(new KownStructure(), manager),
//
new MelaniButtazzo(manager), new FonsecaNelis(manager)));
// List<AbstractTest<DagTask>> tests =
//
te.registerTests(Arrays.asList(new SchmidMottok(new UnkownStructure(), manager),
// new SchmidMottok(new KownStructure(), manager),
// new MelaniButtazzo(manager), new FonsecaNelis(manager)));
//
te.varyNumberOfProcessors(builder, tests, manager, 500);
// te.varyNumberOfProcessors(builder, tests, manager, 500);
// }
{
SystemManager
manager
=
new
SystemManager
(
8
);
DagTaskBuilder
builder
=
new
DagTaskBuilder
();
TestEnvironment
te
=
new
TestEnvironment
();
//
{
//
SystemManager manager = new SystemManager(8);
//
DagTaskBuilder builder = new DagTaskBuilder();
//
TestEnvironment te = new TestEnvironment();
List
<
AbstractTest
<
DagTask
>>
tests
=
te
.
registerTests
(
Arrays
.
asList
(
new
SchmidMottok
(
new
UnkownStructure
(),
manager
),
new
SchmidMottok
(
new
KownStructure
(),
manager
),
new
MelaniButtazzo
(
manager
),
new
FonsecaNelis
(
manager
)));
//
List<AbstractTest<DagTask>> tests =
// te.registerTests(Arrays.asList(new SchmidMottok(new UnkownStructure(), manager),
//
new SchmidMottok(new KownStructure(), manager),
//
new MelaniButtazzo(manager), new FonsecaNelis(manager)));
te
.
varyNumberOfTasks
(
builder
,
tests
,
8
,
500
);
}
//
te.varyNumberOfTasks(builder, tests, 8, 500);
//
}
// {
//
SystemManager manager = new SystemManager(8);
//
DagTaskBuilder builder = new DagTaskBuilder();
//
TestEnvironment te = new TestEnvironment();
// SystemManager manager = new SystemManager(8);
// DagTaskBuilder builder = new DagTaskBuilder();
// TestEnvironment te = new TestEnvironment();
//
List<AbstractTest<DagTask>> tests =
//
te.registerTests(Arrays.asList(new SchmidMottok(manager),
//
new MelaniButtazzo(manager), new FonsecaNelis(manager)));
// List<AbstractTest<DagTask>> tests =
// te.registerTests(Arrays.asList(new SchmidMottok(manager),
// new MelaniButtazzo(manager), new FonsecaNelis(manager)));
//
te.measureExecutionTimes(builder, tests, manager, 500);
// te.measureExecutionTimes(builder, tests, manager, 500);
// }
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/model/SubtaskContext.java
View file @
36080fd3
package
mvd
.
jester
.
model
;
public
class
SubtaskContext
{
private
long
wcet
;
private
final
Subtask
job
;
private
long
remainingExecutionTime
;
private
final
Subtask
subtask
;
public
SubtaskContext
(
final
Subtask
job
)
{
this
.
wcet
=
job
.
getWcet
();
this
.
job
=
job
;
public
SubtaskContext
(
final
Subtask
subtask
)
{
this
.
remainingExecutionTime
=
subtask
.
getWcet
();
this
.
subtask
=
subtask
;
}
/**
* @return the job
*/
public
Subtask
get
Job
()
{
return
job
;
public
Subtask
get
Subtask
()
{
return
subtask
;
}
/**
* @return the wcet
*/
public
long
get
Wcet
()
{
return
wcet
;
public
long
get
RemainingExecutionTime
()
{
return
remainingExecutionTime
;
}
/**
* @param wcet the wcet to set
*/
public
void
setWcet
(
final
long
wcet
)
{
this
.
wcet
=
wcet
;
public
void
setRemainingExecutionTime
(
final
long
wcet
)
{
this
.
remainingExecutionTime
=
wcet
;
}
public
void
updateRemainingExecutionTime
(
final
long
time
)
{
this
.
remainingExecutionTime
-=
time
;
}
@Override
public
String
toString
()
{
return
getSubtask
()
+
":"
+
getRemainingExecutionTime
();
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java
View file @
36080fd3
...
...
@@ -4,10 +4,7 @@ import java.util.Arrays;
import
java.util.HashSet
;
import
java.util.Set
;
import
mvd.jester.model.Task
;
import
mvd.jester.simulator.AbstractSimulator
;
import
mvd.jester.simulator.ParallelSynchronous
;
import
mvd.jester.simulator.DynamicForkJoin
;
import
mvd.jester.simulator.internals.TaskContextInterface
;
import
mvd.jester.simulator.model.JobContext
;
import
mvd.jester.tests.AbstractTest
;
import
mvd.jester.tests.ChwaLee
;
...
...
@@ -18,8 +15,8 @@ public class EarliestDeadlineFirst implements PriorityManager {
final
static
Set
<
Class
<?
extends
AbstractTest
<?
extends
Task
>>>
abstractTests
=
new
HashSet
<>(
Arrays
.
asList
(
ChwaLee
.
class
));
final
static
Set
<
Class
<?
extends
AbstractSimulator
>>
abstractSimulators
=
new
HashSet
<>(
Arrays
.
asList
(
ParallelSynchronous
.
class
,
DynamicForkJoin
.
class
));
//
final static Set<Class<? extends AbstractSimulator>> abstractSimulators =
//
new HashSet<>(Arrays.asList(ParallelSynchronous.class, DynamicForkJoin.class));
/**
* Compare the priority of two tasks according to the Rate Monotonic policy
...
...
@@ -35,7 +32,7 @@ public class EarliestDeadlineFirst implements PriorityManager {
}
@Override
public
int
compare
(
TaskContextInterface
t1
,
TaskContextInterface
t2
)
{
public
int
compare
(
JobContext
t1
,
JobContext
t2
)
{
return
(
int
)
(
t1
.
getDeadline
()
-
t2
.
getDeadline
());
}
...
...
@@ -49,15 +46,15 @@ public class EarliestDeadlineFirst implements PriorityManager {
return
abstractTests
.
contains
(
abstractTestClass
);
}
@Override
public
boolean
hasSimulator
(
AbstractSimulator
abstractSimulator
)
{
return
abstractSimulators
.
contains
(
abstractSimulator
.
getClass
());
}
//
@Override
//
public boolean hasSimulator(AbstractSimulator abstractSimulator) {
//
return abstractSimulators.contains(abstractSimulator.getClass());
//
}
@Override
public
boolean
hasSimulator
(
Class
<?
extends
AbstractSimulator
>
abstractSimulatorClass
)
{
return
abstractSimulators
.
contains
(
abstractSimulatorClass
);
}
//
@Override
//
public boolean hasSimulator(Class<? extends AbstractSimulator> abstractSimulatorClass) {
//
return abstractSimulators.contains(abstractSimulatorClass);
//
}
@Override
public
String
getName
()
{
...
...
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/priority/PriorityManager.java
View file @
36080fd3
package
mvd
.
jester
.
priority
;
import
mvd.jester.model.Task
;
import
mvd.jester.simulator.AbstractSimulator
;
import
mvd.jester.simulator.
internals.TaskContextInterface
;
//
import mvd.jester.simulator.AbstractSimulator;
import
mvd.jester.simulator.
model.JobContext
;
import
mvd.jester.tests.AbstractTest
;
/**
...
...
@@ -12,15 +12,15 @@ public interface PriorityManager {
public
int
compare
(
Task
t1
,
Task
t2
);
public
int
compare
(
TaskContextInterface
t1
,
TaskContextInterface
t2
);
public
int
compare
(
JobContext
t1
,
JobContext
t2
);
public
boolean
hasTest
(
AbstractTest
<?
extends
Task
>
abstractTest
);
public
boolean
hasTest
(
Class
<?
extends
AbstractTest
<?
extends
Task
>>
abstractTestClass
);
public
boolean
hasSimulator
(
AbstractSimulator
abstractTest
);
//
public boolean hasSimulator(AbstractSimulator abstractTest);
public
boolean
hasSimulator
(
Class
<?
extends
AbstractSimulator
>
abstractTestClass
);
//
public boolean hasSimulator(Class<? extends AbstractSimulator> abstractTestClass);
public
String
getName
();
...
...
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/priority/RateMonotonic.java
View file @
36080fd3
...
...
@@ -4,8 +4,8 @@ import java.util.Arrays;
import
java.util.HashSet
;
import
java.util.Set
;
import
mvd.jester.model.Task
;
import
mvd.jester.simulator.AbstractSimulator
;
import
mvd.jester.simulator.
internals.TaskContextInterface
;
//
import mvd.jester.simulator.AbstractSimulator;
import
mvd.jester.simulator.
model.JobContext
;
import
mvd.jester.tests.AbstractTest
;
public
class
RateMonotonic
implements
PriorityManager
{
...
...
@@ -13,9 +13,9 @@ public class RateMonotonic implements PriorityManager {
final
static
Set
<
Class
<?
extends
AbstractTest
<?
extends
Task
>>>
abstractTests
=
new
HashSet
<>(
Arrays
.
asList
(
mvd
.
jester
.
tests
.
MaiaBertogna
.
class
,
mvd
.
jester
.
tests
.
SchmidMottok
.
class
));
final
static
Set
<
Class
<?
extends
AbstractSimulator
>>
abstractSimulators
=
new
HashSet
<>(
Arrays
.
asList
(
mvd
.
jester
.
simulator
.
ParallelSynchronous
.
class
,
mvd
.
jester
.
simulator
.
DynamicForkJoin
.
class
));
//
final static Set<Class<? extends AbstractSimulator>> abstractSimulators =
//
new HashSet<>(Arrays.asList(mvd.jester.simulator.ParallelSynchronous.class,
//
mvd.jester.simulator.DynamicForkJoin.class));
/**
* Compare the priority of two tasks according to the Rate Monotonic policy
...
...
@@ -30,8 +30,16 @@ public class RateMonotonic implements PriorityManager {
return
Long
.
compare
(
t1
.
getPeriod
(),
t2
.
getPeriod
());
}
/**
* Compare the priority of two tasks according to the Rate Monotonic policy
*
* @param t1 The first task context
* @param t2 The second task context
* @return 0 if both tasks have the same priority, negative number if the first task has a
* higher priority, positive number if the second task has a higher priority
*/
@Override
public
int
compare
(
TaskContextInterface
t1
,
TaskContextInterface
t2
)
{
public
int
compare
(
JobContext
t1
,
JobContext
t2
)
{
return
Long
.
compare
(
t1
.
getTask
().
getPeriod
(),
t2
.
getTask
().
getPeriod
());
}
...
...
@@ -45,15 +53,15 @@ public class RateMonotonic implements PriorityManager {
return
abstractTests
.
contains
(
abstractTestClass
);
}
@Override
public
boolean
hasSimulator
(
AbstractSimulator
abstractSimulator
)
{
return
abstractSimulators
.
contains
(
abstractSimulator
.
getClass
());
}
//
@Override
//
public boolean hasSimulator(AbstractSimulator abstractSimulator) {
//
return abstractSimulators.contains(abstractSimulator.getClass());
//
}
@Override
public
boolean
hasSimulator
(
Class
<?
extends
AbstractSimulator
>
abstractSimulatorClass
)
{
return
abstractSimulators
.
contains
(
abstractSimulatorClass
);
}
//
@Override
//
public boolean hasSimulator(Class<? extends AbstractSimulator> abstractSimulatorClass) {
//
return abstractSimulators.contains(abstractSimulatorClass);
//
}
@Override
public
String
getName
()
{
...
...
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/AbstractSimulator.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
;
import
java.util.Comparator
;
import
java.util.HashSet
;
import
java.util.Set
;
import
java.util.TreeSet
;
import
com.google.common.collect.TreeMultiset
;
import
mvd.jester.model.SystemManager
;
import
mvd.jester.priority.PriorityManager
;
import
mvd.jester.priority.RateMonotonic
;
import
mvd.jester.TypeInterface
;
import
mvd.jester.info.SchedulingInfo
;
import
mvd.jester.simulator.internals
.ProcessorContext
;
import
mvd.jester.simulator.internals.TaskContextInterface
;
/**
* AbstractSimulator
*/
public
abstract
class
AbstractSimulator
implements
SimulatorInterface
,
TypeInterface
{
protected
final
SystemManager
systemSetup
;
protected
final
Set
<
ProcessorContext
>
processors
;
protected
TreeMultiset
<
TaskContextInterface
>
readyTasks
;
AbstractSimulator
(
SystemManager
systemSetup
)
{
this
.
systemSetup
=
systemSetup
;
this
.
readyTasks
=
TreeMultiset
.
create
((
t1
,
t2
)
->
new
RateMonotonic
().
compare
(
t1
,
t2
));
processors
=
new
HashSet
<>();
for
(
int
i
=
0
;
i
<
systemSetup
.
getNumberOfProcessors
();
++
i
)
{
processors
.
add
(
new
ProcessorContext
(
i
));
}
}
protected
abstract
boolean
releaseTasks
(
long
timeStep
);
@Override
public
SchedulingInfo
runSimulation
(
PriorityManager
priorityManager
)
{
// SchedulingInfo schedulingInfo = new SchedulingInfo(systemSetup.getParallelTaskRatio(),
// systemSetup.getUtilization());
// long hyperPeriod = init(priorityManager);
// for (int t = 0; t < hyperPeriod; ++t) {
// if (!releaseTasks(t)) {
// throw new RuntimeException("Could not release a task. This should not happen!");
// }
// Set<ProcessorContext> sortedProcessors = sortProcessors(processors);
// for (ProcessorContext p : sortedProcessors) {
// for (TaskContextInterface tc : readyTasks) {
// if (p.acceptTask(tc, t)) {
// break;
// }
// }
// }
// for (ProcessorContext p : processors) {
// Optional<TaskContextInterface> optionalTc = p.updateExecution(t);
// if (optionalTc.isPresent()) {
// TaskContextInterface tc = optionalTc.get();
// if (t >= tc.getDeadline()) {
// TerminationInfo terminationInfo =
// new TerminationInfo(tc.getReleaseTime(), tc.getDeadline(), t);
// schedulingInfo.addTerminationInfo(terminationInfo);
// EventPrinter.print("Time " + t + ": Task " + tc + " failed its deadline!");
// schedulingInfo.setFailedTerminationInfo(terminationInfo);
// return schedulingInfo;
// }
// readyTasks.remove(optionalTc.get());
// }
// }
// }
// return schedulingInfo;
return
null
;
}
private
long
init
(
PriorityManager
priorityManager
)
{
this
.
readyTasks
=
TreeMultiset
.
create
((
t1
,
t2
)
->
priorityManager
.
compare
(
t1
,
t2
));
for
(
ProcessorContext
p
:
processors
)
{
p
.
setJob
(
null
);
}
return
getHyperPeriod
();
}
private
Set
<
ProcessorContext
>
sortProcessors
(
Set
<
ProcessorContext
>
processors
)
{
Set
<
ProcessorContext
>
sortedProcessors
=
new
TreeSet
<>(
new
ProcessorComparator
());
processors
.
forEach
(
p
->
sortedProcessors
.
add
(
p
));
return
sortedProcessors
;
}
private
long
getHyperPeriod
()
{
// return
// systemSetup.getTasks().stream().max(Comparator.comparing(SynchronousTask::getPeriod))
// .get().getPeriod() * 10;
return
10
;
}
private
class
ProcessorComparator
implements
Comparator
<
ProcessorContext
>
{
@Override
public
int
compare
(
ProcessorContext
p1
,
ProcessorContext
p2
)
{
if
(!
p1
.
getJob
().
isPresent
())
{
return
-
1
;
}
else
if
(!
p2
.
getJob
().
isPresent
())
{
return
1
;
}
else
{
long
p1Period
=
p1
.
getJob
().
get
().
getTask
Context
().
getTask
().
getPeriod
();
long
p2Period
=
p2
.
getJob
().
get
().
getTask
Context
().
getTask
().
getPeriod
();
if
(
p1Period
==
p2Period
)
{
return
1
;
}
else
{
return
(
int
)
(
p2
.
getJob
().
get
().
getTask
Context
().
getTask
().
getPeriod
()
-
p1
.
getJob
().
get
().
getTask
Context
().
getTask
().
getPeriod
());
}
}
}
}
}
//
package mvd.jester.simulator;
//
import java.util.Comparator;
//
import java.util.HashSet;
//
import java.util.Set;
//
import java.util.TreeSet;
//
import com.google.common.collect.TreeMultiset;
//
import mvd.jester.model.SystemManager;
//
import mvd.jester.priority.PriorityManager;
//
import mvd.jester.priority.RateMonotonic;
//
import mvd.jester.TypeInterface;
//
import mvd.jester.info.SchedulingInfo;
// import mvd.jester.simulator.model
.ProcessorContext;
// import mvd.jester.simulator.internals.ITaskContext
;
/
/ /
**
//
* AbstractSimulator
//
*/
//
public abstract class AbstractSimulator implements SimulatorInterface, TypeInterface {
//
protected final SystemManager systemSetup;
//
protected final Set<ProcessorContext> processors;
// protected TreeMultiset<ITaskContext
> readyTasks;
//
AbstractSimulator(SystemManager systemSetup) {
//
this.systemSetup = systemSetup;
//
this.readyTasks = TreeMultiset.create((t1, t2) -> new RateMonotonic().compare(t1, t2));
//
processors = new HashSet<>();
//
for (int i = 0; i < systemSetup.getNumberOfProcessors(); ++i) {
//
processors.add(new ProcessorContext(i));
//
}
//
}
//
protected abstract boolean releaseTasks(long timeStep);
//
@Override
//
public SchedulingInfo runSimulation(PriorityManager priorityManager) {
//
// SchedulingInfo schedulingInfo = new SchedulingInfo(systemSetup.getParallelTaskRatio(),
//
// systemSetup.getUtilization());
//
// long hyperPeriod = init(priorityManager);
//
// for (int t = 0; t < hyperPeriod; ++t) {
//
// if (!releaseTasks(t)) {
//
// throw new RuntimeException("Could not release a task. This should not happen!");
//
// }
//
// Set<ProcessorContext> sortedProcessors = sortProcessors(processors);
//
// for (ProcessorContext p : sortedProcessors) {
//
// for (TaskContextInterface tc : readyTasks) {
//
// if (p.acceptTask(tc, t)) {
//
// break;
//
// }
//
// }
//
// }
//
// for (ProcessorContext p : processors) {
//
// Optional<TaskContextInterface> optionalTc = p.updateExecution(t);
//
// if (optionalTc.isPresent()) {
//
// TaskContextInterface tc = optionalTc.get();
//
// if (t >= tc.getDeadline()) {
//
// TerminationInfo terminationInfo =
//
// new TerminationInfo(tc.getReleaseTime(), tc.getDeadline(), t);
//
// schedulingInfo.addTerminationInfo(terminationInfo);
//
// EventPrinter.print("Time " + t + ": Task " + tc + " failed its deadline!");
//
// schedulingInfo.setFailedTerminationInfo(terminationInfo);
//
// return schedulingInfo;
//
// }
//
// readyTasks.remove(optionalTc.get());
//
// }
//
// }
//
// }
//
// return schedulingInfo;
//
return null;
//
}
//
private long init(PriorityManager priorityManager) {
//
this.readyTasks = TreeMultiset.create((t1, t2) -> priorityManager.compare(t1, t2));
//
for (ProcessorContext p : processors) {
//
p.setJob(null);
//
}
//
return getHyperPeriod();
//
}
//
private Set<ProcessorContext> sortProcessors(Set<ProcessorContext> processors) {
//
Set<ProcessorContext> sortedProcessors = new TreeSet<>(new ProcessorComparator());
//
processors.forEach(p -> sortedProcessors.add(p));
//
return sortedProcessors;
//
}
//
private long getHyperPeriod() {
//
// return
//
// systemSetup.getTasks().stream().max(Comparator.comparing(SynchronousTask::getPeriod))
//
// .get().getPeriod() * 10;
//
return 10;
//
}
//
private class ProcessorComparator implements Comparator<ProcessorContext> {
//
@Override
//
public int compare(ProcessorContext p1, ProcessorContext p2) {
// if (!p1.getSubtask
().isPresent()) {
//
return -1;
// } else if (!p2.getSubtask
().isPresent()) {
//
return 1;
//
} else {
// long p1Period = p1.getSubtask().get().getJob
Context().getTask().getPeriod();
// long p2Period = p2.getSubtask().get().getJob
Context().getTask().getPeriod();
//
if (p1Period == p2Period) {
//
return 1;
//
} else {
// return (int) (p2.getSubtask().get().getJob
Context().getTask().getPeriod()
// - p1.getSubtask().get().getJob
Context().getTask().getPeriod());
//
}
//
}
//
}
//
}
//
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/DynamicForkJoin.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
;
import
mvd.jester.model.SystemManager
;
/**
* SchmidMottok
*/
public
class
DynamicForkJoin
extends
AbstractSimulator
{
public
DynamicForkJoin
(
SystemManager
systemSetup
)
{
super
(
systemSetup
);
}
@Override
protected
boolean
releaseTasks
(
long
timeStep
)
{
// // for (SynchronousTask t : systemSetup.getTasks()) {
// if (timeStep % t.getPeriod() == 0) {
// TaskContext tc = new TaskContext(t, systemSetup.getNumberOfProcessors(), timeStep);
// if (!readyTasks.add(tc)) {
// EventPrinter
// .print("Time " + timeStep + ": Task " + tc + " could not be released!");
// return false;
// }
// EventPrinter.print("Time " + timeStep + ": Task " + tc + " released!");
// }
// }
return
true
;
}
@Override
public
String
getName
()
{
return
"SchmidMottok"
;
}
}
//
package mvd.jester.simulator;
//
import mvd.jester.model.SystemManager;
/
/ /
**
//
* SchmidMottok
//
*/
//
public class DynamicForkJoin extends AbstractSimulator {
//
public DynamicForkJoin(SystemManager systemSetup) {
//
super(systemSetup);
//
}
//
@Override
//
protected boolean releaseTasks(long timeStep) {
//
// // for (SynchronousTask t : systemSetup.getTasks()) {
//
// if (timeStep % t.getPeriod() == 0) {
//
// TaskContext tc = new TaskContext(t, systemSetup.getNumberOfProcessors(), timeStep);
//
// if (!readyTasks.add(tc)) {
//
// EventPrinter
//
// .print("Time " + timeStep + ": Task " + tc + " could not be released!");
//
// return false;
//
// }
//
// EventPrinter.print("Time " + timeStep + ": Task " + tc + " released!");
//
// }
//
// }
//
return true;
//
}
//
@Override
//
public String getName() {
//
return "SchmidMottok";
//
}
//
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/GlobalScheduler.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Optional
;
import
java.util.Set
;
import
org.jgrapht.Graphs
;
import
mvd.jester.model.DagTask
;
import
mvd.jester.model.Subtask
;
import
mvd.jester.priority.PriorityManager
;
import
mvd.jester.simulator.events.*
;
import
mvd.jester.simulator.exceptions.SchedulingException
;
import
mvd.jester.simulator.model.ExtendedSubtaskContext
;
import
mvd.jester.simulator.model.JobContext
;
import
mvd.jester.simulator.model.ProcessorContext
;
public
class
GlobalScheduler
{
private
final
int
nbProcessors
;
private
final
PriorityManager
priorityManager
;
public
GlobalScheduler
(
PriorityManager
priorityManager
,
int
nbProcessors
)
{
this
.
priorityManager
=
priorityManager
;
this
.
nbProcessors
=
nbProcessors
;
}
public
void
schedule
(
Set
<
DagTask
>
taskSet
,
long
duration
)
{
SchedulingContext
sc
=
new
SchedulingContext
(
priorityManager
,
nbProcessors
,
duration
);
taskSet
.
forEach
(
t
->
sc
.
events
.
offer
(
new
TaskReleasedEvent
(
0
,
t
)));
while
(!
sc
.
events
.
isEmpty
())
{
IEvent
event
=
sc
.
events
.
poll
();
updateExecution
(
sc
,
event
.
getTime
());
handle
(
event
,
sc
);
}
}
private
void
handle
(
IEvent
event
,
SchedulingContext
sc
)
{
event
.
log
();
switch
(
event
.
getType
())
{
case
SUBTASK_ACTIVATED:
handleSubtaskActivated
((
SubtaskActivatedEvent
)
event
,
sc
);
break
;
case
SUBTASK_COMPLETED:
handleSubtaskCompleted
((
SubtaskCompletedEvent
)
event
,
sc
);
break
;
case
SUBTASK_CHECK_COMPLETED:
handleSubtaskCheckCompleted
((
SubtaskCheckCompletedEvent
)
event
,
sc
);
break
;
case
SUBTASK_PREEMPTED:
handleSubtaskPreempted
((
SubtaskPreemptedEvent
)
event
,
sc
);
break
;
case
SUBTASK_STARTED:
handleSubtaskStarted
((
SubtaskStartedEvent
)
event
,
sc
);
break
;
case
SUBTASK_STOPPED:
handleSubtaskStopped
((
SubtaskStoppedEvent
)
event
,
sc
);
break
;
case
JOB_ACTIVATED:
handleJobActivated
((
JobActivatedEvent
)
event
,
sc
);
break
;
case
TASK_RELEASED:
handleTaskReleased
((
TaskReleasedEvent
)
event
,
sc
);
break
;
default
:
throw
new
IllegalArgumentException
(
event
.
getType
()
+
" is not handled by "
+
this
.
getClass
());
}
}
private
void
handleSubtaskActivated
(
SubtaskActivatedEvent
event
,
SchedulingContext
sc
)
{
Subtask
subtask
=
event
.
getSubtask
();
JobContext
job
=
event
.
getJobContext
();
sc
.
waitingQueue
.
offer
(
new
ExtendedSubtaskContext
(
job
,
subtask
));
updateAdmission
(
sc
,
event
.
getTime
());
}
private
void
handleSubtaskCheckCompleted
(
SubtaskCheckCompletedEvent
event
,
SchedulingContext
sc
)
{
ProcessorContext
processor
=
event
.
getProcessor
();
if
(
processor
.
isIdle
()
||
!
processor
.
getSubtask
().
get
().
equals
(
event
.
getSubtaskContext
()))
{
throw
new
SchedulingException
(
processor
+
" should execute "
+
event
.
getSubtaskContext
());
}
Optional
<
ExtendedSubtaskContext
>
context
=
processor
.
getSubtask
();
if
(
context
.
isPresent
()
&&
context
.
get
().
getRemainingExecutionTime
()
==
0
)
{
sc
.
events
.
offer
(
new
SubtaskStoppedEvent
(
event
.
getTime
(),
context
.
get
(),
processor
));
}
}
private
void
handleSubtaskCompleted
(
SubtaskCompletedEvent
event
,
SchedulingContext
sc
)
{
ExtendedSubtaskContext
subtask
=
event
.
getSubtaskContext
();
JobContext
job
=
subtask
.
getJobContext
();
DagTask
task
=
subtask
.
getJobContext
().
getTask
();
List
<
Subtask
>
successor
=
Graphs
.
successorListOf
(
task
.
getJobDag
(),
subtask
.
getSubtask
());
if
(
successor
.
isEmpty
())
{
sc
.
events
.
offer
(
new
JobCompletedEvent
(
event
.
getTime
(),
job
));
updateAdmission
(
sc
,
event
.
getTime
());
}
else
{
for
(
Subtask
s
:
successor
)
{
sc
.
events
.
offer
(
new
SubtaskActivatedEvent
(
event
.
getTime
(),
job
,
s
));
}
}
}
private
void
handleSubtaskPreempted
(
SubtaskPreemptedEvent
event
,
SchedulingContext
sc
)
{
ProcessorContext
processor
=
event
.
getProcessor
();
long
time
=
event
.
getTime
();
sc
.
events
.
offer
(
new
SubtaskStoppedEvent
(
time
,
event
.
getNextSubtask
(),
processor
));
sc
.
events
.
offer
(
new
SubtaskStartedEvent
(
time
,
event
.
getSubtaskContext
(),
processor
));
}
private
void
handleSubtaskStarted
(
SubtaskStartedEvent
event
,
SchedulingContext
sc
)
{
long
time
=
event
.
getTime
();
ProcessorContext
processor
=
event
.
getProcessor
();
ExtendedSubtaskContext
context
=
event
.
getSubtaskContext
();
if
(
processor
.
accept
(
context
,
time
))
{
sc
.
events
.
offer
(
new
SubtaskCheckCompletedEvent
(
time
+
context
.
getRemainingExecutionTime
(),
context
,
processor
));
}
}
private
void
handleSubtaskStopped
(
SubtaskStoppedEvent
event
,
SchedulingContext
sc
)
{
ExtendedSubtaskContext
context
=
event
.
getSubtaskContext
();
ProcessorContext
processor
=
event
.
getProcessor
();
if
(
context
.
getRemainingExecutionTime
()
>
0
)
{
sc
.
waitingQueue
.
offer
(
context
);
}
else
{
sc
.
events
.
offer
(
new
SubtaskCompletedEvent
(
event
.
getTime
(),
context
));
}
processor
.
free
();
}
private
void
handleJobActivated
(
JobActivatedEvent
event
,
SchedulingContext
sc
)
{
JobContext
job
=
event
.
getJobContext
();
DagTask
task
=
job
.
getTask
();
long
nextRelease
=
event
.
getTime
()
+
task
.
getPeriod
();
if
(
nextRelease
<
sc
.
duration
)
{
JobContext
nextJob
=
new
JobContext
(
task
,
nextRelease
);
sc
.
events
.
offer
(
new
JobActivatedEvent
(
nextRelease
,
nextJob
));
}
sc
.
events
.
offer
(
new
SubtaskActivatedEvent
(
event
.
getTime
(),
job
,
job
.
getSource
()));
}
private
void
handleTaskReleased
(
TaskReleasedEvent
event
,
SchedulingContext
sc
)
{
DagTask
task
=
event
.
getTask
();
long
release
=
event
.
getTime
();
JobContext
job
=
new
JobContext
(
task
,
release
);
sc
.
events
.
offer
(
new
JobActivatedEvent
(
release
,
job
));
}
private
void
updateAdmission
(
SchedulingContext
sc
,
long
time
)
{
for
(
ProcessorContext
processor
:
sc
.
processors
)
{
if
(
processor
.
canAccept
(
sc
.
waitingQueue
.
peek
(),
priorityManager
))
{
ExtendedSubtaskContext
context
=
sc
.
waitingQueue
.
poll
();
if
(
processor
.
isIdle
())
{
sc
.
events
.
offer
(
new
SubtaskStartedEvent
(
time
,
context
,
processor
));
}
else
{
sc
.
events
.
offer
(
new
SubtaskPreemptedEvent
(
time
,
processor
.
getSubtask
().
get
(),
processor
,
context
));
}
}
}
}
private
void
updateExecution
(
SchedulingContext
sc
,
long
time
)
{
for
(
ProcessorContext
processor
:
sc
.
processors
)
{
processor
.
update
(
time
);
}
}
private
class
SchedulingContext
{
private
final
EventQueue
events
;
private
final
Set
<
ProcessorContext
>
processors
;
private
final
WaitQueue
waitingQueue
;
private
final
long
duration
;
private
SchedulingContext
(
PriorityManager
priorityManager
,
int
nbProcessors
,
long
duration
)
{
this
.
events
=
new
EventQueue
(
priorityManager
);
this
.
waitingQueue
=
new
WaitQueue
(
priorityManager
);
this
.
processors
=
new
HashSet
<>();
for
(
int
m
=
0
;
m
<
nbProcessors
;
++
m
)
{
processors
.
add
(
new
ProcessorContext
(
m
));
}
this
.
duration
=
duration
;
}
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/ParallelSynchronous.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
;
//
package mvd.jester.simulator;
import
mvd.jester.model.SystemManager
;
//
import mvd.jester.model.SystemManager;
/**
* MaiaBertogna
*/
public
class
ParallelSynchronous
extends
AbstractSimulator
{
/
/ /
**
//
* MaiaBertogna
//
*/
//
public class ParallelSynchronous extends AbstractSimulator {
public
ParallelSynchronous
(
SystemManager
systemSetup
)
{
super
(
systemSetup
);
}
//
public ParallelSynchronous(SystemManager systemSetup) {
//
super(systemSetup);
//
}
@Override
protected
boolean
releaseTasks
(
long
timeStep
)
{
// for (SynchronousTask t : systemSetup.getTasks()) {
// if (timeStep % t.getPeriod() == 0) {
// TaskContext tc = new TaskContext(t, timeStep);
// if (!readyTasks.add(tc)) {
// EventPrinter
// .print("Time " + timeStep + ": Task " + tc + " could not be released!");
// return false;
// }
// EventPrinter.print("Time " + timeStep + ": Task " + tc + " released!");
// }
// }
return
true
;
}
//
@Override
//
protected boolean releaseTasks(long timeStep) {
//
// for (SynchronousTask t : systemSetup.getTasks()) {
//
// if (timeStep % t.getPeriod() == 0) {
//
// TaskContext tc = new TaskContext(t, timeStep);
//
// if (!readyTasks.add(tc)) {
//
// EventPrinter
//
// .print("Time " + timeStep + ": Task " + tc + " could not be released!");
//
// return false;
//
// }
//
// EventPrinter.print("Time " + timeStep + ": Task " + tc + " released!");
//
// }
//
// }
//
return true;
//
}
@Override
public
String
getName
()
{
return
"MaiaBertogna"
;
}
//
@Override
//
public String getName() {
//
return "MaiaBertogna";
//
}
}
//
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/WaitQueue.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
;
import
java.util.PriorityQueue
;
import
mvd.jester.priority.PriorityManager
;
import
mvd.jester.simulator.model.ExtendedSubtaskContext
;
public
class
WaitQueue
extends
PriorityQueue
<
ExtendedSubtaskContext
>
{
private
static
final
long
serialVersionUID
=
-
4968780596887106984L
;
public
WaitQueue
(
PriorityManager
priorityManager
)
{
super
((
jc1
,
jc2
)
->
priorityManager
.
compare
(
jc1
.
getJobContext
(),
jc2
.
getJobContext
()));
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/AbstractContextEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
mvd.jester.simulator.model.ExtendedSubtaskContext
;
import
mvd.jester.simulator.model.JobContext
;
public
abstract
class
AbstractContextEvent
extends
AbstractSubtaskEvent
implements
ISubtaskEvent
{
private
final
ExtendedSubtaskContext
subtask
;
protected
AbstractContextEvent
(
EventType
type
,
long
time
,
ExtendedSubtaskContext
subtask
,
JobContext
jobContext
)
{
super
(
type
,
time
,
jobContext
);
this
.
subtask
=
subtask
;
}
@Override
public
ExtendedSubtaskContext
getSubtaskContext
()
{
return
subtask
;
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/AbstractEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
public
abstract
class
AbstractEvent
implements
IEvent
{
private
final
EventType
type
;
private
final
long
time
;
protected
AbstractEvent
(
EventType
type
,
long
time
)
{
this
.
type
=
type
;
this
.
time
=
time
;
}
@Override
public
long
getTime
()
{
return
time
;
}
@Override
public
EventType
getType
()
{
return
type
;
}
@Override
public
final
void
log
()
{
System
.
out
.
printf
(
"[%19s] > %s\n"
,
getTime
(),
getLoggingMessage
());
}
protected
abstract
String
getLoggingMessage
();
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/AbstractSubtaskEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
mvd.jester.simulator.model.JobContext
;
public
abstract
class
AbstractSubtaskEvent
extends
AbstractEvent
{
private
final
JobContext
jobContext
;
protected
AbstractSubtaskEvent
(
EventType
type
,
long
time
,
JobContext
job
)
{
super
(
type
,
time
);
this
.
jobContext
=
job
;
}
/**
* @return the jobContext
*/
public
JobContext
getJobContext
()
{
return
jobContext
;
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/EventQueue.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
java.util.Comparator
;
import
java.util.PriorityQueue
;
import
mvd.jester.priority.PriorityManager
;
public
class
EventQueue
extends
PriorityQueue
<
IEvent
>
{
/**
*
*/
private
static
final
long
serialVersionUID
=
-
6221675577222053574L
;
public
EventQueue
(
final
PriorityManager
priorityManager
)
{
super
(
new
EventComparator
(
priorityManager
));
}
private
static
class
EventComparator
implements
Comparator
<
IEvent
>
{
private
final
PriorityManager
priorityManager
;
private
EventComparator
(
final
PriorityManager
priorityManager
)
{
this
.
priorityManager
=
priorityManager
;
}
/**
* Compare two events. The following comparisons are made: 1. time of the events 2. priority
* of the events (according to the event enumeration order) 3. priority of the jobs
* (according to the scheduling priority policy)
*
* @param e1 The first event.
* @param e2 The second event.
* @return 0 if events are considered equivalent, negative number if the first event is
* prior to the second one and positive number if the first event is after the
* second one.
*/
@Override
public
int
compare
(
final
IEvent
e1
,
final
IEvent
e2
)
{
final
long
timeDiff
=
e1
.
getTime
()
-
e2
.
getTime
();
if
(
timeDiff
!=
0
)
{
return
(
int
)
timeDiff
;
}
final
int
ordDiff
=
e1
.
getType
().
ordinal
()
-
e2
.
getType
().
ordinal
();
if
(
ordDiff
!=
0
)
{
return
ordDiff
;
}
if
(!(
e1
instanceof
ISubtaskEvent
&&
e2
instanceof
ISubtaskEvent
))
{
return
0
;
}
return
priorityManager
.
compare
(((
ISubtaskEvent
)
e1
).
getJobContext
(),
((
ISubtaskEvent
)
e2
).
getJobContext
());
}
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/EventType.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
public
enum
EventType
{
TASK_RELEASED
,
JOB_COMPLETED
,
JOB_ACTIVATED
,
SUBTASK_CHECK_COMPLETED
,
SUBTASK_PREEMPTED
,
SUBTASK_COMPLETED
,
SUBTASK_STOPPED
,
SUBTASK_STARTED
,
SUBTASK_ACTIVATED
;
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/IEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
public
interface
IEvent
{
long
getTime
();
EventType
getType
();
void
log
();
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/ISubtaskEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
mvd.jester.simulator.model.ExtendedSubtaskContext
;
import
mvd.jester.simulator.model.JobContext
;
public
interface
ISubtaskEvent
extends
IEvent
{
public
ExtendedSubtaskContext
getSubtaskContext
();
public
JobContext
getJobContext
();
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/JobActivatedEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
mvd.jester.simulator.model.JobContext
;
public
class
JobActivatedEvent
extends
AbstractEvent
{
private
JobContext
job
;
public
JobActivatedEvent
(
long
time
,
JobContext
job
)
{
super
(
EventType
.
JOB_ACTIVATED
,
time
);
this
.
job
=
job
;
}
/**
* @return the job
*/
public
JobContext
getJobContext
()
{
return
job
;
}
@Override
protected
String
getLoggingMessage
()
{
return
"Job "
+
job
+
" released"
;
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/JobCompletedEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
mvd.jester.simulator.model.JobContext
;
public
class
JobCompletedEvent
extends
AbstractEvent
{
private
JobContext
job
;
public
JobCompletedEvent
(
long
time
,
JobContext
job
)
{
super
(
EventType
.
JOB_COMPLETED
,
time
);
this
.
job
=
job
;
}
/**
* @return the job
*/
public
JobContext
getJobContext
()
{
return
job
;
}
@Override
protected
String
getLoggingMessage
()
{
return
"Job "
+
job
+
" completed"
;
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/SubtaskActivatedEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
mvd.jester.model.Subtask
;
import
mvd.jester.simulator.model.JobContext
;
public
class
SubtaskActivatedEvent
extends
AbstractEvent
{
private
final
JobContext
job
;
private
final
Subtask
subtask
;
public
SubtaskActivatedEvent
(
final
long
time
,
final
JobContext
job
,
final
Subtask
subtask
)
{
super
(
EventType
.
SUBTASK_ACTIVATED
,
time
);
this
.
job
=
job
;
this
.
subtask
=
subtask
;
}
/**
* @return the job
*/
public
JobContext
getJobContext
()
{
return
job
;
}
/**
* @return the subtask
*/
public
Subtask
getSubtask
()
{
return
subtask
;
}
@Override
protected
String
getLoggingMessage
()
{
return
"Subtask "
+
getSubtask
()
+
" released"
;
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/SubtaskCheckCompletedEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
mvd.jester.simulator.model.ExtendedSubtaskContext
;
import
mvd.jester.simulator.model.ProcessorContext
;
public
class
SubtaskCheckCompletedEvent
extends
AbstractContextEvent
{
private
final
ProcessorContext
processor
;
public
SubtaskCheckCompletedEvent
(
final
long
time
,
final
ExtendedSubtaskContext
subtask
,
final
ProcessorContext
processor
)
{
super
(
EventType
.
SUBTASK_CHECK_COMPLETED
,
time
,
subtask
,
subtask
.
getJobContext
());
this
.
processor
=
processor
;
}
/**
* @return the processor
*/
public
ProcessorContext
getProcessor
()
{
return
processor
;
}
@Override
protected
String
getLoggingMessage
()
{
return
"Subtask "
+
getSubtaskContext
()
+
" maybe completed on "
+
getProcessor
();
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/SubtaskCompletedEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
mvd.jester.simulator.model.ExtendedSubtaskContext
;
public
class
SubtaskCompletedEvent
extends
AbstractContextEvent
{
public
SubtaskCompletedEvent
(
long
time
,
ExtendedSubtaskContext
subtask
)
{
super
(
EventType
.
SUBTASK_COMPLETED
,
time
,
subtask
,
subtask
.
getJobContext
());
}
@Override
protected
String
getLoggingMessage
()
{
return
"Subtask "
+
getSubtaskContext
()
+
" completed"
;
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/SubtaskPreemptedEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
mvd.jester.simulator.model.ExtendedSubtaskContext
;
import
mvd.jester.simulator.model.ProcessorContext
;
public
class
SubtaskPreemptedEvent
extends
AbstractContextEvent
{
private
ProcessorContext
processor
;
private
ExtendedSubtaskContext
nextSubtask
;
public
SubtaskPreemptedEvent
(
long
time
,
ExtendedSubtaskContext
subtask
,
ProcessorContext
processor
,
ExtendedSubtaskContext
nextSubtask
)
{
super
(
EventType
.
SUBTASK_PREEMPTED
,
time
,
subtask
,
subtask
.
getJobContext
());
this
.
processor
=
processor
;
this
.
nextSubtask
=
nextSubtask
;
}
/**
* @return the processor
*/
public
ProcessorContext
getProcessor
()
{
return
processor
;
}
/**
* @return the nextSubtask
*/
public
ExtendedSubtaskContext
getNextSubtask
()
{
return
nextSubtask
;
}
@Override
protected
String
getLoggingMessage
()
{
return
"Subtask "
+
getSubtaskContext
()
+
" preempted by "
+
getNextSubtask
();
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/SubtaskStartedEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
mvd.jester.simulator.model.ExtendedSubtaskContext
;
import
mvd.jester.simulator.model.ProcessorContext
;
public
class
SubtaskStartedEvent
extends
AbstractContextEvent
{
private
final
ProcessorContext
processor
;
public
SubtaskStartedEvent
(
final
long
time
,
final
ExtendedSubtaskContext
subtask
,
final
ProcessorContext
processor
)
{
super
(
EventType
.
SUBTASK_STARTED
,
time
,
subtask
,
subtask
.
getJobContext
());
this
.
processor
=
processor
;
}
/**
* @return the processor
*/
public
ProcessorContext
getProcessor
()
{
return
processor
;
}
@Override
protected
String
getLoggingMessage
()
{
return
"Subtask "
+
getSubtaskContext
()
+
" started execution on "
+
getProcessor
();
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/SubtaskStoppedEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
mvd.jester.simulator.model.ExtendedSubtaskContext
;
import
mvd.jester.simulator.model.ProcessorContext
;
public
class
SubtaskStoppedEvent
extends
AbstractContextEvent
{
private
ProcessorContext
processor
;
public
SubtaskStoppedEvent
(
long
time
,
ExtendedSubtaskContext
subtask
,
ProcessorContext
processor
)
{
super
(
EventType
.
SUBTASK_STOPPED
,
time
,
subtask
,
subtask
.
getJobContext
());
this
.
processor
=
processor
;
}
/**
* @return the processor
*/
public
ProcessorContext
getProcessor
()
{
return
processor
;
}
@Override
protected
String
getLoggingMessage
()
{
return
"Subtask "
+
getSubtaskContext
()
+
" stopped on "
+
getProcessor
();
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/events/TaskReleasedEvent.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
events
;
import
mvd.jester.model.DagTask
;
public
class
TaskReleasedEvent
extends
AbstractEvent
{
private
final
DagTask
task
;
public
TaskReleasedEvent
(
long
time
,
DagTask
task
)
{
super
(
EventType
.
TASK_RELEASED
,
time
);
this
.
task
=
task
;
}
public
DagTask
getTask
()
{
return
task
;
}
@Override
public
String
getLoggingMessage
()
{
return
"task "
+
getTask
()
+
" started"
;
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/exceptions/DeadlineMissedException.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
exceptions
;
public
class
DeadlineMissedException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
-
7635316944888221110L
;
public
DeadlineMissedException
(
String
message
)
{
super
(
message
);
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/exceptions/ExecutionOverrunException.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
exceptions
;
public
class
ExecutionOverrunException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
-
899332907791579362L
;
public
ExecutionOverrunException
(
String
message
)
{
super
(
message
);
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/exceptions/SchedulingException.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
exceptions
;
public
class
SchedulingException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
-
7851284137097347264L
;
public
SchedulingException
(
String
message
)
{
super
(
message
);
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/internals/JobContextInterface.java
deleted
100644 → 0
View file @
cfdd3254
package
mvd
.
jester
.
simulator
.
internals
;
import
java.util.Optional
;
/**
* JobContextInterface
*/
public
interface
JobContextInterface
{
public
Optional
<
TaskContextInterface
>
updateExecution
(
long
time
);
public
boolean
checkExecutionTime
();
public
void
setCurrentProcessor
(
ProcessorContext
processor
);
public
Optional
<
ProcessorContext
>
getCurrentProcessor
();
public
TaskContextInterface
getTaskContext
();
public
boolean
prepareJob
(
long
time
);
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/internals/ProcessorContext.java
deleted
100644 → 0
View file @
cfdd3254
package
mvd
.
jester
.
simulator
.
internals
;
import
java.util.Optional
;
import
mvd.jester.simulator.EventPrinter
;
/**
* Processor
*/
public
class
ProcessorContext
{
private
Optional
<
JobContextInterface
>
currentJob
;
private
final
long
processorId
;
public
ProcessorContext
(
long
processorId
)
{
currentJob
=
Optional
.
empty
();
this
.
processorId
=
processorId
;
}
public
void
setJob
(
JobContextInterface
job
)
{
this
.
currentJob
=
Optional
.
ofNullable
(
job
);
}
/**
* @return the currentJob
*/
public
Optional
<
JobContextInterface
>
getJob
()
{
return
currentJob
;
}
public
Optional
<
TaskContextInterface
>
updateExecution
(
long
time
)
{
if
(
currentJob
.
isPresent
())
{
return
currentJob
.
get
().
updateExecution
(
time
);
}
return
Optional
.
empty
();
}
public
boolean
acceptTask
(
TaskContextInterface
taskContext
,
int
t
)
{
if
(!
currentJob
.
isPresent
()
||
currentJob
.
get
().
getTaskContext
().
getTask
()
.
getPeriod
()
>
taskContext
.
getTask
().
getPeriod
())
{
Optional
<
JobContextInterface
>
optionalJob
=
taskContext
.
getNextJob
();
if
(
optionalJob
.
isPresent
())
{
if
(!
optionalJob
.
get
().
prepareJob
(
t
))
{
return
false
;
}
if
(
currentJob
.
isPresent
())
{
currentJob
.
get
().
setCurrentProcessor
(
null
);
}
currentJob
=
optionalJob
;
currentJob
.
get
().
setCurrentProcessor
(
this
);
EventPrinter
.
print
(
"Time "
+
t
+
": "
+
this
+
" started job "
+
currentJob
.
get
()
+
"!"
);
return
true
;
}
}
return
false
;
}
@Override
public
String
toString
()
{
return
"Processor "
+
processorId
;
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/internals/SortedTaskContextSet.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
internals
;
//
package mvd.jester.simulator.internals;
import
java.util.TreeSet
;
import
mvd.jester.priority.PriorityManager
;
//
import java.util.TreeSet;
//
import mvd.jester.priority.PriorityManager;
/**
* SortedTaskContextSet
*/
public
class
SortedTaskContextSet
extends
TreeSet
<
TaskContextInterface
>
{
/
/ /
**
//
* SortedTaskContextSet
//
*/
// public class SortedTaskContextSet extends TreeSet<ITaskContext
> {
private
static
final
long
serialVersionUID
=
4808544133562675597L
;
//
private static final long serialVersionUID = 4808544133562675597L;
public
SortedTaskContextSet
(
PriorityManager
priorityMananger
)
{
super
((
t1
,
t2
)
->
priorityMananger
.
compare
(
t1
,
t2
));
}
}
//
public SortedTaskContextSet(PriorityManager priorityMananger) {
//
super((t1, t2) -> priorityMananger.compare(t1, t2));
//
}
//
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/internals/dynamicforkjoin/JobContext.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
internals
.
dynamicforkjoin
;
import
java.util.Optional
;
import
mvd.jester.simulator.EventPrinter
;
import
mvd.jester.simulator.internals.JobContextInterface
;
import
mvd.jester.simulator.internals.ProcessorContext
;
import
mvd.jester.simulator.internals.TaskContextInterface
;
/**
* Job
*
* @param <Job>
*/
public
class
JobContext
implements
JobContextInterface
{
private
final
TaskContext
taskContext
;
private
final
SegmentContext
segmentContext
;
private
final
long
wcet
;
private
Optional
<
ProcessorContext
>
currentProcessor
;
private
Optional
<
TaskletContext
>
currentTasklet
;
public
JobContext
(
TaskContext
taskContext
,
SegmentContext
segmentContext
)
{
this
.
currentProcessor
=
Optional
.
empty
();
this
.
currentTasklet
=
Optional
.
empty
();
this
.
taskContext
=
taskContext
;
this
.
segmentContext
=
segmentContext
;
this
.
wcet
=
segmentContext
.
getSegment
().
getJobWcet
();
}
public
Optional
<
TaskContextInterface
>
updateExecution
(
long
time
)
{
boolean
jobIsIdle
=
true
;
if
(
currentTasklet
.
isPresent
())
{
jobIsIdle
=
currentTasklet
.
get
().
updateExecution
(
time
);
}
if
(
jobIsIdle
)
{
currentTasklet
=
segmentContext
.
getNextTasklet
();
Optional
<
TaskContextInterface
>
tc
=
taskContext
.
acceptNotification
(
time
);
if
(
currentTasklet
.
isPresent
())
{
EventPrinter
.
print
(
"Time "
+
time
+
": Job "
+
this
+
" started executing tasklet "
+
currentTasklet
.
get
()
+
" on Processor "
+
currentProcessor
.
get
());
currentTasklet
.
get
().
setCurrentJob
(
this
);
}
else
{
if
(
currentProcessor
.
isPresent
())
{
currentProcessor
.
get
().
setJob
(
null
);
}
currentProcessor
=
Optional
.
empty
();
return
tc
;
}
}
return
Optional
.
empty
();
}
public
boolean
checkExecutionTime
()
{
if
(
currentTasklet
.
isPresent
())
{
return
currentTasklet
.
get
().
checkExecutionTime
();
}
return
false
;
}
/**
* @return the wcet
*/
public
long
getWcet
()
{
return
wcet
;
}
/**
* @param processor the currentProcessor to set
*/
public
void
setCurrentProcessor
(
ProcessorContext
processor
)
{
this
.
currentProcessor
=
Optional
.
ofNullable
(
processor
);
}
/**
* @return the currentProcessor
*/
public
Optional
<
ProcessorContext
>
getCurrentProcessor
()
{
return
currentProcessor
;
}
/**
* @param currentTasklet the currentTasklet to set
*/
public
void
setCurrentTasklet
(
TaskletContext
currentTasklet
)
{
this
.
currentTasklet
=
Optional
.
ofNullable
(
currentTasklet
);
}
/**
* @return the segmentContext
*/
public
SegmentContext
getSegmentContext
()
{
return
segmentContext
;
}
/**
* @return the taskContext
*/
public
TaskContext
getTaskContext
()
{
return
taskContext
;
}
@Override
public
String
toString
()
{
return
"(of task="
+
taskContext
+
")"
;
}
@Override
public
boolean
prepareJob
(
long
time
)
{
if
(!
currentTasklet
.
isPresent
())
{
currentTasklet
=
segmentContext
.
getNextTasklet
();
if
(
currentTasklet
.
isPresent
())
{
currentTasklet
.
get
().
setCurrentJob
(
this
);
// EventPrinter.print("Time " + time + ": Job " + this + " started executing
// tasklet"
// + currentTasklet.get());
return
true
;
}
else
{
return
false
;
}
}
return
true
;
}
}
//
package mvd.jester.simulator.internals.dynamicforkjoin;
//
import java.util.Optional;
//
import mvd.jester.simulator.EventPrinter;
// import mvd.jester.simulator.internals.ISubtaskContext
;
//
import mvd.jester.simulator.internals.ProcessorContext;
// import mvd.jester.simulator.internals.ITaskContext
;
/
/ /
**
//
* Job
// *
//
* @param <Job>
//
*/
// public class JobContext implements ISubtaskContext
{
//
private final TaskContext taskContext;
//
private final SegmentContext segmentContext;
//
private final long wcet;
//
private Optional<ProcessorContext> currentProcessor;
//
private Optional<TaskletContext> currentTasklet;
//
public JobContext(TaskContext taskContext, SegmentContext segmentContext) {
//
this.currentProcessor = Optional.empty();
//
this.currentTasklet = Optional.empty();
//
this.taskContext = taskContext;
//
this.segmentContext = segmentContext;
//
this.wcet = segmentContext.getSegment().getJobWcet();
//
}
// public Optional<ITaskContext
> updateExecution(long time) {
//
boolean jobIsIdle = true;
//
if (currentTasklet.isPresent()) {
//
jobIsIdle = currentTasklet.get().updateExecution(time);
//
}
//
if (jobIsIdle) {
//
currentTasklet = segmentContext.getNextTasklet();
// Optional<ITaskContext
> tc = taskContext.acceptNotification(time);
//
if (currentTasklet.isPresent()) {
//
EventPrinter.print("Time " + time + ": Job " + this + " started executing tasklet "
//
+ currentTasklet.get() + " on Processor " + currentProcessor.get());
//
currentTasklet.get().setCurrentJob(this);
//
} else {
//
if (currentProcessor.isPresent()) {
//
currentProcessor.get().setJob(null);
//
}
//
currentProcessor = Optional.empty();
//
return tc;
//
}
//
}
//
return Optional.empty();
//
}
//
public boolean checkExecutionTime() {
//
if (currentTasklet.isPresent()) {
//
return currentTasklet.get().checkExecutionTime();
//
}
//
return false;
//
}
//
/**
//
* @return the wcet
//
*/
//
public long getWcet() {
//
return wcet;
//
}
//
/**
//
* @param processor the currentProcessor to set
//
*/
//
public void setCurrentProcessor(ProcessorContext processor) {
//
this.currentProcessor = Optional.ofNullable(processor);
//
}
//
/**
//
* @return the currentProcessor
//
*/
//
public Optional<ProcessorContext> getCurrentProcessor() {
//
return currentProcessor;
//
}
//
/**
//
* @param currentTasklet the currentTasklet to set
//
*/
//
public void setCurrentTasklet(TaskletContext currentTasklet) {
//
this.currentTasklet = Optional.ofNullable(currentTasklet);
//
}
//
/**
//
* @return the segmentContext
//
*/
//
public SegmentContext getSegmentContext() {
//
return segmentContext;
//
}
//
/**
//
* @return the taskContext
//
*/
//
public TaskContext getTaskContext() {
//
return taskContext;
//
}
//
@Override
//
public String toString() {
//
return "(of task=" + taskContext + ")";
//
}
//
@Override
//
public boolean prepareJob(long time) {
//
if (!currentTasklet.isPresent()) {
//
currentTasklet = segmentContext.getNextTasklet();
//
if (currentTasklet.isPresent()) {
//
currentTasklet.get().setCurrentJob(this);
//
// EventPrinter.print("Time " + time + ": Job " + this + " started executing
//
// tasklet"
//
// + currentTasklet.get());
//
return true;
//
} else {
//
return false;
//
}
//
}
//
return true;
//
}
//
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/internals/dynamicforkjoin/SegmentContext.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
internals
.
dynamicforkjoin
;
import
java.util.HashSet
;
import
java.util.Optional
;
import
java.util.Set
;
import
mvd.jester.model.Segment
;
import
mvd.jester.simulator.internals.JobContextInterface
;
/**
* Segment
*/
public
class
SegmentContext
{
private
final
Segment
segment
;
private
final
Set
<
JobContextInterface
>
jobs
;
private
final
Set
<
TaskletContext
>
tasklets
;
public
SegmentContext
(
TaskContext
taskContext
,
Segment
segment
,
long
numberOfProcessors
)
{
this
.
segment
=
segment
;
jobs
=
new
HashSet
<>();
tasklets
=
new
HashSet
<>();
long
numberOfJobs
=
segment
.
getNumberOfJobs
()
>
numberOfProcessors
?
numberOfProcessors
:
segment
.
getNumberOfJobs
();
for
(
int
j
=
0
;
j
<
numberOfJobs
;
++
j
)
{
jobs
.
add
(
new
JobContext
(
taskContext
,
this
));
}
// for (int j = 0; j < segment.getNumberOfTasklets(); ++j) {
// tasklets.add(new TaskletContext(taskContext, this));
// }
}
/**
* @return the segment
*/
public
Segment
getSegment
()
{
return
segment
;
}
public
long
getNumberOfJobs
()
{
return
jobs
.
size
();
}
public
Optional
<
JobContextInterface
>
getNextJob
()
{
boolean
taskletAvailable
=
tasklets
.
stream
()
.
anyMatch
(
t
->
!
t
.
getCurrentJob
().
isPresent
()
&&
t
.
checkExecutionTime
());
boolean
jobNotFinished
=
jobs
.
stream
()
.
anyMatch
(
j
->
!
j
.
getCurrentProcessor
().
isPresent
()
&&
j
.
checkExecutionTime
());
if
(
jobNotFinished
)
{
return
jobs
.
stream
()
.
filter
(
j
->
!
j
.
getCurrentProcessor
().
isPresent
()
&&
j
.
checkExecutionTime
())
.
findFirst
();
}
else
if
(
taskletAvailable
)
{
return
jobs
.
stream
()
.
filter
(
j
->
!
j
.
getCurrentProcessor
().
isPresent
()
&&
!
j
.
checkExecutionTime
())
.
findFirst
();
}
else
{
return
Optional
.
empty
();
}
}
public
Optional
<
TaskletContext
>
getNextTasklet
()
{
return
tasklets
.
stream
()
.
filter
(
t
->
!
t
.
getCurrentJob
().
isPresent
()
&&
t
.
checkExecutionTime
()).
findFirst
();
}
@Override
public
String
toString
()
{
return
"something"
;
// return "(nJobs=" + segment.getNumberOfJobs() + ", nTasklets="
// + segment.getNumberOfTasklets() + ", taskletWcet=" + segment.getTaskletWcet() + ")";
}
}
//
package mvd.jester.simulator.internals.dynamicforkjoin;
//
import java.util.HashSet;
//
import java.util.Optional;
//
import java.util.Set;
//
import mvd.jester.model.Segment;
// import mvd.jester.simulator.internals.ISubtaskContext
;
/
/ /
**
//
* Segment
//
*/
//
public class SegmentContext {
//
private final Segment segment;
// private final Set<ISubtaskContext
> jobs;
//
private final Set<TaskletContext> tasklets;
//
public SegmentContext(TaskContext taskContext, Segment segment, long numberOfProcessors) {
//
this.segment = segment;
//
jobs = new HashSet<>();
//
tasklets = new HashSet<>();
//
long numberOfJobs = segment.getNumberOfJobs() > numberOfProcessors ? numberOfProcessors
//
: segment.getNumberOfJobs();
//
for (int j = 0; j < numberOfJobs; ++j) {
//
jobs.add(new JobContext(taskContext, this));
//
}
//
// for (int j = 0; j < segment.getNumberOfTasklets(); ++j) {
//
// tasklets.add(new TaskletContext(taskContext, this));
//
// }
//
}
//
/**
//
* @return the segment
//
*/
//
public Segment getSegment() {
//
return segment;
//
}
//
public long getNumberOfJobs() {
//
return jobs.size();
//
}
// public Optional<ISubtaskContext
> getNextJob() {
//
boolean taskletAvailable = tasklets.stream()
//
.anyMatch(t -> !t.getCurrentJob().isPresent() && t.checkExecutionTime());
//
boolean jobNotFinished = jobs.stream()
//
.anyMatch(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime());
//
if (jobNotFinished) {
//
return jobs.stream()
//
.filter(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime())
//
.findFirst();
//
} else if (taskletAvailable) {
//
return jobs.stream()
//
.filter(j -> !j.getCurrentProcessor().isPresent() && !j.checkExecutionTime())
//
.findFirst();
//
} else {
//
return Optional.empty();
//
}
//
}
//
public Optional<TaskletContext> getNextTasklet() {
//
return tasklets.stream()
//
.filter(t -> !t.getCurrentJob().isPresent() && t.checkExecutionTime()).findFirst();
//
}
//
@Override
//
public String toString() {
//
return "something";
//
// return "(nJobs=" + segment.getNumberOfJobs() + ", nTasklets="
//
// + segment.getNumberOfTasklets() + ", taskletWcet=" + segment.getTaskletWcet() + ")";
//
}
//
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/internals/dynamicforkjoin/TaskContext.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
internals
.
dynamicforkjoin
;
import
java.util.ArrayList
;
import
java.util.Optional
;
import
mvd.jester.model.Segment
;
import
mvd.jester.model.SynchronousTask
;
import
mvd.jester.simulator.EventPrinter
;
import
mvd.jester.simulator.internals.JobContextInterface
;
import
mvd.jester.simulator.internals.TaskContextInterface
;
/**
* TaskContext
*/
public
class
TaskContext
implements
TaskContextInterface
{
private
final
SynchronousTask
task
;
private
final
ArrayList
<
SegmentContext
>
segments
;
private
final
long
releaseTime
;
private
final
long
deadline
;
private
int
currentSegment
;
private
int
segmentCounter
;
public
TaskContext
(
SynchronousTask
task
,
long
numberOfProcessors
,
long
releaseTime
)
{
this
.
task
=
task
;
this
.
segments
=
new
ArrayList
<>();
this
.
currentSegment
=
0
;
this
.
segmentCounter
=
0
;
this
.
deadline
=
releaseTime
+
task
.
getDeadline
();
this
.
releaseTime
=
releaseTime
;
for
(
Segment
s
:
task
.
getWorkloadDistribution
())
{
segments
.
add
(
new
SegmentContext
(
this
,
s
,
numberOfProcessors
));
}
}
/**
* @return the task
*/
public
SynchronousTask
getTask
()
{
return
task
;
}
/**
* @return the deadline
*/
@Override
public
long
getDeadline
()
{
return
deadline
;
}
@Override
public
long
getReleaseTime
()
{
return
releaseTime
;
}
public
Optional
<
TaskContextInterface
>
acceptNotification
(
long
time
)
{
segmentCounter
++;
// if (segmentCounter >= segments.get(currentSegment).getSegment().getNumberOfTasklets()) {
// currentSegment++;
// segmentCounter = 0;
// if (currentSegment >= segments.size()) {
// EventPrinter.print("Time " + time + ": Task " + this + "finished!");
// return Optional.of(this);
// }
// }
return
Optional
.
empty
();
}
public
Optional
<
JobContextInterface
>
getNextJob
()
{
if
(
currentSegment
<
segments
.
size
())
{
return
segments
.
get
(
currentSegment
).
getNextJob
();
}
return
Optional
.
empty
();
}
@Override
public
String
toString
()
{
return
"(period="
+
task
.
getPeriod
()
+
", deadline="
+
deadline
+
", segments="
+
segments
.
size
()
+
")"
;
}
}
//
package mvd.jester.simulator.internals.dynamicforkjoin;
//
import java.util.ArrayList;
//
import java.util.Optional;
//
import mvd.jester.model.Segment;
//
import mvd.jester.model.SynchronousTask;
//
import mvd.jester.simulator.EventPrinter;
// import mvd.jester.simulator.internals.ISubtaskContext
;
// import mvd.jester.simulator.internals.ITaskContext
;
/
/ /
**
//
* TaskContext
//
*/
// public class TaskContext implements ITaskContext
{
//
private final SynchronousTask task;
//
private final ArrayList<SegmentContext> segments;
//
private final long releaseTime;
//
private final long deadline;
//
private int currentSegment;
//
private int segmentCounter;
//
public TaskContext(SynchronousTask task, long numberOfProcessors, long releaseTime) {
//
this.task = task;
//
this.segments = new ArrayList<>();
//
this.currentSegment = 0;
//
this.segmentCounter = 0;
//
this.deadline = releaseTime + task.getDeadline();
//
this.releaseTime = releaseTime;
//
for (Segment s : task.getWorkloadDistribution()) {
//
segments.add(new SegmentContext(this, s, numberOfProcessors));
//
}
//
}
//
/**
//
* @return the task
//
*/
//
public SynchronousTask getTask() {
//
return task;
//
}
//
/**
//
* @return the deadline
//
*/
//
@Override
//
public long getDeadline() {
//
return deadline;
//
}
//
@Override
//
public long getReleaseTime() {
//
return releaseTime;
//
}
// public Optional<ITaskContext
> acceptNotification(long time) {
//
segmentCounter++;
//
// if (segmentCounter >= segments.get(currentSegment).getSegment().getNumberOfTasklets()) {
//
// currentSegment++;
//
// segmentCounter = 0;
//
// if (currentSegment >= segments.size()) {
//
// EventPrinter.print("Time " + time + ": Task " + this + "finished!");
//
// return Optional.of(this);
//
// }
//
// }
//
return Optional.empty();
//
}
// public Optional<ISubtaskContext
> getNextJob() {
//
if (currentSegment < segments.size()) {
//
return segments.get(currentSegment).getNextJob();
//
}
//
return Optional.empty();
//
}
//
@Override
//
public String toString() {
//
return "(period=" + task.getPeriod() + ", deadline=" + deadline + ", segments="
//
+ segments.size() + ")";
//
}
//
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/internals/dynamicforkjoin/TaskletContext.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
internals
.
dynamicforkjoin
;
import
java.util.Optional
;
/**
* Tasklet
*/
public
class
TaskletContext
{
private
final
TaskContext
taskContext
;
private
Optional
<
JobContext
>
currentJob
;
private
final
long
wcet
;
private
long
executionTime
;
public
TaskletContext
(
TaskContext
taskContext
,
SegmentContext
segment
)
{
this
.
taskContext
=
taskContext
;
this
.
wcet
=
88
;
// segment.getSegment().getTaskletWcet();
this
.
executionTime
=
wcet
;
currentJob
=
Optional
.
empty
();
}
/**
* @return the currentJob
*/
public
Optional
<
JobContext
>
getCurrentJob
()
{
return
currentJob
;
}
public
void
setCurrentJob
(
JobContext
jobContext
)
{
currentJob
=
Optional
.
ofNullable
(
jobContext
);
}
/**
* @return true if tasklet finished, false otherwise
*/
public
boolean
updateExecution
(
long
time
)
{
executionTime
--;
if
(
executionTime
==
0
)
{
if
(
currentJob
.
isPresent
())
{
currentJob
.
get
().
setCurrentTasklet
(
null
);
}
currentJob
=
Optional
.
empty
();
return
true
;
}
else
if
(
executionTime
<
0
)
{
throw
new
RuntimeException
(
"Tasklet was executed for longer than its WCET!"
);
}
return
false
;
}
public
boolean
checkExecutionTime
()
{
return
executionTime
>
0
;
}
@Override
public
String
toString
()
{
return
"(wcet="
+
wcet
+
", task="
+
taskContext
+
")"
;
}
}
//
package mvd.jester.simulator.internals.dynamicforkjoin;
//
import java.util.Optional;
/
/ /
**
//
* Tasklet
//
*/
//
public class TaskletContext {
//
private final TaskContext taskContext;
//
private Optional<JobContext> currentJob;
//
private final long wcet;
//
private long executionTime;
//
public TaskletContext(TaskContext taskContext, SegmentContext segment) {
//
this.taskContext = taskContext;
//
this.wcet = 88;
//
// segment.getSegment().getTaskletWcet();
//
this.executionTime = wcet;
//
currentJob = Optional.empty();
//
}
//
/**
//
* @return the currentJob
//
*/
//
public Optional<JobContext> getCurrentJob() {
//
return currentJob;
//
}
//
public void setCurrentJob(JobContext jobContext) {
//
currentJob = Optional.ofNullable(jobContext);
//
}
//
/**
//
* @return true if tasklet finished, false otherwise
//
*/
//
public boolean updateExecution(long time) {
//
executionTime--;
//
if (executionTime == 0) {
//
if (currentJob.isPresent()) {
//
currentJob.get().setCurrentTasklet(null);
//
}
//
currentJob = Optional.empty();
//
return true;
//
} else if (executionTime < 0) {
//
throw new RuntimeException("Tasklet was executed for longer than its WCET!");
//
}
//
return false;
//
}
//
public boolean checkExecutionTime() {
//
return executionTime > 0;
//
}
//
@Override
//
public String toString() {
//
return "(wcet=" + wcet + ", task=" + taskContext + ")";
//
}
//
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/internals/parallelsynchronous/JobContext.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
internals
.
parallelsynchronous
;
import
java.util.Optional
;
import
mvd.jester.simulator.EventPrinter
;
import
mvd.jester.simulator.internals.JobContextInterface
;
import
mvd.jester.simulator.internals.ProcessorContext
;
import
mvd.jester.simulator.internals.TaskContextInterface
;
/**
* Job
*
* @param <Job>
*/
public
class
JobContext
implements
JobContextInterface
{
private
final
TaskContext
taskContext
;
private
final
SegmentContext
segmentContext
;
private
final
long
wcet
;
private
Optional
<
ProcessorContext
>
currentProcessor
;
private
long
executionTime
;
public
JobContext
(
TaskContext
taskContext
,
SegmentContext
segmentContext
)
{
this
.
currentProcessor
=
Optional
.
empty
();
this
.
taskContext
=
taskContext
;
this
.
segmentContext
=
segmentContext
;
this
.
wcet
=
segmentContext
.
getSegment
().
getJobWcet
();
this
.
executionTime
=
wcet
;
}
public
Optional
<
TaskContextInterface
>
updateExecution
(
long
time
)
{
executionTime
--;
if
(
executionTime
==
0
)
{
EventPrinter
.
print
(
"Time "
+
time
+
": "
+
currentProcessor
.
get
()
+
" finished execution of job "
+
this
+
"!"
);
currentProcessor
.
get
().
setJob
(
null
);
currentProcessor
=
Optional
.
empty
();
return
taskContext
.
acceptNotification
(
time
);
}
else
if
(
executionTime
<
0
)
{
throw
new
RuntimeException
(
"Job was executed for longer than its WCET!"
);
}
return
Optional
.
empty
();
}
public
boolean
checkExecutionTime
()
{
return
executionTime
>
0
;
}
/**
* @return the wcet
*/
public
long
getWcet
()
{
return
wcet
;
}
/**
* @param processor the currentProcessor to set
*/
public
void
setCurrentProcessor
(
ProcessorContext
processor
)
{
this
.
currentProcessor
=
Optional
.
ofNullable
(
processor
);
}
/**
* @return the currentProcessor
*/
public
Optional
<
ProcessorContext
>
getCurrentProcessor
()
{
return
currentProcessor
;
}
/**
* @return the segmentContext
*/
public
SegmentContext
getSegmentContext
()
{
return
segmentContext
;
}
/**
* @return the taskContext
*/
public
TaskContext
getTaskContext
()
{
return
taskContext
;
}
@Override
public
String
toString
()
{
return
"(jobWcet="
+
wcet
+
", of task="
+
taskContext
+
")"
;
}
@Override
public
boolean
prepareJob
(
long
time
)
{
return
true
;
}
}
//
package mvd.jester.simulator.internals.parallelsynchronous;
//
import java.util.Optional;
//
import mvd.jester.simulator.EventPrinter;
// import mvd.jester.simulator.internals.ISubtaskContext
;
//
import mvd.jester.simulator.internals.ProcessorContext;
// import mvd.jester.simulator.internals.ITaskContext
;
/
/ /
**
//
* Job
// *
//
* @param <Job>
//
*/
// public class JobContext implements ISubtaskContext
{
//
private final TaskContext taskContext;
//
private final SegmentContext segmentContext;
//
private final long wcet;
//
private Optional<ProcessorContext> currentProcessor;
//
private long executionTime;
//
public JobContext(TaskContext taskContext, SegmentContext segmentContext) {
//
this.currentProcessor = Optional.empty();
//
this.taskContext = taskContext;
//
this.segmentContext = segmentContext;
//
this.wcet = segmentContext.getSegment().getJobWcet();
//
this.executionTime = wcet;
//
}
// public Optional<ITaskContext
> updateExecution(long time) {
//
executionTime--;
//
if (executionTime == 0) {
//
EventPrinter.print("Time " + time + ": " + currentProcessor.get()
//
+ " finished execution of job " + this + "!");
//
currentProcessor.get().setJob(null);
//
currentProcessor = Optional.empty();
//
return taskContext.acceptNotification(time);
//
} else if (executionTime < 0) {
//
throw new RuntimeException("Job was executed for longer than its WCET!");
//
}
//
return Optional.empty();
//
}
//
public boolean checkExecutionTime() {
//
return executionTime > 0;
//
}
//
/**
//
* @return the wcet
//
*/
//
public long getWcet() {
//
return wcet;
//
}
//
/**
//
* @param processor the currentProcessor to set
//
*/
//
public void setCurrentProcessor(ProcessorContext processor) {
//
this.currentProcessor = Optional.ofNullable(processor);
//
}
//
/**
//
* @return the currentProcessor
//
*/
//
public Optional<ProcessorContext> getCurrentProcessor() {
//
return currentProcessor;
//
}
//
/**
//
* @return the segmentContext
//
*/
//
public SegmentContext getSegmentContext() {
//
return segmentContext;
//
}
//
/**
//
* @return the taskContext
//
*/
//
public TaskContext getTaskContext() {
//
return taskContext;
//
}
//
@Override
//
public String toString() {
//
return "(jobWcet=" + wcet + ", of task=" + taskContext + ")";
//
}
//
@Override
//
public boolean prepareJob(long time) {
//
return true;
//
}
//
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/internals/parallelsynchronous/SegmentContext.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
internals
.
parallelsynchronous
;
import
java.util.HashSet
;
import
java.util.Optional
;
import
java.util.Set
;
import
mvd.jester.model.Segment
;
import
mvd.jester.simulator.internals.JobContextInterface
;
/**
* Segment
*/
public
class
SegmentContext
{
private
final
Segment
segment
;
private
final
Set
<
JobContextInterface
>
jobs
;
public
SegmentContext
(
TaskContext
taskContext
,
Segment
segment
)
{
this
.
segment
=
segment
;
jobs
=
new
HashSet
<>();
for
(
int
j
=
0
;
j
<
segment
.
getNumberOfJobs
();
++
j
)
{
jobs
.
add
(
new
JobContext
(
taskContext
,
this
));
}
}
/**
* @return the segment
*/
public
Segment
getSegment
()
{
return
segment
;
}
public
Optional
<
JobContextInterface
>
getNextJob
()
{
return
jobs
.
stream
()
.
filter
(
j
->
!
j
.
getCurrentProcessor
().
isPresent
()
&&
j
.
checkExecutionTime
())
.
findFirst
();
}
@Override
public
String
toString
()
{
return
"(nJobs="
+
segment
.
getNumberOfJobs
()
+
", jobWcet="
+
segment
.
getJobWcet
()
+
")"
;
}
}
//
package mvd.jester.simulator.internals.parallelsynchronous;
//
import java.util.HashSet;
//
import java.util.Optional;
//
import java.util.Set;
//
import mvd.jester.model.Segment;
// import mvd.jester.simulator.internals.ISubtaskContext
;
/
/ /
**
//
* Segment
//
*/
//
public class SegmentContext {
//
private final Segment segment;
// private final Set<ISubtaskContext
> jobs;
//
public SegmentContext(TaskContext taskContext, Segment segment) {
//
this.segment = segment;
//
jobs = new HashSet<>();
//
for (int j = 0; j < segment.getNumberOfJobs(); ++j) {
//
jobs.add(new JobContext(taskContext, this));
//
}
//
}
//
/**
//
* @return the segment
//
*/
//
public Segment getSegment() {
//
return segment;
//
}
// public Optional<ISubtaskContext
> getNextJob() {
//
return jobs.stream()
//
.filter(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime())
//
.findFirst();
//
}
//
@Override
//
public String toString() {
//
return "(nJobs=" + segment.getNumberOfJobs() + ", jobWcet=" + segment.getJobWcet() + ")";
//
}
//
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/internals/parallelsynchronous/TaskContext.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
internals
.
parallelsynchronous
;
import
java.util.ArrayList
;
import
java.util.Optional
;
import
mvd.jester.model.Segment
;
import
mvd.jester.model.SynchronousTask
;
import
mvd.jester.simulator.EventPrinter
;
import
mvd.jester.simulator.internals.JobContextInterface
;
import
mvd.jester.simulator.internals.TaskContextInterface
;
/**
* TaskContext
*/
public
class
TaskContext
implements
TaskContextInterface
{
private
final
SynchronousTask
task
;
private
final
ArrayList
<
SegmentContext
>
segments
;
private
final
long
deadline
;
private
final
long
releaseTime
;
private
int
currentSegment
;
private
int
segmentCounter
;
public
TaskContext
(
SynchronousTask
task
,
long
releaseTime
)
{
this
.
task
=
task
;
this
.
segments
=
new
ArrayList
<>();
this
.
currentSegment
=
0
;
this
.
segmentCounter
=
0
;
this
.
releaseTime
=
releaseTime
;
this
.
deadline
=
releaseTime
+
task
.
getDeadline
();
for
(
Segment
s
:
task
.
getWorkloadDistribution
())
{
segments
.
add
(
new
SegmentContext
(
this
,
s
));
}
}
/**
* @return the task
*/
public
SynchronousTask
getTask
()
{
return
task
;
}
/**
* @return the deadline
*/
@Override
public
long
getDeadline
()
{
return
deadline
;
}
@Override
public
long
getReleaseTime
()
{
return
releaseTime
;
}
public
Optional
<
TaskContextInterface
>
acceptNotification
(
long
time
)
{
segmentCounter
++;
if
(
segmentCounter
>=
segments
.
get
(
currentSegment
).
getSegment
().
getNumberOfJobs
())
{
currentSegment
++;
segmentCounter
=
0
;
if
(
currentSegment
>=
segments
.
size
())
{
EventPrinter
.
print
(
"Time "
+
time
+
": Task "
+
this
+
"finished!"
);
return
Optional
.
of
(
this
);
}
}
return
Optional
.
empty
();
}
public
Optional
<
JobContextInterface
>
getNextJob
()
{
if
(
currentSegment
<
segments
.
size
())
{
return
segments
.
get
(
currentSegment
).
getNextJob
();
}
return
Optional
.
empty
();
}
@Override
public
String
toString
()
{
return
"(period="
+
task
.
getPeriod
()
+
", deadline="
+
deadline
+
", segments="
+
segments
.
size
()
+
")"
;
}
}
//
package mvd.jester.simulator.internals.parallelsynchronous;
//
import java.util.ArrayList;
//
import java.util.Optional;
//
import mvd.jester.model.Segment;
//
import mvd.jester.model.SynchronousTask;
//
import mvd.jester.simulator.EventPrinter;
// import mvd.jester.simulator.internals.ISubtaskContext
;
// import mvd.jester.simulator.internals.ITaskContext
;
/
/ /
**
//
* TaskContext
//
*/
// public class TaskContext implements ITaskContext
{
//
private final SynchronousTask task;
//
private final ArrayList<SegmentContext> segments;
//
private final long deadline;
//
private final long releaseTime;
//
private int currentSegment;
//
private int segmentCounter;
//
public TaskContext(SynchronousTask task, long releaseTime) {
//
this.task = task;
//
this.segments = new ArrayList<>();
//
this.currentSegment = 0;
//
this.segmentCounter = 0;
//
this.releaseTime = releaseTime;
//
this.deadline = releaseTime + task.getDeadline();
//
for (Segment s : task.getWorkloadDistribution()) {
//
segments.add(new SegmentContext(this, s));
//
}
//
}
//
/**
//
* @return the task
//
*/
//
public SynchronousTask getTask() {
//
return task;
//
}
//
/**
//
* @return the deadline
//
*/
//
@Override
//
public long getDeadline() {
//
return deadline;
//
}
//
@Override
//
public long getReleaseTime() {
//
return releaseTime;
//
}
// public Optional<ITaskContext
> acceptNotification(long time) {
//
segmentCounter++;
//
if (segmentCounter >= segments.get(currentSegment).getSegment().getNumberOfJobs()) {
//
currentSegment++;
//
segmentCounter = 0;
//
if (currentSegment >= segments.size()) {
//
EventPrinter.print("Time " + time + ": Task " + this + "finished!");
//
return Optional.of(this);
//
}
//
}
//
return Optional.empty();
//
}
// public Optional<ISubtaskContext
> getNextJob() {
//
if (currentSegment < segments.size()) {
//
return segments.get(currentSegment).getNextJob();
//
}
//
return Optional.empty();
//
}
//
@Override
//
public String toString() {
//
return "(period=" + task.getPeriod() + ", deadline=" + deadline + ", segments="
//
+ segments.size() + ")";
//
}
//
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/model/ExtendedSubtaskContext.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
model
;
import
mvd.jester.model.Subtask
;
import
mvd.jester.model.SubtaskContext
;
public
class
ExtendedSubtaskContext
extends
SubtaskContext
{
private
JobContext
jobContext
;
public
ExtendedSubtaskContext
(
JobContext
jobContext
,
Subtask
subtask
)
{
super
(
subtask
);
this
.
jobContext
=
jobContext
;
}
public
JobContext
getJobContext
()
{
return
jobContext
;
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/model/ISubtaskContext.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
model
;
import
mvd.jester.model.Task
;
/**
* JobContextInterface
*/
public
interface
ISubtaskContext
{
public
void
updateWcet
(
long
time
);
public
Task
getTask
();
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/
internals/TaskContextInterface
.java
→
src/main/java/mvd/jester/simulator/
model/ITaskContext
.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
internals
;
package
mvd
.
jester
.
simulator
.
model
;
import
java.util.Optional
;
import
mvd.jester.model.
Synchronous
Task
;
import
mvd.jester.model.Task
;
/**
* TaskContextInterface
*/
public
interface
TaskContextInterface
{
public
interface
ITaskContext
{
public
Synchronous
Task
getTask
();
public
Task
getTask
();
public
Optional
<
TaskContextInterface
>
acceptNotification
(
long
time
);
public
Optional
<
ITaskContext
>
acceptNotification
(
long
time
);
public
Optional
<
JobContextInterface
>
getNextJob
();
public
Optional
<
ISubtaskContext
>
getNextJob
();
public
boolean
checkRemainingThreads
();
public
long
getDeadline
();
...
...
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/model/JobContext.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
model
;
import
org.jgrapht.experimental.dag.DirectedAcyclicGraph
;
import
org.jgrapht.graph.DefaultEdge
;
import
mvd.jester.model.DagTask
;
import
mvd.jester.model.Subtask
;
public
class
JobContext
{
private
final
DagTask
task
;
private
final
long
releaseTime
;
private
final
long
deadline
;
private
final
Subtask
source
;
// private long activeThreads; // TODO: Use threads
public
JobContext
(
DagTask
task
,
long
releaseTime
)
{
this
.
task
=
task
;
this
.
releaseTime
=
releaseTime
;
this
.
deadline
=
releaseTime
+
task
.
getDeadline
();
this
.
source
=
findSource
(
task
);
// this.activeThreads = task.getNumberOfThreads();
}
private
Subtask
findSource
(
DagTask
task
)
{
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
=
task
.
getJobDag
();
for
(
Subtask
subtask
:
jobDag
)
{
if
(
jobDag
.
inDegreeOf
(
subtask
)
==
0
)
{
return
subtask
;
}
}
throw
new
RuntimeException
(
"No source found in DAG. How can that be!?"
);
}
/**
* @return the task
*/
public
DagTask
getTask
()
{
return
task
;
}
/**
* @return the source
*/
public
Subtask
getSource
()
{
return
source
;
}
/**
* @return the deadline
*/
public
long
getDeadline
()
{
return
deadline
;
}
/**
* @return the releaseTime
*/
public
long
getReleaseTime
()
{
return
releaseTime
;
}
public
boolean
checkRemainingThreads
()
{
return
false
;
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/simulator/model/ProcessorContext.java
0 → 100644
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
model
;
import
java.util.Optional
;
import
mvd.jester.priority.PriorityManager
;
import
mvd.jester.simulator.exceptions.DeadlineMissedException
;
import
mvd.jester.simulator.exceptions.ExecutionOverrunException
;
/**
* Processor
*/
public
class
ProcessorContext
{
private
final
long
processorId
;
private
Optional
<
ExtendedSubtaskContext
>
currentSubtask
;
private
long
lastEventTime
;
public
ProcessorContext
(
long
processorId
)
{
currentSubtask
=
Optional
.
empty
();
this
.
processorId
=
processorId
;
this
.
lastEventTime
=
0
;
}
public
void
setSubtask
(
ExtendedSubtaskContext
subtask
)
{
this
.
currentSubtask
=
Optional
.
ofNullable
(
subtask
);
}
public
boolean
accept
(
ExtendedSubtaskContext
context
,
long
time
)
{
if
(
isIdle
())
{
this
.
currentSubtask
=
Optional
.
of
(
context
);
lastEventTime
=
time
;
return
true
;
}
return
false
;
}
/**
* @return the currentJob
*/
public
Optional
<
ExtendedSubtaskContext
>
getSubtask
()
{
return
currentSubtask
;
}
public
boolean
canAccept
(
ExtendedSubtaskContext
subtaskContext
,
PriorityManager
priorityManager
)
{
if
(
subtaskContext
==
null
)
{
return
false
;
}
if
(
currentSubtask
.
isEmpty
())
{
if
(
subtaskContext
.
getJobContext
().
checkRemainingThreads
())
{
return
true
;
}
return
false
;
}
if
(
priorityManager
.
compare
(
subtaskContext
.
getJobContext
(),
currentSubtask
.
get
().
getJobContext
())
<
0
)
{
return
true
;
}
return
false
;
}
public
void
free
()
{
currentSubtask
=
Optional
.
ofNullable
(
null
);
}
public
boolean
isIdle
()
{
if
(
currentSubtask
.
isEmpty
())
{
return
true
;
}
return
false
;
}
public
void
update
(
long
time
)
{
if
(
currentSubtask
.
isPresent
())
{
currentSubtask
.
get
().
updateRemainingExecutionTime
(
time
-
lastEventTime
);
lastEventTime
=
time
;
long
remainingTime
=
currentSubtask
.
get
().
getRemainingExecutionTime
();
if
(
remainingTime
<
0
)
{
throw
new
ExecutionOverrunException
(
currentSubtask
.
get
().
getJobContext
()
+
" overruns its execution at time "
+
time
+
": "
+
remainingTime
);
}
if
(
time
>
currentSubtask
.
get
().
getJobContext
().
getDeadline
())
{
throw
new
DeadlineMissedException
(
currentSubtask
.
get
().
getJobContext
()
+
" misses its deadline"
);
}
}
}
@Override
public
String
toString
()
{
return
"Processor "
+
processorId
;
}
}
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/tests/FonsecaNelis.java
View file @
36080fd3
...
...
@@ -68,7 +68,8 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
nfjJobDag
=
DagUtils
.
createNFJGraph
(
jobDag
);
final
BinaryDecompositionTree
<
Subtask
>
tree
=
DagUtils
.
createDecompositionTree
(
nfjJobDag
);
final
BinaryDecompositionTree
<
Subtask
>
tree
=
DagUtils
.
createDecompositionTree
(
nfjJobDag
);
carryOutSegments
.
put
(
t
,
constructCarryOutDistribution
(
nfjJobDag
,
tree
));
}
...
...
@@ -83,14 +84,15 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
boolean
isEmpty
=
false
;
do
{
final
Set
<
SubtaskContext
>
parallelJobs
=
getMaximumParallelism
(
modifiedTree
.
getRootNode
());
final
Optional
<
SubtaskContext
>
min
=
parallelJobs
.
stream
().
min
((
p1
,
p2
)
->
Long
.
compare
(
p1
.
getWcet
(),
p2
.
getWcet
()));
final
Set
<
SubtaskContext
>
parallelJobs
=
getMaximumParallelism
(
modifiedTree
.
getRootNode
());
final
Optional
<
SubtaskContext
>
min
=
parallelJobs
.
stream
().
min
((
p1
,
p2
)
->
Long
.
compare
(
p1
.
getRemainingExecutionTime
(),
p2
.
getRemainingExecutionTime
()));
if
(
min
.
isPresent
())
{
final
long
width
=
min
.
get
().
get
Wcet
();
final
long
width
=
min
.
get
().
get
RemainingExecutionTime
();
carryOutWorkload
.
add
(
new
Segment
(
width
,
parallelJobs
.
size
()));
for
(
final
SubtaskContext
p
:
parallelJobs
)
{
p
.
set
Wcet
(
p
.
getWcet
()
-
width
);
p
.
set
RemainingExecutionTime
(
p
.
getRemainingExecutionTime
()
-
width
);
}
}
else
{
break
;
...
...
@@ -104,17 +106,20 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
private
BinaryDecompositionTree
<
SubtaskContext
>
transformTree
(
final
BinaryDecompositionTree
<
Subtask
>
tree
)
{
final
BinaryDecompositionTree
<
SubtaskContext
>
modifiedTree
=
new
BinaryDecompositionTree
<>();
final
BinaryDecompositionTree
<
SubtaskContext
>
modifiedTree
=
new
BinaryDecompositionTree
<>();
final
Node
<
SubtaskContext
>
root
=
transformNode
(
null
,
tree
.
getRootNode
());
modifiedTree
.
setRoot
(
root
);
return
modifiedTree
;
}
private
Node
<
SubtaskContext
>
transformNode
(
final
Node
<
SubtaskContext
>
parent
,
final
Node
<
Subtask
>
node
)
{
private
Node
<
SubtaskContext
>
transformNode
(
final
Node
<
SubtaskContext
>
parent
,
final
Node
<
Subtask
>
node
)
{
if
(
node
.
getNodeType
().
equals
(
NodeType
.
LEAF
))
{
return
new
Node
<
SubtaskContext
>(
parent
,
new
SubtaskContext
(
node
.
getObject
()));
}
else
{
final
Node
<
SubtaskContext
>
modifiedNode
=
new
Node
<
SubtaskContext
>(
parent
,
node
.
getNodeType
());
final
Node
<
SubtaskContext
>
modifiedNode
=
new
Node
<
SubtaskContext
>(
parent
,
node
.
getNodeType
());
modifiedNode
.
setLeftNode
(
transformNode
(
modifiedNode
,
node
.
getLeftNode
()));
modifiedNode
.
setRightNode
(
transformNode
(
modifiedNode
,
node
.
getRightNode
()));
return
modifiedNode
;
...
...
@@ -136,7 +141,7 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
return
right
;
}
}
else
{
if
(
node
.
getObject
().
get
Wcet
()
>
0
)
{
if
(
node
.
getObject
().
get
RemainingExecutionTime
()
>
0
)
{
return
new
HashSet
<>(
Arrays
.
asList
(
node
.
getObject
()));
}
else
{
return
new
HashSet
<>();
...
...
This diff is collapsed.
Click to expand it.
src/test/java/mvd/jester/priority/TestEarliestDeadlineFirst.java
View file @
36080fd3
package
mvd
.
jester
.
priority
;
//
package mvd.jester.priority;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertFalse
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.Test
;
import
mvd.jester.model.SynchronousTask
;
import
mvd.jester.model.SystemManager
;
import
mvd.jester.simulator.DynamicForkJoin
;
import
mvd.jester.simulator.ParallelSynchronous
;
import
mvd.jester.simulator.internals.parallelsynchronous.TaskContext
;
import
mvd.jester.tests.ChwaLee
;
import
mvd.jester.tests.MaiaBertogna
;
import
mvd.jester.tests.SchmidMottok
;
import
mvd.jester.tests.TypeFunction
;
//
import static org.junit.jupiter.api.Assertions.assertFalse;
//
import static org.junit.jupiter.api.Assertions.assertTrue;
//
import static org.mockito.Mockito.mock;
//
import static org.mockito.Mockito.when;
//
import org.junit.jupiter.api.DisplayName;
//
import org.junit.jupiter.api.Test;
//
import mvd.jester.model.SynchronousTask;
//
import mvd.jester.model.SystemManager;
//
import mvd.jester.simulator.DynamicForkJoin;
//
import mvd.jester.simulator.ParallelSynchronous;
//
import mvd.jester.simulator.internals.parallelsynchronous.TaskContext;
//
import mvd.jester.tests.ChwaLee;
//
import mvd.jester.tests.MaiaBertogna;
//
import mvd.jester.tests.SchmidMottok;
//
import mvd.jester.tests.TypeFunction;
/**
* TestEarliestDeadlineFirst
*/
public
class
TestEarliestDeadlineFirst
{
/
/ /
**
//
* TestEarliestDeadlineFirst
//
*/
//
public class TestEarliestDeadlineFirst {
@Test
@DisplayName
(
"Test if priority manager returns the correct priority."
)
public
void
testPriority
()
{
EarliestDeadlineFirst
edf
=
new
EarliestDeadlineFirst
();
//
@Test
//
@DisplayName("Test if priority manager returns the correct priority.")
//
public void testPriority() {
//
EarliestDeadlineFirst edf = new EarliestDeadlineFirst();
SynchronousTask
t1
=
mock
(
SynchronousTask
.
class
);
SynchronousTask
t2
=
mock
(
SynchronousTask
.
class
);
when
(
t1
.
getDeadline
()).
thenReturn
((
long
)
100
);
when
(
t2
.
getDeadline
()).
thenReturn
((
long
)
200
);
//
SynchronousTask t1 = mock(SynchronousTask.class);
//
SynchronousTask t2 = mock(SynchronousTask.class);
//
when(t1.getDeadline()).thenReturn((long) 100);
//
when(t2.getDeadline()).thenReturn((long) 200);
TaskContext
tc1
=
mock
(
TaskContext
.
class
);
TaskContext
tc2
=
mock
(
TaskContext
.
class
);
when
(
tc1
.
getDeadline
()).
thenReturn
((
long
)
100
);
when
(
tc2
.
getDeadline
()).
thenReturn
((
long
)
200
);
//
TaskContext tc1 = mock(TaskContext.class);
//
TaskContext tc2 = mock(TaskContext.class);
//
when(tc1.getDeadline()).thenReturn((long) 100);
//
when(tc2.getDeadline()).thenReturn((long) 200);
assertTrue
(
edf
.
compare
(
t1
,
t2
)
<
0
);
assertTrue
(
edf
.
compare
(
tc1
,
tc2
)
<
0
);
assertTrue
(
edf
.
compare
(
t1
,
t1
)
==
0
);
assertTrue
(
edf
.
compare
(
tc1
,
tc1
)
==
0
);
assertTrue
(
edf
.
compare
(
t2
,
t1
)
>
0
);
assertTrue
(
edf
.
compare
(
tc2
,
tc1
)
>
0
);
}
//
assertTrue(edf.compare(t1, t2) < 0);
//
assertTrue(edf.compare(tc1, tc2) < 0);
//
assertTrue(edf.compare(t1, t1) == 0);
//
assertTrue(edf.compare(tc1, tc1) == 0);
//
assertTrue(edf.compare(t2, t1) > 0);
//
assertTrue(edf.compare(tc2, tc1) > 0);
//
}
@Test
@DisplayName
(
"Check Getters, Tests and Simulators."
)
void
testGettersTestsAndSimulators
()
{
EarliestDeadlineFirst
edf
=
new
EarliestDeadlineFirst
();
SystemManager
manager
=
new
SystemManager
(
4
);
assertTrue
(
edf
.
hasTest
(
ChwaLee
.
class
));
assertFalse
(
edf
.
hasTest
(
MaiaBertogna
.
class
));
assertFalse
(
edf
.
hasTest
(
SchmidMottok
.
class
));
assertTrue
(
edf
.
hasSimulator
(
ParallelSynchronous
.
class
));
assertTrue
(
edf
.
hasSimulator
(
DynamicForkJoin
.
class
));
//
@Test
//
@DisplayName("Check Getters, Tests and Simulators.")
//
void testGettersTestsAndSimulators() {
//
EarliestDeadlineFirst edf = new EarliestDeadlineFirst();
//
SystemManager manager = new SystemManager(4);
//
assertTrue(edf.hasTest(ChwaLee.class));
//
assertFalse(edf.hasTest(MaiaBertogna.class));
//
assertFalse(edf.hasTest(SchmidMottok.class));
//
assertTrue(edf.hasSimulator(ParallelSynchronous.class));
//
assertTrue(edf.hasSimulator(DynamicForkJoin.class));
assertTrue
(
edf
.
hasTest
(
new
ChwaLee
(
manager
)));
assertFalse
(
edf
.
hasTest
(
new
SchmidMottok
(
new
TypeFunction
.
KownStructure
(),
manager
)));
assertFalse
(
edf
.
hasTest
(
new
MaiaBertogna
(
manager
)));
// assertTrue(edf.hasSimulator(new ParallelSynchronous(mock(SystemSetup.class))));
// assertTrue(edf.hasSimulator(new DynamicForkJoin(mock(SystemSetup.class))));
//
assertTrue(edf.hasTest(new ChwaLee(manager)));
//
assertFalse(edf.hasTest(new SchmidMottok(new TypeFunction.KownStructure(), manager)));
//
assertFalse(edf.hasTest(new MaiaBertogna(manager)));
//
// assertTrue(edf.hasSimulator(new ParallelSynchronous(mock(SystemSetup.class))));
//
// assertTrue(edf.hasSimulator(new DynamicForkJoin(mock(SystemSetup.class))));
assertTrue
(
edf
.
getName
().
equals
(
"EDF"
));
}
//
assertTrue(edf.getName().equals("EDF"));
//
}
}
//
}
This diff is collapsed.
Click to expand it.
src/test/java/mvd/jester/priority/TestRateMonotonic.java
View file @
36080fd3
package
mvd
.
jester
.
priority
;
//
package mvd.jester.priority;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertFalse
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.Test
;
import
mvd.jester.model.SynchronousTask
;
import
mvd.jester.model.SystemManager
;
import
mvd.jester.simulator.DynamicForkJoin
;
import
mvd.jester.simulator.ParallelSynchronous
;
import
mvd.jester.simulator.internals.parallelsynchronous.TaskContext
;
import
mvd.jester.tests.ChwaLee
;
import
mvd.jester.tests.MaiaBertogna
;
import
mvd.jester.tests.SchmidMottok
;
import
mvd.jester.tests.TypeFunction
;
//
import static org.junit.jupiter.api.Assertions.assertFalse;
//
import static org.junit.jupiter.api.Assertions.assertTrue;
//
import static org.mockito.Mockito.mock;
//
import static org.mockito.Mockito.when;
//
import org.junit.jupiter.api.DisplayName;
//
import org.junit.jupiter.api.Test;
//
import mvd.jester.model.SynchronousTask;
//
import mvd.jester.model.SystemManager;
//
import mvd.jester.simulator.DynamicForkJoin;
//
import mvd.jester.simulator.ParallelSynchronous;
//
import mvd.jester.simulator.internals.parallelsynchronous.TaskContext;
//
import mvd.jester.tests.ChwaLee;
//
import mvd.jester.tests.MaiaBertogna;
//
import mvd.jester.tests.SchmidMottok;
//
import mvd.jester.tests.TypeFunction;
/**
* TestRateMonotonic
*/
public
class
TestRateMonotonic
{
/
/ /
**
//
* TestRateMonotonic
//
*/
//
public class TestRateMonotonic {
@Test
@DisplayName
(
"Test if priority manager returns the correct priority."
)
public
void
testPriority
()
{
RateMonotonic
rm
=
new
RateMonotonic
();
SynchronousTask
t1
=
mock
(
SynchronousTask
.
class
);
SynchronousTask
t2
=
mock
(
SynchronousTask
.
class
);
when
(
t1
.
getPeriod
()).
thenReturn
((
long
)
100
);
when
(
t2
.
getPeriod
()).
thenReturn
((
long
)
200
);
//
@Test
//
@DisplayName("Test if priority manager returns the correct priority.")
//
public void testPriority() {
//
RateMonotonic rm = new RateMonotonic();
//
SynchronousTask t1 = mock(SynchronousTask.class);
//
SynchronousTask t2 = mock(SynchronousTask.class);
//
when(t1.getPeriod()).thenReturn((long) 100);
//
when(t2.getPeriod()).thenReturn((long) 200);
TaskContext
tc1
=
mock
(
TaskContext
.
class
);
TaskContext
tc2
=
mock
(
TaskContext
.
class
);
when
(
tc1
.
getTask
()).
thenReturn
(
t1
);
when
(
tc2
.
getTask
()).
thenReturn
(
t2
);
//
TaskContext tc1 = mock(TaskContext.class);
//
TaskContext tc2 = mock(TaskContext.class);
//
when(tc1.getTask()).thenReturn(t1);
//
when(tc2.getTask()).thenReturn(t2);
assertTrue
(
rm
.
compare
(
t1
,
t2
)
<
0
);
assertTrue
(
rm
.
compare
(
tc1
,
tc2
)
<
0
);
assertTrue
(
rm
.
compare
(
t1
,
t1
)
==
0
);
assertTrue
(
rm
.
compare
(
tc1
,
tc1
)
==
0
);
assertTrue
(
rm
.
compare
(
t2
,
t1
)
>
0
);
assertTrue
(
rm
.
compare
(
tc2
,
tc1
)
>
0
);
}
//
assertTrue(rm.compare(t1, t2) < 0);
//
assertTrue(rm.compare(tc1, tc2) < 0);
//
assertTrue(rm.compare(t1, t1) == 0);
//
assertTrue(rm.compare(tc1, tc1) == 0);
//
assertTrue(rm.compare(t2, t1) > 0);
//
assertTrue(rm.compare(tc2, tc1) > 0);
//
}
@Test
@DisplayName
(
"Check Tests and Simulators."
)
void
testTestsAndSimulators
()
{
RateMonotonic
rm
=
new
RateMonotonic
();
SystemManager
manager
=
new
SystemManager
(
8
);
assertFalse
(
rm
.
hasTest
(
ChwaLee
.
class
));
assertTrue
(
rm
.
hasTest
(
MaiaBertogna
.
class
));
assertTrue
(
rm
.
hasTest
(
SchmidMottok
.
class
));
assertTrue
(
rm
.
hasSimulator
(
ParallelSynchronous
.
class
));
assertTrue
(
rm
.
hasSimulator
(
DynamicForkJoin
.
class
));
//
@Test
//
@DisplayName("Check Tests and Simulators.")
//
void testTestsAndSimulators() {
//
RateMonotonic rm = new RateMonotonic();
//
SystemManager manager = new SystemManager(8);
//
assertFalse(rm.hasTest(ChwaLee.class));
//
assertTrue(rm.hasTest(MaiaBertogna.class));
//
assertTrue(rm.hasTest(SchmidMottok.class));
//
assertTrue(rm.hasSimulator(ParallelSynchronous.class));
//
assertTrue(rm.hasSimulator(DynamicForkJoin.class));
assertFalse
(
rm
.
hasTest
(
new
ChwaLee
(
manager
)));
assertTrue
(
rm
.
hasTest
(
new
SchmidMottok
(
new
TypeFunction
.
UnkownStructure
(),
manager
)));
assertTrue
(
rm
.
hasTest
(
new
MaiaBertogna
(
manager
)));
// assertTrue(rm.hasSimulator(new ParallelSynchronous(mock(SystemSetup.class))));
// assertTrue(rm.hasSimulator(new DynamicForkJoin(mock(SystemSetup.class))));
//
assertFalse(rm.hasTest(new ChwaLee(manager)));
//
assertTrue(rm.hasTest(new SchmidMottok(new TypeFunction.UnkownStructure(), manager)));
//
assertTrue(rm.hasTest(new MaiaBertogna(manager)));
//
// assertTrue(rm.hasSimulator(new ParallelSynchronous(mock(SystemSetup.class))));
//
// assertTrue(rm.hasSimulator(new DynamicForkJoin(mock(SystemSetup.class))));
assertTrue
(
rm
.
getName
().
equals
(
"RM"
));
}
}
//
assertTrue(rm.getName().equals("RM"));
//
}
//
}
This diff is collapsed.
Click to expand it.
src/test/java/mvd/jester/simulator/TestProcessorContext.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertFalse
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
static
org
.
mockito
.
ArgumentMatchers
.
anyLong
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
static
org
.
mockito
.
AdditionalMatchers
.
gt
;
import
static
org
.
mockito
.
AdditionalMatchers
.
lt
;
import
java.util.Optional
;
import
java.util.concurrent.ThreadLocalRandom
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.Test
;
import
mvd.jester.model.SynchronousTask
;
import
mvd.jester.simulator.internals.ProcessorContext
;
import
mvd.jester.simulator.internals.TaskContextInterface
;
import
mvd.jester.simulator.internals.parallelsynchronous.JobContext
;
import
mvd.jester.simulator.internals.parallelsynchronous.TaskContext
;
/**
* TestProcessorContext
*/
public
class
TestProcessorContext
{
@Test
@DisplayName
(
"Check if the job execution is updated correctly."
)
void
testUpdateExecution
()
{
for
(
int
run
=
0
;
run
<
100
;
++
run
)
{
long
jobWcet
=
ThreadLocalRandom
.
current
().
nextLong
(
1
,
10
);
TaskContext
task
=
mock
(
TaskContext
.
class
);
JobContext
job
=
mock
(
JobContext
.
class
);
when
(
job
.
updateExecution
(
lt
(
jobWcet
))).
thenReturn
(
Optional
.
empty
());
when
(
job
.
updateExecution
(
jobWcet
)).
thenReturn
(
Optional
.
of
(
task
));
when
(
job
.
updateExecution
(
gt
(
jobWcet
))).
thenThrow
(
RuntimeException
.
class
);
ProcessorContext
processor
=
new
ProcessorContext
(
1
);
assertFalse
(
processor
.
updateExecution
(
0
).
isPresent
());
processor
.
setJob
(
job
);
for
(
int
i
=
0
;
i
<
jobWcet
;
++
i
)
{
assertFalse
(
processor
.
updateExecution
(
i
).
isPresent
());
}
Optional
<
TaskContextInterface
>
tci
=
processor
.
updateExecution
(
jobWcet
);
assertTrue
(
tci
.
isPresent
());
assertTrue
(
tci
.
get
().
equals
(
task
));
assertThrows
(
RuntimeException
.
class
,
()
->
processor
.
updateExecution
(
jobWcet
+
1
));
verify
(
job
,
times
((
int
)
jobWcet
+
2
)).
updateExecution
(
anyLong
());
}
}
@Test
@DisplayName
(
"Check if the processor correctly accepts jobs"
)
void
testAcceptTask
()
{
for
(
int
run
=
0
;
run
<
100
;
++
run
)
{
long
firstPeriod
=
ThreadLocalRandom
.
current
().
nextLong
(
100
,
1000
);
long
secondPeriod
=
ThreadLocalRandom
.
current
().
nextLong
(
100
,
1000
);
JobContext
firstJob
=
mock
(
JobContext
.
class
);
TaskContext
firstTaskContext
=
mock
(
TaskContext
.
class
);
SynchronousTask
firstTask
=
mock
(
SynchronousTask
.
class
);
when
(
firstJob
.
getTask
Context
()).
thenReturn
(
firstTaskContext
);
when
(
firstJob
.
prepareJob
(
anyLong
())).
thenReturn
(
true
);
when
(
firstTaskContext
.
getTask
()).
thenReturn
(
firstTask
);
when
(
firstTaskContext
.
getNextJob
()).
thenReturn
(
Optional
.
of
(
firstJob
));
when
(
firstTask
.
getPeriod
()).
thenReturn
((
long
)
firstPeriod
);
JobContext
secondJob
=
mock
(
JobContext
.
class
);
TaskContext
secondTaskContext
=
mock
(
TaskContext
.
class
);
SynchronousTask
secondTask
=
mock
(
SynchronousTask
.
class
);
when
(
secondJob
.
getTask
Context
()).
thenReturn
(
secondTaskContext
);
when
(
secondJob
.
prepareJob
(
anyLong
())).
thenReturn
(
true
);
when
(
secondTaskContext
.
getTask
()).
thenReturn
(
secondTask
);
when
(
secondTaskContext
.
getNextJob
()).
thenReturn
(
Optional
.
of
(
secondJob
));
when
(
secondTask
.
getPeriod
()).
thenReturn
((
long
)
secondPeriod
);
ProcessorContext
processor
=
new
ProcessorContext
(
1
);
assertTrue
(
processor
.
acceptTask
(
secondTaskContext
,
run
));
if
(
firstPeriod
<
secondPeriod
)
{
assertTrue
(
processor
.
acceptTask
(
firstTaskContext
,
run
));
}
else
{
assertFalse
(
processor
.
acceptTask
(
firstTaskContext
,
run
));
}
assertFalse
(
processor
.
acceptTask
(
secondTaskContext
,
run
));
int
time
=
firstPeriod
<
secondPeriod
?
1
:
0
;
verify
(
firstJob
,
times
(
time
)).
prepareJob
(
anyLong
());
verify
(
firstJob
,
times
(
time
)).
setCurrentProcessor
(
processor
);
verify
(
firstTaskContext
,
times
(
time
)).
getNextJob
();
verify
(
secondJob
,
times
(
1
)).
prepareJob
(
anyLong
());
verify
(
secondJob
,
times
(
1
)).
setCurrentProcessor
(
processor
);
verify
(
secondJob
,
times
(
time
)).
setCurrentProcessor
(
null
);
verify
(
secondTaskContext
,
times
(
1
)).
getNextJob
();
}
}
}
//
package mvd.jester.simulator;
//
import static org.junit.jupiter.api.Assertions.assertFalse;
//
import static org.junit.jupiter.api.Assertions.assertThrows;
//
import static org.junit.jupiter.api.Assertions.assertTrue;
//
import static org.mockito.ArgumentMatchers.anyLong;
//
import static org.mockito.Mockito.mock;
//
import static org.mockito.Mockito.times;
//
import static org.mockito.Mockito.verify;
//
import static org.mockito.Mockito.when;
//
import static org.mockito.AdditionalMatchers.gt;
//
import static org.mockito.AdditionalMatchers.lt;
//
import java.util.Optional;
//
import java.util.concurrent.ThreadLocalRandom;
//
import org.junit.jupiter.api.DisplayName;
//
import org.junit.jupiter.api.Test;
//
import mvd.jester.model.SynchronousTask;
//
import mvd.jester.simulator.internals.ProcessorContext;
// import mvd.jester.simulator.internals.ITaskContext
;
//
import mvd.jester.simulator.internals.parallelsynchronous.JobContext;
//
import mvd.jester.simulator.internals.parallelsynchronous.TaskContext;
/
/ /
**
//
* TestProcessorContext
//
*/
//
public class TestProcessorContext {
//
@Test
//
@DisplayName("Check if the job execution is updated correctly.")
//
void testUpdateExecution() {
//
for (int run = 0; run < 100; ++run) {
//
long jobWcet = ThreadLocalRandom.current().nextLong(1, 10);
//
TaskContext task = mock(TaskContext.class);
//
JobContext job = mock(JobContext.class);
//
when(job.updateExecution(lt(jobWcet))).thenReturn(Optional.empty());
//
when(job.updateExecution(jobWcet)).thenReturn(Optional.of(task));
//
when(job.updateExecution(gt(jobWcet))).thenThrow(RuntimeException.class);
//
ProcessorContext processor = new ProcessorContext(1);
//
assertFalse(processor.updateExecution(0).isPresent());
//
processor.setJob(job);
//
for (int i = 0; i < jobWcet; ++i) {
//
assertFalse(processor.updateExecution(i).isPresent());
//
}
// Optional<ITaskContext
> tci = processor.updateExecution(jobWcet);
//
assertTrue(tci.isPresent());
//
assertTrue(tci.get().equals(task));
//
assertThrows(RuntimeException.class, () -> processor.updateExecution(jobWcet + 1));
//
verify(job, times((int) jobWcet + 2)).updateExecution(anyLong());
//
}
//
}
//
@Test
//
@DisplayName("Check if the processor correctly accepts jobs")
//
void testAcceptTask() {
//
for (int run = 0; run < 100; ++run) {
//
long firstPeriod = ThreadLocalRandom.current().nextLong(100, 1000);
//
long secondPeriod = ThreadLocalRandom.current().nextLong(100, 1000);
//
JobContext firstJob = mock(JobContext.class);
//
TaskContext firstTaskContext = mock(TaskContext.class);
//
SynchronousTask firstTask = mock(SynchronousTask.class);
// when(firstJob.getJob
Context()).thenReturn(firstTaskContext);
//
when(firstJob.prepareJob(anyLong())).thenReturn(true);
//
when(firstTaskContext.getTask()).thenReturn(firstTask);
//
when(firstTaskContext.getNextJob()).thenReturn(Optional.of(firstJob));
//
when(firstTask.getPeriod()).thenReturn((long) firstPeriod);
//
JobContext secondJob = mock(JobContext.class);
//
TaskContext secondTaskContext = mock(TaskContext.class);
//
SynchronousTask secondTask = mock(SynchronousTask.class);
// when(secondJob.getJob
Context()).thenReturn(secondTaskContext);
//
when(secondJob.prepareJob(anyLong())).thenReturn(true);
//
when(secondTaskContext.getTask()).thenReturn(secondTask);
//
when(secondTaskContext.getNextJob()).thenReturn(Optional.of(secondJob));
//
when(secondTask.getPeriod()).thenReturn((long) secondPeriod);
//
ProcessorContext processor = new ProcessorContext(1);
//
assertTrue(processor.acceptTask(secondTaskContext, run));
//
if (firstPeriod < secondPeriod) {
//
assertTrue(processor.acceptTask(firstTaskContext, run));
//
} else {
//
assertFalse(processor.acceptTask(firstTaskContext, run));
//
}
//
assertFalse(processor.acceptTask(secondTaskContext, run));
//
int time = firstPeriod < secondPeriod ? 1 : 0;
//
verify(firstJob, times(time)).prepareJob(anyLong());
//
verify(firstJob, times(time)).setCurrentProcessor(processor);
//
verify(firstTaskContext, times(time)).getNextJob();
//
verify(secondJob, times(1)).prepareJob(anyLong());
//
verify(secondJob, times(1)).setCurrentProcessor(processor);
//
verify(secondJob, times(time)).setCurrentProcessor(null);
//
verify(secondTaskContext, times(1)).getNextJob();
//
}
//
}
//
}
This diff is collapsed.
Click to expand it.
src/test/java/mvd/jester/simulator/dynamicforkjoin/TestJobContext.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
dynamicforkjoin
;
//
package mvd.jester.simulator.dynamicforkjoin;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertFalse
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
static
org
.
mockito
.
ArgumentMatchers
.
anyLong
;
import
static
org
.
mockito
.
ArgumentMatchers
.
eq
;
import
static
org
.
mockito
.
AdditionalMatchers
.
not
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
java.util.Optional
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.Test
;
import
mvd.jester.model.Segment
;
import
mvd.jester.simulator.internals.ProcessorContext
;
import
mvd.jester.simulator.internals.dynamicforkjoin.JobContext
;
import
mvd.jester.simulator.internals.dynamicforkjoin.SegmentContext
;
import
mvd.jester.simulator.internals.dynamicforkjoin.TaskContext
;
import
mvd.jester.simulator.internals.dynamicforkjoin.TaskletContext
;;
//
import static org.junit.jupiter.api.Assertions.assertFalse;
//
import static org.junit.jupiter.api.Assertions.assertTrue;
//
import static org.mockito.ArgumentMatchers.anyLong;
//
import static org.mockito.ArgumentMatchers.eq;
//
import static org.mockito.AdditionalMatchers.not;
//
import static org.mockito.Mockito.mock;
//
import static org.mockito.Mockito.times;
//
import static org.mockito.Mockito.verify;
//
import static org.mockito.Mockito.when;
//
import java.util.Optional;
//
import org.junit.jupiter.api.DisplayName;
//
import org.junit.jupiter.api.Test;
//
import mvd.jester.model.Segment;
//
import mvd.jester.simulator.internals.ProcessorContext;
//
import mvd.jester.simulator.internals.dynamicforkjoin.JobContext;
//
import mvd.jester.simulator.internals.dynamicforkjoin.SegmentContext;
//
import mvd.jester.simulator.internals.dynamicforkjoin.TaskContext;
//
import mvd.jester.simulator.internals.dynamicforkjoin.TaskletContext;;
/**
* TestJobContext
*/
public
class
TestJobContext
{
/
/ /
**
//
* TestJobContext
//
*/
//
public class TestJobContext {
@Test
@DisplayName
(
"Check if the job is prepared correctly."
)
public
void
testPrepareJob
()
{
TaskContext
tc
=
mock
(
TaskContext
.
class
);
TaskletContext
tlc
=
mock
(
TaskletContext
.
class
);
SegmentContext
sc
=
mock
(
SegmentContext
.
class
);
Segment
s
=
mock
(
Segment
.
class
);
when
(
sc
.
getSegment
()).
thenReturn
(
s
);
when
(
s
.
getJobWcet
()).
thenReturn
((
long
)
20
);
when
(
sc
.
getNextTasklet
()).
thenReturn
(
Optional
.
of
(
tlc
))
.
thenReturn
(
Optional
.
ofNullable
(
null
));
//
@Test
//
@DisplayName("Check if the job is prepared correctly.")
//
public void testPrepareJob() {
//
TaskContext tc = mock(TaskContext.class);
//
TaskletContext tlc = mock(TaskletContext.class);
//
SegmentContext sc = mock(SegmentContext.class);
//
Segment s = mock(Segment.class);
//
when(sc.getSegment()).thenReturn(s);
//
when(s.getJobWcet()).thenReturn((long) 20);
//
when(sc.getNextTasklet()).thenReturn(Optional.of(tlc))
//
.thenReturn(Optional.ofNullable(null));
JobContext
jc
=
new
JobContext
(
tc
,
sc
);
//
JobContext jc = new JobContext(tc, sc);
assertTrue
(
jc
.
prepareJob
(
0
));
assertTrue
(
jc
.
prepareJob
(
1
));
jc
.
setCurrentTasklet
(
null
);
assertFalse
(
jc
.
prepareJob
(
2
));
}
//
assertTrue(jc.prepareJob(0));
//
assertTrue(jc.prepareJob(1));
//
jc.setCurrentTasklet(null);
//
assertFalse(jc.prepareJob(2));
//
}
@Test
@DisplayName
(
"Check if the execution time is checked correctly."
)
void
testCheckExecutionTime
()
{
TaskContext
tc
=
mock
(
TaskContext
.
class
);
TaskletContext
tlc
=
mock
(
TaskletContext
.
class
);
SegmentContext
sc
=
mock
(
SegmentContext
.
class
);
Segment
s
=
mock
(
Segment
.
class
);
when
(
sc
.
getSegment
()).
thenReturn
(
s
);
when
(
s
.
getJobWcet
()).
thenReturn
((
long
)
20
);
when
(
tlc
.
checkExecutionTime
()).
thenReturn
(
true
,
false
);
//
@Test
//
@DisplayName("Check if the execution time is checked correctly.")
//
void testCheckExecutionTime() {
//
TaskContext tc = mock(TaskContext.class);
//
TaskletContext tlc = mock(TaskletContext.class);
//
SegmentContext sc = mock(SegmentContext.class);
//
Segment s = mock(Segment.class);
//
when(sc.getSegment()).thenReturn(s);
//
when(s.getJobWcet()).thenReturn((long) 20);
//
when(tlc.checkExecutionTime()).thenReturn(true, false);
JobContext
jc
=
new
JobContext
(
tc
,
sc
);
//
JobContext jc = new JobContext(tc, sc);
assertFalse
(
jc
.
checkExecutionTime
());
jc
.
setCurrentTasklet
(
tlc
);
assertTrue
(
jc
.
checkExecutionTime
());
assertFalse
(
jc
.
checkExecutionTime
());
}
//
assertFalse(jc.checkExecutionTime());
//
jc.setCurrentTasklet(tlc);
//
assertTrue(jc.checkExecutionTime());
//
assertFalse(jc.checkExecutionTime());
//
}
@Test
@DisplayName
(
"Check if the execution is updated correctly."
)
void
checkUpdateExecution
()
{
TaskContext
tc
=
mock
(
TaskContext
.
class
);
TaskletContext
tlc
=
mock
(
TaskletContext
.
class
);
SegmentContext
sc
=
mock
(
SegmentContext
.
class
);
Segment
s
=
mock
(
Segment
.
class
);
ProcessorContext
pc
=
mock
(
ProcessorContext
.
class
);
when
(
sc
.
getSegment
()).
thenReturn
(
s
);
when
(
sc
.
getNextTasklet
()).
thenReturn
(
Optional
.
ofNullable
(
tlc
))
.
thenReturn
(
Optional
.
ofNullable
(
null
));
when
(
s
.
getJobWcet
()).
thenReturn
((
long
)
20
);
when
(
tlc
.
checkExecutionTime
()).
thenReturn
(
true
,
false
);
when
(
tlc
.
updateExecution
(
not
(
eq
(
0
)))).
thenReturn
(
true
);
when
(
tlc
.
updateExecution
(
0
)).
thenReturn
(
false
);
when
(
tc
.
acceptNotification
(
not
(
eq
(
1
)))).
thenReturn
(
Optional
.
ofNullable
(
null
));
when
(
tc
.
acceptNotification
(
1
)).
thenReturn
(
Optional
.
ofNullable
(
tc
));
//
@Test
//
@DisplayName("Check if the execution is updated correctly.")
//
void checkUpdateExecution() {
//
TaskContext tc = mock(TaskContext.class);
//
TaskletContext tlc = mock(TaskletContext.class);
//
SegmentContext sc = mock(SegmentContext.class);
//
Segment s = mock(Segment.class);
//
ProcessorContext pc = mock(ProcessorContext.class);
//
when(sc.getSegment()).thenReturn(s);
//
when(sc.getNextTasklet()).thenReturn(Optional.ofNullable(tlc))
//
.thenReturn(Optional.ofNullable(null));
//
when(s.getJobWcet()).thenReturn((long) 20);
//
when(tlc.checkExecutionTime()).thenReturn(true, false);
//
when(tlc.updateExecution(not(eq(0)))).thenReturn(true);
//
when(tlc.updateExecution(0)).thenReturn(false);
//
when(tc.acceptNotification(not(eq(1)))).thenReturn(Optional.ofNullable(null));
//
when(tc.acceptNotification(1)).thenReturn(Optional.ofNullable(tc));
JobContext
jc
=
new
JobContext
(
tc
,
sc
);
jc
.
setCurrentProcessor
(
pc
);
//
JobContext jc = new JobContext(tc, sc);
//
jc.setCurrentProcessor(pc);
assertFalse
(
jc
.
updateExecution
(
0
).
isPresent
());
assertFalse
(
jc
.
updateExecution
(
0
).
isPresent
());
//
assertFalse(jc.updateExecution(0).isPresent());
//
assertFalse(jc.updateExecution(0).isPresent());
jc
.
setCurrentTasklet
(
tlc
);
assertTrue
(
jc
.
updateExecution
(
1
).
isPresent
());
//
jc.setCurrentTasklet(tlc);
//
assertTrue(jc.updateExecution(1).isPresent());
verify
(
tlc
,
times
(
2
)).
updateExecution
(
anyLong
());
verify
(
tc
,
times
(
2
)).
acceptNotification
(
anyLong
());
verify
(
sc
,
times
(
2
)).
getNextTasklet
();
}
}
//
verify(tlc, times(2)).updateExecution(anyLong());
//
verify(tc, times(2)).acceptNotification(anyLong());
//
verify(sc, times(2)).getNextTasklet();
//
}
//
}
This diff is collapsed.
Click to expand it.
src/test/java/mvd/jester/simulator/parallelsynchronous/TestJobContext.java
View file @
36080fd3
package
mvd
.
jester
.
simulator
.
parallelsynchronous
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertFalse
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
static
org
.
mockito
.
ArgumentMatchers
.
anyLong
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
java.util.Optional
;
import
java.util.concurrent.ThreadLocalRandom
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.Test
;
import
mvd.jester.model.Segment
;
import
mvd.jester.simulator.internals.ProcessorContext
;
import
mvd.jester.simulator.internals.TaskContextInterface
;
import
mvd.jester.simulator.internals.parallelsynchronous.JobContext
;
import
mvd.jester.simulator.internals.parallelsynchronous.SegmentContext
;
import
mvd.jester.simulator.internals.parallelsynchronous.TaskContext
;
/**
* TestJobContext
*/
public
class
TestJobContext
{
@Test
@DisplayName
(
"Check if execution of Job is updated correctly."
)
public
void
testUpdateExecution
()
{
for
(
int
run
=
0
;
run
<
100
;
++
run
)
{
long
jobWcet
=
ThreadLocalRandom
.
current
().
nextLong
(
20
,
50
);
Segment
s
=
mock
(
Segment
.
class
);
when
(
s
.
getJobWcet
()).
thenReturn
(
jobWcet
);
SegmentContext
sc
=
mock
(
SegmentContext
.
class
);
when
(
sc
.
getSegment
()).
thenReturn
(
s
);
TaskContext
tc
=
mock
(
TaskContext
.
class
);
when
(
tc
.
acceptNotification
(
anyLong
())).
thenReturn
(
Optional
.
of
(
tc
));
JobContext
job
=
new
JobContext
(
tc
,
sc
);
ProcessorContext
p
=
mock
(
ProcessorContext
.
class
);
job
.
setCurrentProcessor
(
p
);
assertTrue
(
job
.
checkExecutionTime
());
for
(
int
i
=
0
;
i
<
jobWcet
-
1
;
++
i
)
{
assertFalse
(
job
.
updateExecution
(
i
).
isPresent
());
}
Optional
<
TaskContextInterface
>
otc
=
job
.
updateExecution
(
0
);
assertTrue
(
otc
.
isPresent
());
assertTrue
(
tc
.
equals
(
otc
.
get
()));
assertFalse
(
p
.
getJob
().
isPresent
());
assertFalse
(
job
.
getCurrentProcessor
().
isPresent
());
assertFalse
(
job
.
checkExecutionTime
());
verify
(
p
,
times
(
1
)).
setJob
(
null
);
assertThrows
(
RuntimeException
.
class
,
()
->
job
.
updateExecution
(
1
));
}
}
}
//
package mvd.jester.simulator.parallelsynchronous;
//
import static org.junit.jupiter.api.Assertions.assertFalse;
//
import static org.junit.jupiter.api.Assertions.assertThrows;
//
import static org.junit.jupiter.api.Assertions.assertTrue;
//
import static org.mockito.ArgumentMatchers.anyLong;
//
import static org.mockito.Mockito.mock;
//
import static org.mockito.Mockito.times;
//
import static org.mockito.Mockito.verify;
//
import static org.mockito.Mockito.when;
//
import java.util.Optional;
//
import java.util.concurrent.ThreadLocalRandom;
//
import org.junit.jupiter.api.DisplayName;
//
import org.junit.jupiter.api.Test;
//
import mvd.jester.model.Segment;
//
import mvd.jester.simulator.internals.ProcessorContext;
// import mvd.jester.simulator.internals.ITaskContext
;
//
import mvd.jester.simulator.internals.parallelsynchronous.JobContext;
//
import mvd.jester.simulator.internals.parallelsynchronous.SegmentContext;
//
import mvd.jester.simulator.internals.parallelsynchronous.TaskContext;
/
/ /
**
//
* TestJobContext
//
*/
//
public class TestJobContext {
//
@Test
//
@DisplayName("Check if execution of Job is updated correctly.")
//
public void testUpdateExecution() {
//
for (int run = 0; run < 100; ++run) {
//
long jobWcet = ThreadLocalRandom.current().nextLong(20, 50);
//
Segment s = mock(Segment.class);
//
when(s.getJobWcet()).thenReturn(jobWcet);
//
SegmentContext sc = mock(SegmentContext.class);
//
when(sc.getSegment()).thenReturn(s);
//
TaskContext tc = mock(TaskContext.class);
//
when(tc.acceptNotification(anyLong())).thenReturn(Optional.of(tc));
//
JobContext job = new JobContext(tc, sc);
//
ProcessorContext p = mock(ProcessorContext.class);
//
job.setCurrentProcessor(p);
//
assertTrue(job.checkExecutionTime());
//
for (int i = 0; i < jobWcet - 1; ++i) {
//
assertFalse(job.updateExecution(i).isPresent());
//
}
// Optional<ITaskContext
> otc = job.updateExecution(0);
//
assertTrue(otc.isPresent());
//
assertTrue(tc.equals(otc.get()));
// assertFalse(p.getSubtask
().isPresent());
//
assertFalse(job.getCurrentProcessor().isPresent());
//
assertFalse(job.checkExecutionTime());
//
verify(p, times(1)).setJob(null);
//
assertThrows(RuntimeException.class, () -> job.updateExecution(1));
//
}
//
}
//
}
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment