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
cfdd3254
authored
4 years ago
by
Michael Schmid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changes names
parent
9809bc74
scheduler
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
192 additions
and
192 deletions
+192
-192
src/main/java/mvd/jester/model/DagTask.java
+4
-4
src/main/java/mvd/jester/model/Subtask.java
+2
-2
src/main/java/mvd/jester/model/SubtaskContext.java
+4
-4
src/main/java/mvd/jester/model/SystemManager.java
+17
-17
src/main/java/mvd/jester/tests/FonsecaNelis.java
+23
-23
src/main/java/mvd/jester/utils/DagUtils.java
+101
-101
src/test/java/mvd/jester/model/TestDagUtils.java
+37
-37
src/test/java/mvd/jester/model/TestSystemSetup.java
+4
-4
No files found.
src/main/java/mvd/jester/model/DagTask.java
View file @
cfdd3254
...
@@ -7,7 +7,7 @@ import mvd.jester.utils.DagUtils;
...
@@ -7,7 +7,7 @@ import mvd.jester.utils.DagUtils;
public
class
DagTask
implements
Task
{
public
class
DagTask
implements
Task
{
private
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
;
private
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
;
private
final
Set
<
Segment
>
workloadDistribution
;
private
final
Set
<
Segment
>
workloadDistribution
;
private
final
long
workload
;
private
final
long
workload
;
private
final
long
criticalPath
;
private
final
long
criticalPath
;
...
@@ -15,7 +15,7 @@ public class DagTask implements Task {
...
@@ -15,7 +15,7 @@ public class DagTask implements Task {
private
final
long
deadline
;
private
final
long
deadline
;
private
final
long
numberOfThreads
;
private
final
long
numberOfThreads
;
public
DagTask
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
final
long
period
,
public
DagTask
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
,
final
long
period
,
final
long
numberOfThreads
)
{
final
long
numberOfThreads
)
{
this
.
jobDag
=
jobDag
;
this
.
jobDag
=
jobDag
;
this
.
period
=
period
;
this
.
period
=
period
;
...
@@ -41,14 +41,14 @@ public class DagTask implements Task {
...
@@ -41,14 +41,14 @@ public class DagTask implements Task {
/**
/**
* @return the jobDag
* @return the jobDag
*/
*/
public
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
getJobDag
()
{
public
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
getJobDag
()
{
return
jobDag
;
return
jobDag
;
}
}
/**
/**
* @param jobDag the jobDag to set
* @param jobDag the jobDag to set
*/
*/
public
void
setJobDag
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
public
void
setJobDag
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
)
{
this
.
jobDag
=
jobDag
;
this
.
jobDag
=
jobDag
;
}
}
...
...
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/model/
Job
.java
→
src/main/java/mvd/jester/model/
Subtask
.java
View file @
cfdd3254
package
mvd
.
jester
.
model
;
package
mvd
.
jester
.
model
;
public
class
Job
{
public
class
Subtask
{
private
final
long
wcet
;
private
final
long
wcet
;
private
long
relativeCompletionTime
;
private
long
relativeCompletionTime
;
public
Job
(
long
wcet
)
{
public
Subtask
(
long
wcet
)
{
this
.
wcet
=
wcet
;
this
.
wcet
=
wcet
;
this
.
relativeCompletionTime
=
wcet
;
this
.
relativeCompletionTime
=
wcet
;
}
}
...
...
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/model/
TreeJob
.java
→
src/main/java/mvd/jester/model/
SubtaskContext
.java
View file @
cfdd3254
package
mvd
.
jester
.
model
;
package
mvd
.
jester
.
model
;
public
class
TreeJob
{
public
class
SubtaskContext
{
private
long
wcet
;
private
long
wcet
;
private
final
Job
job
;
private
final
Subtask
job
;
public
TreeJob
(
final
Job
job
)
{
public
SubtaskContext
(
final
Subtask
job
)
{
this
.
wcet
=
job
.
getWcet
();
this
.
wcet
=
job
.
getWcet
();
this
.
job
=
job
;
this
.
job
=
job
;
}
}
...
@@ -12,7 +12,7 @@ public class TreeJob {
...
@@ -12,7 +12,7 @@ public class TreeJob {
/**
/**
* @return the job
* @return the job
*/
*/
public
Job
getJob
()
{
public
Subtask
getJob
()
{
return
job
;
return
job
;
}
}
...
...
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/model/SystemManager.java
View file @
cfdd3254
...
@@ -222,10 +222,10 @@ public class SystemManager {
...
@@ -222,10 +222,10 @@ public class SystemManager {
}
}
public
DagTask
generateTask
(
double
utilization
)
{
public
DagTask
generateTask
(
double
utilization
)
{
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
=
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
final
Job
j
=
fork
(
jobDag
,
Optional
.
empty
(),
this
.
depth
);
final
Subtask
j
=
fork
(
jobDag
,
Optional
.
empty
(),
this
.
depth
);
fork
(
jobDag
,
Optional
.
of
(
j
),
this
.
depth
);
fork
(
jobDag
,
Optional
.
of
(
j
),
this
.
depth
);
randomEdges
(
jobDag
);
randomEdges
(
jobDag
);
...
@@ -237,10 +237,10 @@ public class SystemManager {
...
@@ -237,10 +237,10 @@ public class SystemManager {
}
}
public
DagTask
generateTask
()
{
public
DagTask
generateTask
()
{
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
=
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
final
Job
j
=
fork
(
jobDag
,
Optional
.
empty
(),
this
.
depth
);
final
Subtask
j
=
fork
(
jobDag
,
Optional
.
empty
(),
this
.
depth
);
fork
(
jobDag
,
Optional
.
of
(
j
),
this
.
depth
);
fork
(
jobDag
,
Optional
.
of
(
j
),
this
.
depth
);
randomEdges
(
jobDag
);
randomEdges
(
jobDag
);
...
@@ -252,12 +252,12 @@ public class SystemManager {
...
@@ -252,12 +252,12 @@ public class SystemManager {
return
new
DagTask
(
jobDag
,
period
,
numberOfProcessors
);
return
new
DagTask
(
jobDag
,
period
,
numberOfProcessors
);
}
}
private
Job
join
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
final
Job
current
,
private
Subtask
join
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
,
final
Subtask
current
,
final
Set
<
Job
>
childs
)
{
final
Set
<
Subtask
>
childs
)
{
if
(
childs
.
size
()
>
0
)
{
if
(
childs
.
size
()
>
0
)
{
final
Job
job
=
new
Job
(
randomWcet
());
final
Subtask
job
=
new
Subtask
(
randomWcet
());
jobDag
.
addVertex
(
job
);
jobDag
.
addVertex
(
job
);
for
(
final
Job
c
:
childs
)
{
for
(
final
Subtask
c
:
childs
)
{
try
{
try
{
jobDag
.
addDagEdge
(
c
,
job
);
jobDag
.
addDagEdge
(
c
,
job
);
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
...
@@ -269,11 +269,11 @@ public class SystemManager {
...
@@ -269,11 +269,11 @@ public class SystemManager {
return
current
;
return
current
;
}
}
private
Job
fork
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
private
Subtask
fork
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
,
final
Optional
<
Job
>
predecessor
,
final
long
depth
)
{
final
Optional
<
Subtask
>
predecessor
,
final
long
depth
)
{
final
Job
job
=
new
Job
(
randomWcet
());
final
Subtask
job
=
new
Subtask
(
randomWcet
());
jobDag
.
addVertex
(
job
);
jobDag
.
addVertex
(
job
);
final
Set
<
Job
>
childs
=
new
HashSet
<>();
final
Set
<
Subtask
>
childs
=
new
HashSet
<>();
if
(
predecessor
.
isPresent
())
{
if
(
predecessor
.
isPresent
())
{
try
{
try
{
jobDag
.
addDagEdge
(
predecessor
.
get
(),
job
);
jobDag
.
addDagEdge
(
predecessor
.
get
(),
job
);
...
@@ -291,17 +291,17 @@ public class SystemManager {
...
@@ -291,17 +291,17 @@ public class SystemManager {
return
join
(
jobDag
,
job
,
childs
);
return
join
(
jobDag
,
job
,
childs
);
}
}
private
void
randomEdges
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
private
void
randomEdges
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
)
{
final
Multimap
<
Job
,
Job
>
edgePairs
=
ArrayListMultimap
.
create
();
final
Multimap
<
Subtask
,
Subtask
>
edgePairs
=
ArrayListMultimap
.
create
();
for
(
final
Job
j1
:
jobDag
)
{
for
(
final
Subtask
j1
:
jobDag
)
{
for
(
final
Job
j2
:
jobDag
)
{
for
(
final
Subtask
j2
:
jobDag
)
{
if
(
randomProbability
()
<
p_add
)
{
if
(
randomProbability
()
<
p_add
)
{
edgePairs
.
put
(
j1
,
j2
);
edgePairs
.
put
(
j1
,
j2
);
}
}
}
}
}
}
for
(
final
Map
.
Entry
<
Job
,
Job
>
pairs
:
edgePairs
.
entries
())
{
for
(
final
Map
.
Entry
<
Subtask
,
Subtask
>
pairs
:
edgePairs
.
entries
())
{
try
{
try
{
jobDag
.
addDagEdge
(
pairs
.
getKey
(),
pairs
.
getValue
());
jobDag
.
addDagEdge
(
pairs
.
getKey
(),
pairs
.
getValue
());
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
...
...
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/tests/FonsecaNelis.java
View file @
cfdd3254
...
@@ -18,12 +18,12 @@ import org.jgrapht.graph.DefaultEdge;
...
@@ -18,12 +18,12 @@ import org.jgrapht.graph.DefaultEdge;
import
mvd.jester.info.SchedulingInfo
;
import
mvd.jester.info.SchedulingInfo
;
import
mvd.jester.info.TerminationInfo
;
import
mvd.jester.info.TerminationInfo
;
import
mvd.jester.model.DagTask
;
import
mvd.jester.model.DagTask
;
import
mvd.jester.model.
Job
;
import
mvd.jester.model.
Subtask
;
import
mvd.jester.model.Segment
;
import
mvd.jester.model.Segment
;
import
mvd.jester.model.SortedTaskSet
;
import
mvd.jester.model.SortedTaskSet
;
import
mvd.jester.model.SystemManager
;
import
mvd.jester.model.SystemManager
;
import
mvd.jester.model.Task
;
import
mvd.jester.model.Task
;
import
mvd.jester.model.
TreeJob
;
import
mvd.jester.model.
SubtaskContext
;
import
mvd.jester.utils.DagUtils
;
import
mvd.jester.utils.DagUtils
;
import
mvd.jester.priority.PriorityManager
;
import
mvd.jester.priority.PriorityManager
;
import
mvd.jester.priority.RateMonotonic
;
import
mvd.jester.priority.RateMonotonic
;
...
@@ -64,32 +64,32 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
...
@@ -64,32 +64,32 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
private
void
createNFJandDecompositionTree
(
final
SortedTaskSet
<
DagTask
>
tasks
)
{
private
void
createNFJandDecompositionTree
(
final
SortedTaskSet
<
DagTask
>
tasks
)
{
for
(
final
DagTask
t
:
tasks
)
{
for
(
final
DagTask
t
:
tasks
)
{
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
t
.
getJobDag
();
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
=
t
.
getJobDag
();
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
nfjJobDag
=
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
nfjJobDag
=
DagUtils
.
createNFJGraph
(
jobDag
);
DagUtils
.
createNFJGraph
(
jobDag
);
final
BinaryDecompositionTree
<
Job
>
tree
=
DagUtils
.
createDecompositionTree
(
nfjJobDag
);
final
BinaryDecompositionTree
<
Subtask
>
tree
=
DagUtils
.
createDecompositionTree
(
nfjJobDag
);
carryOutSegments
.
put
(
t
,
constructCarryOutDistribution
(
nfjJobDag
,
tree
));
carryOutSegments
.
put
(
t
,
constructCarryOutDistribution
(
nfjJobDag
,
tree
));
}
}
}
}
private
Set
<
Segment
>
constructCarryOutDistribution
(
private
Set
<
Segment
>
constructCarryOutDistribution
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
nfjDag
,
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
nfjDag
,
final
BinaryDecompositionTree
<
Job
>
tree
)
{
final
BinaryDecompositionTree
<
Subtask
>
tree
)
{
// List statt Set
// List statt Set
final
Set
<
Segment
>
carryOutWorkload
=
new
LinkedHashSet
<>();
final
Set
<
Segment
>
carryOutWorkload
=
new
LinkedHashSet
<>();
final
BinaryDecompositionTree
<
TreeJob
>
modifiedTree
=
transformTree
(
tree
);
final
BinaryDecompositionTree
<
SubtaskContext
>
modifiedTree
=
transformTree
(
tree
);
boolean
isEmpty
=
false
;
boolean
isEmpty
=
false
;
do
{
do
{
final
Set
<
TreeJob
>
parallelJobs
=
getMaximumParallelism
(
modifiedTree
.
getRootNode
());
final
Set
<
SubtaskContext
>
parallelJobs
=
getMaximumParallelism
(
modifiedTree
.
getRootNode
());
final
Optional
<
TreeJob
>
min
=
final
Optional
<
SubtaskContext
>
min
=
parallelJobs
.
stream
().
min
((
p1
,
p2
)
->
Long
.
compare
(
p1
.
getWcet
(),
p2
.
getWcet
()));
parallelJobs
.
stream
().
min
((
p1
,
p2
)
->
Long
.
compare
(
p1
.
getWcet
(),
p2
.
getWcet
()));
if
(
min
.
isPresent
())
{
if
(
min
.
isPresent
())
{
final
long
width
=
min
.
get
().
getWcet
();
final
long
width
=
min
.
get
().
getWcet
();
carryOutWorkload
.
add
(
new
Segment
(
width
,
parallelJobs
.
size
()));
carryOutWorkload
.
add
(
new
Segment
(
width
,
parallelJobs
.
size
()));
for
(
final
TreeJob
p
:
parallelJobs
)
{
for
(
final
SubtaskContext
p
:
parallelJobs
)
{
p
.
setWcet
(
p
.
getWcet
()
-
width
);
p
.
setWcet
(
p
.
getWcet
()
-
width
);
}
}
}
else
{
}
else
{
...
@@ -102,34 +102,34 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
...
@@ -102,34 +102,34 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
}
}
private
BinaryDecompositionTree
<
TreeJob
>
transformTree
(
private
BinaryDecompositionTree
<
SubtaskContext
>
transformTree
(
final
BinaryDecompositionTree
<
Job
>
tree
)
{
final
BinaryDecompositionTree
<
Subtask
>
tree
)
{
final
BinaryDecompositionTree
<
TreeJob
>
modifiedTree
=
new
BinaryDecompositionTree
<>();
final
BinaryDecompositionTree
<
SubtaskContext
>
modifiedTree
=
new
BinaryDecompositionTree
<>();
final
Node
<
TreeJob
>
root
=
transformNode
(
null
,
tree
.
getRootNode
());
final
Node
<
SubtaskContext
>
root
=
transformNode
(
null
,
tree
.
getRootNode
());
modifiedTree
.
setRoot
(
root
);
modifiedTree
.
setRoot
(
root
);
return
modifiedTree
;
return
modifiedTree
;
}
}
private
Node
<
TreeJob
>
transformNode
(
final
Node
<
TreeJob
>
parent
,
final
Node
<
Job
>
node
)
{
private
Node
<
SubtaskContext
>
transformNode
(
final
Node
<
SubtaskContext
>
parent
,
final
Node
<
Subtask
>
node
)
{
if
(
node
.
getNodeType
().
equals
(
NodeType
.
LEAF
))
{
if
(
node
.
getNodeType
().
equals
(
NodeType
.
LEAF
))
{
return
new
Node
<
TreeJob
>(
parent
,
new
TreeJob
(
node
.
getObject
()));
return
new
Node
<
SubtaskContext
>(
parent
,
new
SubtaskContext
(
node
.
getObject
()));
}
else
{
}
else
{
final
Node
<
TreeJob
>
modifiedNode
=
new
Node
<
TreeJob
>(
parent
,
node
.
getNodeType
());
final
Node
<
SubtaskContext
>
modifiedNode
=
new
Node
<
SubtaskContext
>(
parent
,
node
.
getNodeType
());
modifiedNode
.
setLeftNode
(
transformNode
(
modifiedNode
,
node
.
getLeftNode
()));
modifiedNode
.
setLeftNode
(
transformNode
(
modifiedNode
,
node
.
getLeftNode
()));
modifiedNode
.
setRightNode
(
transformNode
(
modifiedNode
,
node
.
getRightNode
()));
modifiedNode
.
setRightNode
(
transformNode
(
modifiedNode
,
node
.
getRightNode
()));
return
modifiedNode
;
return
modifiedNode
;
}
}
}
}
private
Set
<
TreeJob
>
getMaximumParallelism
(
final
Node
<
TreeJob
>
node
)
{
private
Set
<
SubtaskContext
>
getMaximumParallelism
(
final
Node
<
SubtaskContext
>
node
)
{
final
NodeType
nodeType
=
node
.
getNodeType
();
final
NodeType
nodeType
=
node
.
getNodeType
();
if
(
nodeType
.
equals
(
NodeType
.
PAR
))
{
if
(
nodeType
.
equals
(
NodeType
.
PAR
))
{
final
Set
<
TreeJob
>
left
=
getMaximumParallelism
(
node
.
getLeftNode
());
final
Set
<
SubtaskContext
>
left
=
getMaximumParallelism
(
node
.
getLeftNode
());
final
Set
<
TreeJob
>
right
=
getMaximumParallelism
(
node
.
getRightNode
());
final
Set
<
SubtaskContext
>
right
=
getMaximumParallelism
(
node
.
getRightNode
());
return
Sets
.
union
(
left
,
right
);
return
Sets
.
union
(
left
,
right
);
}
else
if
(
nodeType
.
equals
(
NodeType
.
SEQ
))
{
}
else
if
(
nodeType
.
equals
(
NodeType
.
SEQ
))
{
final
Set
<
TreeJob
>
left
=
getMaximumParallelism
(
node
.
getLeftNode
());
final
Set
<
SubtaskContext
>
left
=
getMaximumParallelism
(
node
.
getLeftNode
());
final
Set
<
TreeJob
>
right
=
getMaximumParallelism
(
node
.
getRightNode
());
final
Set
<
SubtaskContext
>
right
=
getMaximumParallelism
(
node
.
getRightNode
());
if
(
left
.
size
()
>=
right
.
size
())
{
if
(
left
.
size
()
>=
right
.
size
())
{
return
left
;
return
left
;
}
else
{
}
else
{
...
...
This diff is collapsed.
Click to expand it.
src/main/java/mvd/jester/utils/DagUtils.java
View file @
cfdd3254
...
@@ -14,29 +14,29 @@ import org.jgrapht.Graphs;
...
@@ -14,29 +14,29 @@ import org.jgrapht.Graphs;
import
org.jgrapht.experimental.dag.DirectedAcyclicGraph
;
import
org.jgrapht.experimental.dag.DirectedAcyclicGraph
;
import
org.jgrapht.graph.DefaultEdge
;
import
org.jgrapht.graph.DefaultEdge
;
import
org.jgrapht.traverse.TopologicalOrderIterator
;
import
org.jgrapht.traverse.TopologicalOrderIterator
;
import
mvd.jester.model.
Job
;
import
mvd.jester.model.
Subtask
;
import
mvd.jester.model.Segment
;
import
mvd.jester.model.Segment
;
import
mvd.jester.utils.BinaryDecompositionTree.Node
;
import
mvd.jester.utils.BinaryDecompositionTree.Node
;
import
mvd.jester.utils.BinaryDecompositionTree.NodeType
;
import
mvd.jester.utils.BinaryDecompositionTree.NodeType
;
public
class
DagUtils
{
public
class
DagUtils
{
public
static
long
calculateWorkload
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
public
static
long
calculateWorkload
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
)
{
long
workload
=
0
;
long
workload
=
0
;
for
(
final
Job
job
:
jobDag
)
{
for
(
final
Subtask
job
:
jobDag
)
{
workload
+=
job
.
getWcet
();
workload
+=
job
.
getWcet
();
}
}
return
workload
;
return
workload
;
}
}
public
static
long
calculateCriticalPath
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
public
static
long
calculateCriticalPath
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
)
{
long
criticalPath
=
0
;
long
criticalPath
=
0
;
for
(
final
Job
job
:
jobDag
)
{
for
(
final
Subtask
job
:
jobDag
)
{
final
Set
<
DefaultEdge
>
edges
=
jobDag
.
incomingEdgesOf
(
job
);
final
Set
<
DefaultEdge
>
edges
=
jobDag
.
incomingEdgesOf
(
job
);
long
longestRelativeCompletionTime
=
0
;
long
longestRelativeCompletionTime
=
0
;
for
(
final
DefaultEdge
e
:
edges
)
{
for
(
final
DefaultEdge
e
:
edges
)
{
final
Job
source
=
jobDag
.
getEdgeSource
(
e
);
final
Subtask
source
=
jobDag
.
getEdgeSource
(
e
);
longestRelativeCompletionTime
=
longestRelativeCompletionTime
=
longestRelativeCompletionTime
>=
source
.
getRelativeCompletionTime
()
longestRelativeCompletionTime
>=
source
.
getRelativeCompletionTime
()
?
longestRelativeCompletionTime
?
longestRelativeCompletionTime
...
@@ -51,13 +51,13 @@ public class DagUtils {
...
@@ -51,13 +51,13 @@ public class DagUtils {
}
}
public
static
LinkedHashSet
<
Segment
>
calculateWorkloadDistribution
(
public
static
LinkedHashSet
<
Segment
>
calculateWorkloadDistribution
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
final
long
criticalPath
)
{
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
,
final
long
criticalPath
)
{
final
LinkedHashSet
<
Segment
>
segments
=
new
LinkedHashSet
<>();
final
LinkedHashSet
<
Segment
>
segments
=
new
LinkedHashSet
<>();
long
segmentDuration
=
0
;
long
segmentDuration
=
0
;
long
segmentHeight
=
1
;
long
segmentHeight
=
1
;
for
(
long
t
=
0
;
t
<
criticalPath
;
++
t
)
{
for
(
long
t
=
0
;
t
<
criticalPath
;
++
t
)
{
long
currentHeight
=
0
;
long
currentHeight
=
0
;
for
(
final
Job
j
:
jobDag
)
{
for
(
final
Subtask
j
:
jobDag
)
{
if
(
t
>=
j
.
getRelativeCompletionTime
()
-
j
.
getWcet
()
if
(
t
>=
j
.
getRelativeCompletionTime
()
-
j
.
getWcet
()
&&
t
<
j
.
getRelativeCompletionTime
())
{
&&
t
<
j
.
getRelativeCompletionTime
())
{
currentHeight
++;
currentHeight
++;
...
@@ -85,12 +85,12 @@ public class DagUtils {
...
@@ -85,12 +85,12 @@ public class DagUtils {
// return createNFJGraph(jobDag, forkNodes, joinNodes);
// return createNFJGraph(jobDag, forkNodes, joinNodes);
// }
// }
public
static
void
collectForksAndJoins
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
public
static
void
collectForksAndJoins
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
,
final
LinkedList
<
Job
>
forkNodes
,
final
LinkedList
<
Job
>
joinNodes
)
{
final
LinkedList
<
Subtask
>
forkNodes
,
final
LinkedList
<
Subtask
>
joinNodes
)
{
// final ClosestFirstIterator<Job, DefaultEdge> it = new ClosestFirstIterator<>(jobDag);
// final ClosestFirstIterator<Job, DefaultEdge> it = new ClosestFirstIterator<>(jobDag);
Iterator
<
Job
>
it
=
jobDag
.
iterator
();
Iterator
<
Subtask
>
it
=
jobDag
.
iterator
();
for
(;
it
.
hasNext
();)
{
for
(;
it
.
hasNext
();)
{
final
Job
j
=
it
.
next
();
final
Subtask
j
=
it
.
next
();
// for (final Job j : jobDag) {
// for (final Job j : jobDag) {
if
(
jobDag
.
inDegreeOf
(
j
)
>
1
)
{
if
(
jobDag
.
inDegreeOf
(
j
)
>
1
)
{
joinNodes
.
add
(
j
);
joinNodes
.
add
(
j
);
...
@@ -103,13 +103,13 @@ public class DagUtils {
...
@@ -103,13 +103,13 @@ public class DagUtils {
private
static
LinkedList
<
Job
>
getUnvisitedJoinNodes
(
private
static
LinkedList
<
Subtask
>
getUnvisitedJoinNodes
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
final
Set
<
Job
>
visitedJobs
)
{
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
,
final
Set
<
Subtask
>
visitedJobs
)
{
final
LinkedList
<
Job
>
joinNodes
=
new
LinkedList
<>();
final
LinkedList
<
Subtask
>
joinNodes
=
new
LinkedList
<>();
final
TopologicalOrderIterator
<
Job
,
DefaultEdge
>
it
=
final
TopologicalOrderIterator
<
Subtask
,
DefaultEdge
>
it
=
new
TopologicalOrderIterator
<>(
jobDag
);
new
TopologicalOrderIterator
<>(
jobDag
);
for
(;
it
.
hasNext
();)
{
for
(;
it
.
hasNext
();)
{
final
Job
j
=
it
.
next
();
final
Subtask
j
=
it
.
next
();
if
(
jobDag
.
inDegreeOf
(
j
)
>
1
&&
!
visitedJobs
.
contains
(
j
))
{
if
(
jobDag
.
inDegreeOf
(
j
)
>
1
&&
!
visitedJobs
.
contains
(
j
))
{
joinNodes
.
add
(
j
);
joinNodes
.
add
(
j
);
}
}
...
@@ -117,29 +117,29 @@ public class DagUtils {
...
@@ -117,29 +117,29 @@ public class DagUtils {
return
joinNodes
;
return
joinNodes
;
}
}
public
static
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
createNFJGraph
(
public
static
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
createNFJGraph
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
)
{
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
modifiedJobDag
=
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
modifiedJobDag
=
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
Graphs
.
addGraph
(
modifiedJobDag
,
jobDag
);
Graphs
.
addGraph
(
modifiedJobDag
,
jobDag
);
Job
sink
=
null
;
Subtask
sink
=
null
;
for
(
final
Job
j
:
modifiedJobDag
)
{
for
(
final
Subtask
j
:
modifiedJobDag
)
{
sink
=
j
;
sink
=
j
;
}
}
final
Set
<
Job
>
visitedJobs
=
new
HashSet
<>();
final
Set
<
Subtask
>
visitedJobs
=
new
HashSet
<>();
while
(
true
)
{
while
(
true
)
{
final
LinkedList
<
Job
>
joins
=
getUnvisitedJoinNodes
(
modifiedJobDag
,
visitedJobs
);
final
LinkedList
<
Subtask
>
joins
=
getUnvisitedJoinNodes
(
modifiedJobDag
,
visitedJobs
);
if
(
joins
.
isEmpty
())
{
if
(
joins
.
isEmpty
())
{
break
;
break
;
}
}
final
Job
joinNode
=
joins
.
getFirst
();
final
Subtask
joinNode
=
joins
.
getFirst
();
visitedJobs
.
add
(
joinNode
);
visitedJobs
.
add
(
joinNode
);
nextEdge:
while
(
modifiedJobDag
.
inDegreeOf
(
joinNode
)
>
1
)
{
nextEdge:
while
(
modifiedJobDag
.
inDegreeOf
(
joinNode
)
>
1
)
{
final
List
<
Job
>
predecessors
=
Graphs
.
predecessorListOf
(
modifiedJobDag
,
joinNode
);
final
List
<
Subtask
>
predecessors
=
Graphs
.
predecessorListOf
(
modifiedJobDag
,
joinNode
);
for
(
final
Job
p
:
predecessors
)
{
for
(
final
Subtask
p
:
predecessors
)
{
if
(!
checkPredecessors
(
modifiedJobDag
,
joinNode
,
p
))
{
if
(!
checkPredecessors
(
modifiedJobDag
,
joinNode
,
p
))
{
final
DefaultEdge
conflictingEdge
=
modifiedJobDag
.
getEdge
(
p
,
joinNode
);
final
DefaultEdge
conflictingEdge
=
modifiedJobDag
.
getEdge
(
p
,
joinNode
);
modifiedJobDag
.
removeEdge
(
conflictingEdge
);
modifiedJobDag
.
removeEdge
(
conflictingEdge
);
...
@@ -161,22 +161,22 @@ public class DagUtils {
...
@@ -161,22 +161,22 @@ public class DagUtils {
}
}
private
static
boolean
checkPredecessors
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
private
static
boolean
checkPredecessors
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
,
final
Job
joinNode
,
Job
current
)
{
final
Subtask
joinNode
,
Subtask
current
)
{
if
(
jobDag
.
outDegreeOf
(
current
)
>
1
)
{
if
(
jobDag
.
outDegreeOf
(
current
)
>
1
)
{
final
Set
<
Job
>
ancestorsOfJ
=
jobDag
.
getAncestors
(
jobDag
,
joinNode
);
final
Set
<
Subtask
>
ancestorsOfJ
=
jobDag
.
getAncestors
(
jobDag
,
joinNode
);
ancestorsOfJ
.
add
(
joinNode
);
ancestorsOfJ
.
add
(
joinNode
);
if
(!
ancestorsOfJ
.
containsAll
(
Graphs
.
successorListOf
(
jobDag
,
current
)))
{
if
(!
ancestorsOfJ
.
containsAll
(
Graphs
.
successorListOf
(
jobDag
,
current
)))
{
return
false
;
return
false
;
}
}
final
Set
<
Job
>
descendantsOfCurrent
=
jobDag
.
getDescendants
(
jobDag
,
current
);
final
Set
<
Subtask
>
descendantsOfCurrent
=
jobDag
.
getDescendants
(
jobDag
,
current
);
if
(
descendantsOfCurrent
.
containsAll
(
Graphs
.
predecessorListOf
(
jobDag
,
joinNode
)))
{
if
(
descendantsOfCurrent
.
containsAll
(
Graphs
.
predecessorListOf
(
jobDag
,
joinNode
)))
{
return
true
;
return
true
;
}
}
}
}
final
List
<
Job
>
predecessorList
=
Graphs
.
predecessorListOf
(
jobDag
,
current
);
final
List
<
Subtask
>
predecessorList
=
Graphs
.
predecessorListOf
(
jobDag
,
current
);
for
(
Job
p
:
predecessorList
)
{
for
(
Subtask
p
:
predecessorList
)
{
if
(!
checkPredecessors
(
jobDag
,
joinNode
,
p
))
{
if
(!
checkPredecessors
(
jobDag
,
joinNode
,
p
))
{
return
false
;
return
false
;
}
}
...
@@ -184,23 +184,23 @@ public class DagUtils {
...
@@ -184,23 +184,23 @@ public class DagUtils {
return
true
;
return
true
;
}
}
public
static
BinaryDecompositionTree
<
Job
>
createDecompositionTree
(
public
static
BinaryDecompositionTree
<
Subtask
>
createDecompositionTree
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
)
{
final
LinkedList
<
Job
>
joinNodes
=
new
LinkedList
<>();
final
LinkedList
<
Subtask
>
joinNodes
=
new
LinkedList
<>();
final
LinkedList
<
Job
>
forkNodes
=
new
LinkedList
<>();
final
LinkedList
<
Subtask
>
forkNodes
=
new
LinkedList
<>();
collectForksAndJoins
(
jobDag
,
forkNodes
,
joinNodes
);
collectForksAndJoins
(
jobDag
,
forkNodes
,
joinNodes
);
return
createDecompositionTree
(
jobDag
,
forkNodes
,
joinNodes
);
return
createDecompositionTree
(
jobDag
,
forkNodes
,
joinNodes
);
}
}
public
static
BinaryDecompositionTree
<
Job
>
createDecompositionTree
(
public
static
BinaryDecompositionTree
<
Subtask
>
createDecompositionTree
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
final
LinkedList
<
Job
>
forkNodes
,
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
,
final
LinkedList
<
Subtask
>
forkNodes
,
final
LinkedList
<
Job
>
joinNodes
)
{
final
LinkedList
<
Subtask
>
joinNodes
)
{
final
BinaryDecompositionTree
<
Job
>
tree
=
new
BinaryDecompositionTree
<>();
final
BinaryDecompositionTree
<
Subtask
>
tree
=
new
BinaryDecompositionTree
<>();
Optional
<
Job
>
source
=
Optional
.
empty
();
Optional
<
Subtask
>
source
=
Optional
.
empty
();
Optional
<
Job
>
sink
=
Optional
.
empty
();
Optional
<
Subtask
>
sink
=
Optional
.
empty
();
boolean
firstRun
=
true
;
boolean
firstRun
=
true
;
for
(
final
Job
j
:
jobDag
)
{
for
(
final
Subtask
j
:
jobDag
)
{
if
(
firstRun
)
{
if
(
firstRun
)
{
firstRun
=
false
;
firstRun
=
false
;
source
=
Optional
.
of
(
j
);
source
=
Optional
.
of
(
j
);
...
@@ -209,7 +209,7 @@ public class DagUtils {
...
@@ -209,7 +209,7 @@ public class DagUtils {
}
}
if
(
source
.
isPresent
()
&&
sink
.
isPresent
())
{
if
(
source
.
isPresent
()
&&
sink
.
isPresent
())
{
final
Job
current
=
source
.
get
();
final
Subtask
current
=
source
.
get
();
DagUtils
.
constructTree
(
jobDag
,
null
,
current
,
tree
,
forkNodes
,
joinNodes
,
sink
.
get
());
DagUtils
.
constructTree
(
jobDag
,
null
,
current
,
tree
,
forkNodes
,
joinNodes
,
sink
.
get
());
}
}
...
@@ -217,42 +217,42 @@ public class DagUtils {
...
@@ -217,42 +217,42 @@ public class DagUtils {
return
tree
;
return
tree
;
}
}
private
static
Node
<
Job
>
constructTree
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
private
static
Node
<
Subtask
>
constructTree
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
,
final
Node
<
Job
>
parentNode
,
final
Job
currentJob
,
final
Node
<
Subtask
>
parentNode
,
final
Subtask
currentJob
,
final
BinaryDecompositionTree
<
Job
>
tree
,
final
LinkedList
<
Job
>
forkVertices
,
final
BinaryDecompositionTree
<
Subtask
>
tree
,
final
LinkedList
<
Subtask
>
forkVertices
,
final
LinkedList
<
Job
>
joinVertices
,
final
Job
sinkJob
)
{
final
LinkedList
<
Subtask
>
joinVertices
,
final
Subtask
sinkJob
)
{
if
(
forkVertices
.
contains
(
currentJob
))
{
if
(
forkVertices
.
contains
(
currentJob
))
{
final
Job
forkJob
=
currentJob
;
final
Subtask
forkJob
=
currentJob
;
final
Job
joinJob
=
findJoin
(
jobDag
,
forkJob
,
sinkJob
,
joinVertices
);
final
Subtask
joinJob
=
findJoin
(
jobDag
,
forkJob
,
sinkJob
,
joinVertices
);
final
Node
<
Job
>
seqForkNode
=
new
Node
<
Job
>(
parentNode
,
NodeType
.
SEQ
);
final
Node
<
Subtask
>
seqForkNode
=
new
Node
<
Subtask
>(
parentNode
,
NodeType
.
SEQ
);
seqForkNode
.
setLeftNode
(
new
Node
<
Job
>(
seqForkNode
,
forkJob
));
seqForkNode
.
setLeftNode
(
new
Node
<
Subtask
>(
seqForkNode
,
forkJob
));
if
(
tree
.
isEmpty
())
{
if
(
tree
.
isEmpty
())
{
tree
.
setRoot
(
seqForkNode
);
tree
.
setRoot
(
seqForkNode
);
}
}
final
Node
<
Job
>
parContinuationNode
;
final
Node
<
Subtask
>
parContinuationNode
;
if
(!
tree
.
contains
(
joinJob
))
{
if
(!
tree
.
contains
(
joinJob
))
{
final
Node
<
Job
>
seqJoinNode
=
final
Node
<
Subtask
>
seqJoinNode
=
seqForkNode
.
setRightNode
(
new
Node
<
Job
>(
seqForkNode
,
NodeType
.
SEQ
));
seqForkNode
.
setRightNode
(
new
Node
<
Subtask
>(
seqForkNode
,
NodeType
.
SEQ
));
final
Node
<
Job
>
subTreeOfJoin
=
constructTree
(
jobDag
,
seqJoinNode
,
joinJob
,
tree
,
final
Node
<
Subtask
>
subTreeOfJoin
=
constructTree
(
jobDag
,
seqJoinNode
,
joinJob
,
tree
,
forkVertices
,
joinVertices
,
sinkJob
);
forkVertices
,
joinVertices
,
sinkJob
);
seqJoinNode
.
setRightNode
(
subTreeOfJoin
);
seqJoinNode
.
setRightNode
(
subTreeOfJoin
);
parContinuationNode
=
parContinuationNode
=
seqJoinNode
.
setLeftNode
(
new
Node
<
Job
>(
seqJoinNode
,
NodeType
.
PAR
));
seqJoinNode
.
setLeftNode
(
new
Node
<
Subtask
>(
seqJoinNode
,
NodeType
.
PAR
));
}
else
{
}
else
{
parContinuationNode
=
parContinuationNode
=
seqForkNode
.
setRightNode
(
new
Node
<
Job
>(
seqForkNode
,
NodeType
.
PAR
));
seqForkNode
.
setRightNode
(
new
Node
<
Subtask
>(
seqForkNode
,
NodeType
.
PAR
));
}
}
Node
<
Job
>
successorParent
=
parContinuationNode
;
Node
<
Subtask
>
successorParent
=
parContinuationNode
;
final
List
<
Job
>
successors
=
Graphs
.
successorListOf
(
jobDag
,
currentJob
);
final
List
<
Subtask
>
successors
=
Graphs
.
successorListOf
(
jobDag
,
currentJob
);
// create leftSide of joinNode
// create leftSide of joinNode
for
(
int
i
=
0
;
i
<
successors
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
successors
.
size
();
++
i
)
{
final
Job
succ
=
successors
.
get
(
i
);
final
Subtask
succ
=
successors
.
get
(
i
);
final
Node
<
Job
>
thisNode
=
constructTree
(
jobDag
,
successorParent
,
succ
,
tree
,
final
Node
<
Subtask
>
thisNode
=
constructTree
(
jobDag
,
successorParent
,
succ
,
tree
,
forkVertices
,
joinVertices
,
sinkJob
);
forkVertices
,
joinVertices
,
sinkJob
);
if
(
i
==
successors
.
size
()
-
1
)
{
if
(
i
==
successors
.
size
()
-
1
)
{
successorParent
.
setRightNode
(
thisNode
);
successorParent
.
setRightNode
(
thisNode
);
...
@@ -267,22 +267,22 @@ public class DagUtils {
...
@@ -267,22 +267,22 @@ public class DagUtils {
return
seqForkNode
;
return
seqForkNode
;
}
else
{
}
else
{
final
List
<
Job
>
successorList
=
Graphs
.
successorListOf
(
jobDag
,
currentJob
);
final
List
<
Subtask
>
successorList
=
Graphs
.
successorListOf
(
jobDag
,
currentJob
);
if
(
successorList
.
size
()
>
0
)
{
if
(
successorList
.
size
()
>
0
)
{
final
Job
successor
=
successorList
.
get
(
0
);
final
Subtask
successor
=
successorList
.
get
(
0
);
if
(!
tree
.
contains
(
successor
))
{
if
(!
tree
.
contains
(
successor
))
{
final
Node
<
Job
>
seqJobNode
=
new
Node
<
Job
>(
parentNode
,
NodeType
.
SEQ
);
final
Node
<
Subtask
>
seqJobNode
=
new
Node
<
Subtask
>(
parentNode
,
NodeType
.
SEQ
);
if
(
tree
.
isEmpty
())
{
if
(
tree
.
isEmpty
())
{
tree
.
setRoot
(
seqJobNode
);
tree
.
setRoot
(
seqJobNode
);
}
}
seqJobNode
.
setLeftNode
(
new
Node
<
Job
>(
seqJobNode
,
currentJob
));
seqJobNode
.
setLeftNode
(
new
Node
<
Subtask
>(
seqJobNode
,
currentJob
));
final
Node
<
Job
>
contNode
=
constructTree
(
jobDag
,
seqJobNode
,
successor
,
tree
,
final
Node
<
Subtask
>
contNode
=
constructTree
(
jobDag
,
seqJobNode
,
successor
,
tree
,
forkVertices
,
joinVertices
,
sinkJob
);
forkVertices
,
joinVertices
,
sinkJob
);
seqJobNode
.
setRightNode
(
contNode
);
seqJobNode
.
setRightNode
(
contNode
);
return
seqJobNode
;
return
seqJobNode
;
}
}
}
}
final
Node
<
Job
>
jobNode
=
new
Node
<
Job
>(
parentNode
,
currentJob
);
final
Node
<
Subtask
>
jobNode
=
new
Node
<
Subtask
>(
parentNode
,
currentJob
);
if
(
tree
.
isEmpty
())
{
if
(
tree
.
isEmpty
())
{
tree
.
setRoot
(
jobNode
);
tree
.
setRoot
(
jobNode
);
}
}
...
@@ -292,20 +292,20 @@ public class DagUtils {
...
@@ -292,20 +292,20 @@ public class DagUtils {
private
static
Job
findJoin
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
private
static
Subtask
findJoin
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
,
final
Job
forkNode
,
final
Job
sink
,
final
List
<
Job
>
joinNodes
)
{
final
Subtask
forkNode
,
final
Subtask
sink
,
final
List
<
Subtask
>
joinNodes
)
{
for
(
final
Job
j
:
joinNodes
)
{
for
(
final
Subtask
j
:
joinNodes
)
{
final
Set
<
Job
>
ancestorsOfJ
=
jobDag
.
getAncestors
(
jobDag
,
j
);
final
Set
<
Subtask
>
ancestorsOfJ
=
jobDag
.
getAncestors
(
jobDag
,
j
);
final
Set
<
Job
>
ancestorsOfFork
=
jobDag
.
getAncestors
(
jobDag
,
forkNode
);
final
Set
<
Subtask
>
ancestorsOfFork
=
jobDag
.
getAncestors
(
jobDag
,
forkNode
);
ancestorsOfFork
.
add
(
forkNode
);
ancestorsOfFork
.
add
(
forkNode
);
final
Set
<
Job
>
inbetweenJobs
=
new
HashSet
<>(
ancestorsOfJ
);
final
Set
<
Subtask
>
inbetweenJobs
=
new
HashSet
<>(
ancestorsOfJ
);
inbetweenJobs
.
removeAll
(
ancestorsOfFork
);
inbetweenJobs
.
removeAll
(
ancestorsOfFork
);
inbetweenJobs
.
add
(
j
);
inbetweenJobs
.
add
(
j
);
if
(
inbetweenJobs
.
isEmpty
())
{
if
(
inbetweenJobs
.
isEmpty
())
{
continue
;
continue
;
}
}
final
List
<
Job
>
successorOfFork
=
Graphs
.
successorListOf
(
jobDag
,
forkNode
);
final
List
<
Subtask
>
successorOfFork
=
Graphs
.
successorListOf
(
jobDag
,
forkNode
);
if
(
inbetweenJobs
.
containsAll
(
successorOfFork
))
{
if
(
inbetweenJobs
.
containsAll
(
successorOfFork
))
{
return
j
;
return
j
;
...
@@ -316,9 +316,9 @@ public class DagUtils {
...
@@ -316,9 +316,9 @@ public class DagUtils {
}
}
public
static
boolean
checkNFJProperty
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
public
static
boolean
checkNFJProperty
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
)
{
final
LinkedList
<
Job
>
joinNodes
=
new
LinkedList
<>();
final
LinkedList
<
Subtask
>
joinNodes
=
new
LinkedList
<>();
final
LinkedList
<
Job
>
forkNodes
=
new
LinkedList
<>();
final
LinkedList
<
Subtask
>
forkNodes
=
new
LinkedList
<>();
collectForksAndJoins
(
jobDag
,
forkNodes
,
joinNodes
);
collectForksAndJoins
(
jobDag
,
forkNodes
,
joinNodes
);
...
@@ -326,19 +326,19 @@ public class DagUtils {
...
@@ -326,19 +326,19 @@ public class DagUtils {
return
true
;
return
true
;
}
}
nextJoin:
for
(
final
Job
j
:
joinNodes
)
{
nextJoin:
for
(
final
Subtask
j
:
joinNodes
)
{
nextFork:
for
(
final
Job
f
:
forkNodes
)
{
nextFork:
for
(
final
Subtask
f
:
forkNodes
)
{
final
Set
<
Job
>
ancestorsOfJ
=
jobDag
.
getAncestors
(
jobDag
,
j
);
final
Set
<
Subtask
>
ancestorsOfJ
=
jobDag
.
getAncestors
(
jobDag
,
j
);
final
Set
<
Job
>
descendantsOfF
=
jobDag
.
getDescendants
(
jobDag
,
f
);
final
Set
<
Subtask
>
descendantsOfF
=
jobDag
.
getDescendants
(
jobDag
,
f
);
final
Set
<
Job
>
inbetweenJobs
=
new
HashSet
<>(
ancestorsOfJ
);
final
Set
<
Subtask
>
inbetweenJobs
=
new
HashSet
<>(
ancestorsOfJ
);
inbetweenJobs
.
retainAll
(
descendantsOfF
);
inbetweenJobs
.
retainAll
(
descendantsOfF
);
if
(
inbetweenJobs
.
isEmpty
())
{
if
(
inbetweenJobs
.
isEmpty
())
{
continue
;
continue
;
}
}
for
(
final
Job
a
:
inbetweenJobs
)
{
for
(
final
Subtask
a
:
inbetweenJobs
)
{
final
List
<
Job
>
neighboursOfA
=
Graphs
.
neighborListOf
(
jobDag
,
a
);
final
List
<
Subtask
>
neighboursOfA
=
Graphs
.
neighborListOf
(
jobDag
,
a
);
for
(
final
Job
b
:
neighboursOfA
)
{
for
(
final
Subtask
b
:
neighboursOfA
)
{
if
((
jobDag
.
getAncestors
(
jobDag
,
j
).
contains
(
b
)
||
b
==
j
)
if
((
jobDag
.
getAncestors
(
jobDag
,
j
).
contains
(
b
)
||
b
==
j
)
&&
(
jobDag
.
getDescendants
(
jobDag
,
f
).
contains
(
b
)
||
b
==
f
))
{
&&
(
jobDag
.
getDescendants
(
jobDag
,
f
).
contains
(
b
)
||
b
==
f
))
{
// this b is ok
// this b is ok
...
@@ -355,9 +355,9 @@ public class DagUtils {
...
@@ -355,9 +355,9 @@ public class DagUtils {
return
true
;
return
true
;
}
}
public
static
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
createNFJfromDecompositionTree
(
public
static
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
createNFJfromDecompositionTree
(
final
BinaryDecompositionTree
<
Job
>
tree
)
{
final
BinaryDecompositionTree
<
Subtask
>
tree
)
{
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
=
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
if
(
tree
.
getRootNode
()
!=
null
)
{
if
(
tree
.
getRootNode
()
!=
null
)
{
...
@@ -368,20 +368,20 @@ public class DagUtils {
...
@@ -368,20 +368,20 @@ public class DagUtils {
}
}
private
static
GraphEndPoints
traverseNodes
(
final
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
private
static
GraphEndPoints
traverseNodes
(
final
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
,
final
Node
<
Job
>
node
)
{
final
Node
<
Subtask
>
node
)
{
switch
(
node
.
getNodeType
())
{
switch
(
node
.
getNodeType
())
{
case
LEAF:
{
case
LEAF:
{
final
Job
j
=
node
.
getObject
();
final
Subtask
j
=
node
.
getObject
();
jobDag
.
addVertex
(
j
);
jobDag
.
addVertex
(
j
);
final
Set
<
Job
>
endPoints
=
new
HashSet
<
Job
>(
Arrays
.
asList
(
j
));
final
Set
<
Subtask
>
endPoints
=
new
HashSet
<
Subtask
>(
Arrays
.
asList
(
j
));
return
new
GraphEndPoints
(
endPoints
,
endPoints
);
return
new
GraphEndPoints
(
endPoints
,
endPoints
);
}
}
case
SEQ:
{
case
SEQ:
{
final
GraphEndPoints
leftEndPoints
=
traverseNodes
(
jobDag
,
node
.
getLeftNode
());
final
GraphEndPoints
leftEndPoints
=
traverseNodes
(
jobDag
,
node
.
getLeftNode
());
final
GraphEndPoints
rightEndPoints
=
traverseNodes
(
jobDag
,
node
.
getRightNode
());
final
GraphEndPoints
rightEndPoints
=
traverseNodes
(
jobDag
,
node
.
getRightNode
());
for
(
final
Job
l
:
leftEndPoints
.
right
)
{
for
(
final
Subtask
l
:
leftEndPoints
.
right
)
{
for
(
final
Job
r
:
rightEndPoints
.
left
)
{
for
(
final
Subtask
r
:
rightEndPoints
.
left
)
{
if
(
r
==
l
)
{
if
(
r
==
l
)
{
continue
;
continue
;
}
}
...
@@ -397,9 +397,9 @@ public class DagUtils {
...
@@ -397,9 +397,9 @@ public class DagUtils {
case
PAR:
{
case
PAR:
{
final
GraphEndPoints
leftEndPoints
=
traverseNodes
(
jobDag
,
node
.
getLeftNode
());
final
GraphEndPoints
leftEndPoints
=
traverseNodes
(
jobDag
,
node
.
getLeftNode
());
final
GraphEndPoints
rightEndPoints
=
traverseNodes
(
jobDag
,
node
.
getRightNode
());
final
GraphEndPoints
rightEndPoints
=
traverseNodes
(
jobDag
,
node
.
getRightNode
());
final
Set
<
Job
>
leftEndPointJobs
=
final
Set
<
Subtask
>
leftEndPointJobs
=
Sets
.
newHashSet
(
Iterables
.
concat
(
leftEndPoints
.
left
,
rightEndPoints
.
left
));
Sets
.
newHashSet
(
Iterables
.
concat
(
leftEndPoints
.
left
,
rightEndPoints
.
left
));
final
Set
<
Job
>
rightEndPointJobs
=
Sets
final
Set
<
Subtask
>
rightEndPointJobs
=
Sets
.
newHashSet
(
Iterables
.
concat
(
leftEndPoints
.
right
,
rightEndPoints
.
right
));
.
newHashSet
(
Iterables
.
concat
(
leftEndPoints
.
right
,
rightEndPoints
.
right
));
return
new
GraphEndPoints
(
leftEndPointJobs
,
rightEndPointJobs
);
return
new
GraphEndPoints
(
leftEndPointJobs
,
rightEndPointJobs
);
}
}
...
@@ -410,10 +410,10 @@ public class DagUtils {
...
@@ -410,10 +410,10 @@ public class DagUtils {
}
}
public
static
class
GraphEndPoints
{
public
static
class
GraphEndPoints
{
public
Set
<
Job
>
left
;
public
Set
<
Subtask
>
left
;
public
Set
<
Job
>
right
;
public
Set
<
Subtask
>
right
;
public
GraphEndPoints
(
final
Set
<
Job
>
left
,
final
Set
<
Job
>
right
)
{
public
GraphEndPoints
(
final
Set
<
Subtask
>
left
,
final
Set
<
Subtask
>
right
)
{
this
.
left
=
left
;
this
.
left
=
left
;
this
.
right
=
right
;
this
.
right
=
right
;
}
}
...
...
This diff is collapsed.
Click to expand it.
src/test/java/mvd/jester/model/TestDagUtils.java
View file @
cfdd3254
...
@@ -16,15 +16,15 @@ public class TestDagUtils {
...
@@ -16,15 +16,15 @@ public class TestDagUtils {
@Test
@Test
@DisplayName
(
"Test if dynamic segments are constructed correctly."
)
@DisplayName
(
"Test if dynamic segments are constructed correctly."
)
public
void
checkPathLength
()
{
public
void
checkPathLength
()
{
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
createJobDag
();
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
=
createJobDag
();
long
criticalPath
=
DagUtils
.
calculateCriticalPath
(
jobDag
);
long
criticalPath
=
DagUtils
.
calculateCriticalPath
(
jobDag
);
for
(
Job
j
:
jobDag
)
{
for
(
Subtask
j
:
jobDag
)
{
assertTrue
(
j
.
getRelativeCompletionTime
()
<=
criticalPath
);
assertTrue
(
j
.
getRelativeCompletionTime
()
<=
criticalPath
);
}
}
for
(
DefaultEdge
e
:
jobDag
.
edgeSet
())
{
for
(
DefaultEdge
e
:
jobDag
.
edgeSet
())
{
Job
source
=
jobDag
.
getEdgeSource
(
e
);
Subtask
source
=
jobDag
.
getEdgeSource
(
e
);
Job
target
=
jobDag
.
getEdgeTarget
(
e
);
Subtask
target
=
jobDag
.
getEdgeTarget
(
e
);
assertTrue
(
source
.
getRelativeCompletionTime
()
<
target
.
getRelativeCompletionTime
());
assertTrue
(
source
.
getRelativeCompletionTime
()
<
target
.
getRelativeCompletionTime
());
}
}
...
@@ -39,7 +39,7 @@ public class TestDagUtils {
...
@@ -39,7 +39,7 @@ public class TestDagUtils {
DagTaskBuilder
b
=
new
DagTaskBuilder
();
DagTaskBuilder
b
=
new
DagTaskBuilder
();
DagTask
t
=
b
.
generateTask
();
DagTask
t
=
b
.
generateTask
();
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
nfjDag
=
DagUtils
.
createNFJGraph
(
t
.
getJobDag
());
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
nfjDag
=
DagUtils
.
createNFJGraph
(
t
.
getJobDag
());
assertTrue
(
DagUtils
.
checkNFJProperty
(
nfjDag
));
assertTrue
(
DagUtils
.
checkNFJProperty
(
nfjDag
));
}
}
...
@@ -53,11 +53,11 @@ public class TestDagUtils {
...
@@ -53,11 +53,11 @@ public class TestDagUtils {
long
numberOfProcessors
=
ThreadLocalRandom
.
current
().
nextLong
(
4
,
16
);
long
numberOfProcessors
=
ThreadLocalRandom
.
current
().
nextLong
(
4
,
16
);
DagTaskBuilder
b
=
new
DagTaskBuilder
().
setNumberOfProcessors
(
numberOfProcessors
);
DagTaskBuilder
b
=
new
DagTaskBuilder
().
setNumberOfProcessors
(
numberOfProcessors
);
DagTask
t
=
b
.
generateTask
();
DagTask
t
=
b
.
generateTask
();
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
t
.
getJobDag
();
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
=
t
.
getJobDag
();
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
nfjJobDag
=
DagUtils
.
createNFJGraph
(
jobDag
);
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
nfjJobDag
=
DagUtils
.
createNFJGraph
(
jobDag
);
BinaryDecompositionTree
<
Job
>
tree
=
DagUtils
.
createDecompositionTree
(
nfjJobDag
);
BinaryDecompositionTree
<
Subtask
>
tree
=
DagUtils
.
createDecompositionTree
(
nfjJobDag
);
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDagFromTree
=
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDagFromTree
=
DagUtils
.
createNFJfromDecompositionTree
(
tree
);
DagUtils
.
createNFJfromDecompositionTree
(
tree
);
assertTrue
(
jobDag
.
vertexSet
().
size
()
==
nfjJobDag
.
vertexSet
().
size
());
assertTrue
(
jobDag
.
vertexSet
().
size
()
==
nfjJobDag
.
vertexSet
().
size
());
...
@@ -65,14 +65,14 @@ public class TestDagUtils {
...
@@ -65,14 +65,14 @@ public class TestDagUtils {
assertTrue
(
jobDagFromTree
.
edgeSet
().
size
()
==
nfjJobDag
.
edgeSet
().
size
());
assertTrue
(
jobDagFromTree
.
edgeSet
().
size
()
==
nfjJobDag
.
edgeSet
().
size
());
for
(
DefaultEdge
e
:
nfjJobDag
.
edgeSet
())
{
for
(
DefaultEdge
e
:
nfjJobDag
.
edgeSet
())
{
Job
target
=
nfjJobDag
.
getEdgeTarget
(
e
);
Subtask
target
=
nfjJobDag
.
getEdgeTarget
(
e
);
Job
source
=
nfjJobDag
.
getEdgeSource
(
e
);
Subtask
source
=
nfjJobDag
.
getEdgeSource
(
e
);
assertTrue
(
jobDagFromTree
.
containsEdge
(
source
,
target
));
assertTrue
(
jobDagFromTree
.
containsEdge
(
source
,
target
));
}
}
for
(
Job
j
:
nfjJobDag
)
{
for
(
Subtask
j
:
nfjJobDag
)
{
for
(
Job
n
:
nfjJobDag
)
{
for
(
Subtask
n
:
nfjJobDag
)
{
if
(
n
==
j
)
{
if
(
n
==
j
)
{
continue
;
continue
;
}
}
...
@@ -83,19 +83,19 @@ public class TestDagUtils {
...
@@ -83,19 +83,19 @@ public class TestDagUtils {
assertTrue
(
nfjJobDag
.
inDegreeOf
(
j
)
==
jobDagFromTree
.
inDegreeOf
(
j
));
assertTrue
(
nfjJobDag
.
inDegreeOf
(
j
)
==
jobDagFromTree
.
inDegreeOf
(
j
));
assertTrue
(
nfjJobDag
.
outDegreeOf
(
j
)
==
jobDagFromTree
.
outDegreeOf
(
j
));
assertTrue
(
nfjJobDag
.
outDegreeOf
(
j
)
==
jobDagFromTree
.
outDegreeOf
(
j
));
for
(
Job
p
:
Graphs
.
predecessorListOf
(
nfjJobDag
,
j
))
{
for
(
Subtask
p
:
Graphs
.
predecessorListOf
(
nfjJobDag
,
j
))
{
assertTrue
(
Graphs
.
predecessorListOf
(
jobDagFromTree
,
j
).
contains
(
p
));
assertTrue
(
Graphs
.
predecessorListOf
(
jobDagFromTree
,
j
).
contains
(
p
));
}
}
for
(
Job
s
:
Graphs
.
successorListOf
(
nfjJobDag
,
j
))
{
for
(
Subtask
s
:
Graphs
.
successorListOf
(
nfjJobDag
,
j
))
{
assertTrue
(
Graphs
.
successorListOf
(
jobDagFromTree
,
j
).
contains
(
s
));
assertTrue
(
Graphs
.
successorListOf
(
jobDagFromTree
,
j
).
contains
(
s
));
}
}
for
(
Job
a
:
nfjJobDag
.
getAncestors
(
nfjJobDag
,
j
))
{
for
(
Subtask
a
:
nfjJobDag
.
getAncestors
(
nfjJobDag
,
j
))
{
assertTrue
(
jobDagFromTree
.
getAncestors
(
jobDagFromTree
,
j
).
contains
(
a
));
assertTrue
(
jobDagFromTree
.
getAncestors
(
jobDagFromTree
,
j
).
contains
(
a
));
}
}
for
(
Job
d
:
nfjJobDag
.
getDescendants
(
nfjJobDag
,
j
))
{
for
(
Subtask
d
:
nfjJobDag
.
getDescendants
(
nfjJobDag
,
j
))
{
assertTrue
(
jobDagFromTree
.
getDescendants
(
jobDagFromTree
,
j
).
contains
(
d
));
assertTrue
(
jobDagFromTree
.
getDescendants
(
jobDagFromTree
,
j
).
contains
(
d
));
}
}
}
}
...
@@ -105,35 +105,35 @@ public class TestDagUtils {
...
@@ -105,35 +105,35 @@ public class TestDagUtils {
}
}
private
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
createJobDag
()
{
private
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
createJobDag
()
{
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
=
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
Job
source
=
new
Job
(
20
);
Subtask
source
=
new
Subtask
(
20
);
Job
pathA
=
new
Job
(
10
);
Subtask
pathA
=
new
Subtask
(
10
);
Job
pathB
=
new
Job
(
30
);
Subtask
pathB
=
new
Subtask
(
30
);
Job
pathC
=
new
Job
(
40
);
Subtask
pathC
=
new
Subtask
(
40
);
Job
child1OfA
=
new
Job
(
5
);
Subtask
child1OfA
=
new
Subtask
(
5
);
Job
child2OfA
=
new
Job
(
15
);
Subtask
child2OfA
=
new
Subtask
(
15
);
Job
child3OfA
=
new
Job
(
5
);
Subtask
child3OfA
=
new
Subtask
(
5
);
Job
childsOfAJoin
=
new
Job
(
10
);
Subtask
childsOfAJoin
=
new
Subtask
(
10
);
Job
child1OfC
=
new
Job
(
5
);
Subtask
child1OfC
=
new
Subtask
(
5
);
Job
child2OfC
=
new
Job
(
10
);
Subtask
child2OfC
=
new
Subtask
(
10
);
Job
child3OfC
=
new
Job
(
15
);
Subtask
child3OfC
=
new
Subtask
(
15
);
Job
child4OfC
=
new
Job
(
20
);
Subtask
child4OfC
=
new
Subtask
(
20
);
Job
firstJoin
=
new
Job
(
20
);
Subtask
firstJoin
=
new
Subtask
(
20
);
Job
intermediateFork
=
new
Job
(
10
);
Subtask
intermediateFork
=
new
Subtask
(
10
);
Job
forkChild1
=
new
Job
(
5
);
Subtask
forkChild1
=
new
Subtask
(
5
);
Job
forkChild2
=
new
Job
(
10
);
Subtask
forkChild2
=
new
Subtask
(
10
);
Job
forkChild3
=
new
Job
(
15
);
Subtask
forkChild3
=
new
Subtask
(
15
);
Job
sink
=
new
Job
(
30
);
Subtask
sink
=
new
Subtask
(
30
);
try
{
try
{
jobDag
.
addVertex
(
source
);
jobDag
.
addVertex
(
source
);
jobDag
.
addVertex
(
pathA
);
jobDag
.
addVertex
(
pathA
);
...
...
This diff is collapsed.
Click to expand it.
src/test/java/mvd/jester/model/TestSystemSetup.java
View file @
cfdd3254
...
@@ -75,12 +75,12 @@ public class TestSystemSetup {
...
@@ -75,12 +75,12 @@ public class TestSystemSetup {
for
(
int
i
=
0
;
i
<
100
;
++
i
)
{
for
(
int
i
=
0
;
i
<
100
;
++
i
)
{
DagTaskBuilder
builder
=
new
DagTaskBuilder
();
DagTaskBuilder
builder
=
new
DagTaskBuilder
();
DagTask
task
=
builder
.
generateTask
();
DagTask
task
=
builder
.
generateTask
();
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
task
.
getJobDag
();
DirectedAcyclicGraph
<
Subtask
,
DefaultEdge
>
jobDag
=
task
.
getJobDag
();
assertTrue
(
task
.
getCriticalPath
()
<=
task
.
getPeriod
());
assertTrue
(
task
.
getCriticalPath
()
<=
task
.
getPeriod
());
assertTrue
(
task
.
getPeriod
()
<=
(
long
)
(
task
.
getWorkload
()
/
builder
.
getBeta
()));
assertTrue
(
task
.
getPeriod
()
<=
(
long
)
(
task
.
getWorkload
()
/
builder
.
getBeta
()));
for
(
Job
j
:
jobDag
)
{
for
(
Subtask
j
:
jobDag
)
{
assertTrue
(
1
<=
j
.
getWcet
()
&&
j
.
getWcet
()
<=
100
);
assertTrue
(
1
<=
j
.
getWcet
()
&&
j
.
getWcet
()
<=
100
);
assertTrue
(
j
.
getRelativeCompletionTime
()
<=
task
.
getCriticalPath
());
assertTrue
(
j
.
getRelativeCompletionTime
()
<=
task
.
getCriticalPath
());
if
(
jobDag
.
outDegreeOf
(
j
)
==
0
)
{
if
(
jobDag
.
outDegreeOf
(
j
)
==
0
)
{
...
@@ -88,8 +88,8 @@ public class TestSystemSetup {
...
@@ -88,8 +88,8 @@ public class TestSystemSetup {
}
}
}
}
for
(
DefaultEdge
e
:
jobDag
.
edgeSet
())
{
for
(
DefaultEdge
e
:
jobDag
.
edgeSet
())
{
Job
source
=
jobDag
.
getEdgeSource
(
e
);
Subtask
source
=
jobDag
.
getEdgeSource
(
e
);
Job
target
=
jobDag
.
getEdgeTarget
(
e
);
Subtask
target
=
jobDag
.
getEdgeTarget
(
e
);
assertTrue
(
source
.
getRelativeCompletionTime
()
<
target
.
getRelativeCompletionTime
());
assertTrue
(
source
.
getRelativeCompletionTime
()
<
target
.
getRelativeCompletionTime
());
}
}
}
}
...
...
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