Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qpme-core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
2
Issues
2
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Descartes Research
qpme-core
Commits
95a621d4
Commit
95a621d4
authored
Dec 01, 2017
by
Simon Eismann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
integrated priority scheduling
parent
af73d431
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
194 additions
and
17 deletions
+194
-17
sources/qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/Place.java
...qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/Place.java
+22
-4
sources/qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/QPlace.java
...pme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/QPlace.java
+1
-0
sources/qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/Queue.java
...qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/Queue.java
+92
-3
sources/qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/Simulator.java
....simqpn.kernel/src/de/tud/cs/simqpn/kernel/Simulator.java
+27
-7
sources/qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/TokenPrioComparator.java
...rnel/src/de/tud/cs/simqpn/kernel/TokenPrioComparator.java
+16
-0
sources/qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/Transition.java
...simqpn.kernel/src/de/tud/cs/simqpn/kernel/Transition.java
+36
-3
No files found.
sources/qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/Place.java
View file @
95a621d4
...
...
@@ -58,6 +58,7 @@ package de.tud.cs.simqpn.kernel;
import
java.util.Arrays
;
import
java.util.LinkedList
;
import
java.util.Random
;
import
org.apache.log4j.Logger
;
import
org.dom4j.Element
;
...
...
@@ -74,6 +75,7 @@ public class Place extends Node {
// Supported departure disciplines (depDiscip):
public
static
final
int
NORMAL
=
0
;
// Arriving tokens become available for output transitions immediately upon arrival.
public
static
final
int
FIFO
=
1
;
// First-In-First-Out: Arriving tokens become available for output transitions in the order of their arrival.
public
static
final
int
RANDOM
=
3
;
// First-In-First-Out: Arriving tokens become available for output transitions randomly.
// Supported probe actions
public
static
final
int
PROBE_ACTION_NONE
=
0
;
...
...
@@ -89,6 +91,7 @@ public class Place extends Node {
public
int
numColors
;
public
String
[]
colors
;
// Names of the colors that can reside in this Place.
public
int
[]
priorities
;
//priority of each color
public
int
statsLevel
;
// Determines the amount of statistics to be gathered during the run.
public
int
depDiscip
;
// Departure discipline.
@SuppressWarnings
(
"rawtypes"
)
...
...
@@ -135,6 +138,7 @@ public class Place extends Node {
super
(
id
,
name
);
this
.
colors
=
colors
;
this
.
numColors
=
colors
.
length
;
this
.
priorities
=
new
int
[
colors
.
length
];
this
.
inTrans
=
new
Transition
[
numInTrans
];
this
.
outTrans
=
new
Transition
[
numOutTrans
];
this
.
tokenPop
=
new
int
[
numColors
];
...
...
@@ -152,7 +156,7 @@ public class Place extends Node {
this
.
tokenPop
[
c
]
=
0
;
this
.
availTokens
[
c
]
=
0
;
}
if
(
depDiscip
==
FIFO
)
{
if
(
depDiscip
==
FIFO
||
depDiscip
==
RANDOM
)
{
this
.
depQueue
=
new
LinkedList
();
this
.
depReady
=
false
;
}
...
...
@@ -191,7 +195,7 @@ public class Place extends Node {
if
(
depDiscip
==
NORMAL
)
{
availTokens
=
tokenPop
;
//Note: from here on, availTokens and tokenPop point to the same array!
}
else
if
(
depDiscip
==
FIFO
)
{
else
if
(
depDiscip
==
FIFO
||
depDiscip
==
RANDOM
)
{
int
totTkPop
=
0
;
int
[]
tkPop
=
new
int
[
numColors
];
for
(
int
c
=
0
;
c
<
numColors
;
c
++)
{
...
...
@@ -327,7 +331,7 @@ public class Place extends Node {
for
(
int
i
=
0
;
i
<
outTrans
.
length
;
i
++)
outTrans
[
i
].
updateState
(
id
,
color
,
tokenPop
[
color
],
count
);
}
else
if
(
depDiscip
==
FIFO
)
{
else
if
(
depDiscip
==
FIFO
||
depDiscip
==
RANDOM
)
{
if
(
depReady
)
{
for
(
int
i
=
0
;
i
<
count
;
i
++)
depQueue
.
addLast
(
new
Integer
(
color
));
...
...
@@ -406,6 +410,20 @@ public class Place extends Node {
}
else
depReady
=
false
;
}
else
if
(
depDiscip
==
RANDOM
)
{
availTokens
[
color
]
-=
count
;
for
(
int
i
=
0
;
i
<
outTrans
.
length
;
i
++)
outTrans
[
i
].
updateState
(
id
,
color
,
availTokens
[
color
],
(-
1
)*
count
);
if
(
depQueue
.
size
()
>
0
)
{
Random
rand
=
new
Random
();
int
nextCol
=
((
Integer
)
depQueue
.
remove
(
rand
.
nextInt
(
depQueue
.
size
()))).
intValue
();
availTokens
[
nextCol
]++;
depReady
=
true
;
// Left for clarity. Actually redundant since depReady should already be true.
for
(
int
i
=
0
;
i
<
outTrans
.
length
;
i
++)
outTrans
[
i
].
updateState
(
id
,
nextCol
,
availTokens
[
nextCol
],
1
);
}
else
depReady
=
false
;
}
else
{
log
.
error
(
"Invalid depDiscip specified for place "
+
name
);
throw
new
SimQPNException
();
...
...
@@ -465,5 +483,5 @@ public class Place extends Node {
}
}
}
}
sources/qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/QPlace.java
View file @
95a621d4
...
...
@@ -61,6 +61,7 @@
package
de.tud.cs.simqpn.kernel
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
org.apache.log4j.Logger
;
import
org.dom4j.Element
;
...
...
sources/qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/Queue.java
View file @
95a621d4
...
...
@@ -44,12 +44,16 @@
* 2009/08/03 Frederik Zipp Added xmlId property.
* 2009/05/05 Frederik Zipp Support for central queues.
* 2010/07/24 Simon Spinner Support for tracking tokens.
* 2013/06/25 Mehran Saliminia Added RANDOM discipline.
*
*/
package
de.tud.cs.simqpn.kernel
;
import
java.util.Comparator
;
import
java.util.LinkedList
;
import
java.util.PriorityQueue
;
import
java.util.Random
;
import
org.apache.log4j.Logger
;
...
...
@@ -74,6 +78,8 @@ public class Queue {
public
static
final
int
IS
=
0
;
public
static
final
int
FCFS
=
1
;
public
static
final
int
PS
=
2
;
public
static
final
int
RANDOM
=
3
;
public
static
final
int
PRIO
=
4
;
private
static
Logger
log
=
Logger
.
getLogger
(
Queue
.
class
);
...
...
@@ -89,7 +95,11 @@ public class Queue {
public
int
numServers
;
// FCFS queues: Number of servers in queueing station.
public
int
numBusyServers
;
// FCFS queues: Number of currently busy servers.
public
LinkedList
waitingLine
;
// FCFS queues: List of tokens waiting for service (waiting area of the queue).
public
LinkedList
waitingLine
;
// FCFS queues: List of tokens waiting for service (waiting area of the queue).
public
Comparator
<
Token
>
comparator
;
// PRIO queues comparator
public
PriorityQueue
<
Token
>
priorityQueue
;
// PRIO queues: List of tokens waiting for service (waiting area of the queue).
public
boolean
eventsUpToDate
;
// PS queues: True if currently scheduled events for this queue (if any)
// reflect the latest token popolation of the queue.
...
...
@@ -137,8 +147,8 @@ public class Queue {
this
.
totNumColors
=
0
;
this
.
statsLevel
=
0
;
// FCFS Queues
if
(
queueDiscip
==
FCFS
)
{
// FCFS
/RANDOM
Queues
if
(
queueDiscip
==
FCFS
||
queueDiscip
==
RANDOM
)
{
this
.
numBusyServers
=
0
;
this
.
waitingLine
=
new
LinkedList
();
}
...
...
@@ -148,6 +158,13 @@ public class Queue {
eventScheduled
=
false
;
expPS
=
false
;
// By default non-exponential queue is assumed.
}
// PRIO Queues
if
(
queueDiscip
==
PRIO
)
{
this
.
numBusyServers
=
0
;
this
.
comparator
=
new
TokenPrioComparator
();
this
.
priorityQueue
=
new
PriorityQueue
<
Token
>(
2
,
comparator
);
}
}
/**
...
...
@@ -518,6 +535,50 @@ public class Queue {
n
++;
}
}
else
if
(
queueDiscip
==
RANDOM
)
{
int
n
=
0
;
while
(
n
<
count
&&
numBusyServers
<
numServers
)
{
// Schedule service completion event
double
servTime
=
qPl
.
randServTimeGen
[
color
].
nextDouble
();
if
(
servTime
<
0
)
servTime
=
0
;
Token
tk
=
(
tokensToBeAdded
!=
null
)
?
tokensToBeAdded
[
n
]
:
new
Token
(
qPl
,
color
);
tk
.
arrivTS
=
Simulator
.
clock
;
Simulator
.
scheduleEvent
(
Simulator
.
clock
+
servTime
,
this
,
tk
);
numBusyServers
++;
n
++;
// Update Stats
if
(
qPl
.
statsLevel
>=
3
)
qPl
.
qPlaceQueueStats
.
updateDelayTimeStats
(
color
,
0
);
}
while
(
n
<
count
)
{
// Place the rest of the tokens in the waitingLine
Token
tk
=
(
tokensToBeAdded
!=
null
)
?
tokensToBeAdded
[
n
]
:
new
Token
(
qPl
,
color
);
tk
.
arrivTS
=
Simulator
.
clock
;
waitingLine
.
addLast
(
tk
);
n
++;
}
}
else
if
(
queueDiscip
==
PRIO
)
{
int
n
=
0
;
while
(
n
<
count
&&
numBusyServers
<
numServers
)
{
// Schedule service completion event
double
servTime
=
qPl
.
randServTimeGen
[
color
].
nextDouble
();
if
(
servTime
<
0
)
servTime
=
0
;
Token
tk
=
(
tokensToBeAdded
!=
null
)
?
tokensToBeAdded
[
n
]
:
new
Token
(
qPl
,
color
);
tk
.
arrivTS
=
Simulator
.
clock
;
Simulator
.
scheduleEvent
(
Simulator
.
clock
+
servTime
,
this
,
tk
);
numBusyServers
++;
n
++;
// Update Stats
if
(
qPl
.
statsLevel
>=
3
)
qPl
.
qPlaceQueueStats
.
updateDelayTimeStats
(
color
,
0
);
}
while
(
n
<
count
)
{
// Place the rest of the tokens in the priorityQueue
Token
tk
=
(
tokensToBeAdded
!=
null
)
?
tokensToBeAdded
[
n
]
:
new
Token
(
qPl
,
color
);
tk
.
arrivTS
=
Simulator
.
clock
;
priorityQueue
.
add
(
tk
);
n
++;
}
}
else
if
(
queueDiscip
==
PS
)
{
if
(!
expPS
)
{
if
(
eventScheduled
)
updateResidServTimes
();
//NOTE: WATCH OUT! Method should be called before the new tokens have been added to queueTokResidServTimes!
...
...
@@ -574,6 +635,34 @@ public class Queue {
}
else
numBusyServers
--;
}
else
if
(
queueDiscip
==
RANDOM
)
{
if
(
waitingLine
.
size
()
>
0
)
{
Random
randomGenerator
=
new
Random
();
int
index
=
randomGenerator
.
nextInt
(
waitingLine
.
size
());
Token
tk
=
(
Token
)
waitingLine
.
remove
(
index
);
QPlace
qPl
=
(
QPlace
)
tk
.
place
;
double
servTime
=
qPl
.
randServTimeGen
[
tk
.
color
].
nextDouble
();
if
(
servTime
<
0
)
servTime
=
0
;
Simulator
.
scheduleEvent
(
Simulator
.
clock
+
servTime
,
this
,
tk
);
// Update stats
if
(
qPl
.
statsLevel
>=
3
)
qPl
.
qPlaceQueueStats
.
updateDelayTimeStats
(
tk
.
color
,
Simulator
.
clock
-
tk
.
arrivTS
);
}
else
numBusyServers
--;
}
else
if
(
queueDiscip
==
PRIO
)
{
if
(!
priorityQueue
.
isEmpty
())
{
Token
tk
=
priorityQueue
.
remove
();
QPlace
qPl
=
(
QPlace
)
tk
.
place
;
double
servTime
=
qPl
.
randServTimeGen
[
tk
.
color
].
nextDouble
();
if
(
servTime
<
0
)
servTime
=
0
;
Simulator
.
scheduleEvent
(
Simulator
.
clock
+
servTime
,
this
,
tk
);
// Update stats
if
(
qPl
.
statsLevel
>=
3
)
qPl
.
qPlaceQueueStats
.
updateDelayTimeStats
(
tk
.
color
,
Simulator
.
clock
-
tk
.
arrivTS
);
}
else
numBusyServers
--;
}
else
if
(
queueDiscip
==
PS
)
{
QPlace
qPl
=
((
QPlace
)
token
.
place
);
if
(!
expPS
)
{
...
...
sources/qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/Simulator.java
View file @
95a621d4
...
...
@@ -546,7 +546,8 @@ public class Simulator {
Stats
[]
result
=
null
;
simRunning
=
true
;
// NOTE: In the following, if the simulation is interrupted, simRunning should be reset.
// NOTE: In the following, if the simulation is interrupted, simRunning should be reset.
long
startTs
=
System
.
currentTimeMillis
();
try
{
validateInputNet
(
net
);
...
...
@@ -603,6 +604,8 @@ public class Simulator {
simRunning
=
false
;
LogManager
.
shutdown
();
}
long
t
=
System
.
currentTimeMillis
()
-
startTs
;
System
.
out
.
println
(
"Simulation Time :"
+
t
+
" ms"
);
return
result
;
}
...
...
@@ -620,7 +623,7 @@ public class Simulator {
xpathSelector
=
createXPath
(
"//color-ref[@priority > 0]"
);
if
(
xpathSelector
.
selectSingleNode
(
net
)
!=
null
)
{
log
.
error
(
"Priority attribute currently not supported (Set to 0 for all places)"
);
throw
new
SimQPNException
();
//
throw new SimQPNException();
}
xpathSelector
=
createXPath
(
"//transition[@priority > 0]"
);
if
(
xpathSelector
.
selectSingleNode
(
net
)
!=
null
)
{
...
...
@@ -3005,6 +3008,10 @@ public class Simulator {
throw
new
SimQPNException
();
}
trans
[
i
].
modeWeights
[
j
]
=
Double
.
parseDouble
(
mode
.
attributeValue
(
"firing-weight"
));
if
(
trans
[
i
].
modeWeights
[
j
]
==
0
)
trans
[
i
].
dynamicModeWeights
[
j
]
=
true
;
else
trans
[
i
].
dynamicModeWeights
[
j
]
=
false
;
log
.
debug
(
"trans["
+
i
+
"].modeWeights["
+
j
+
"] = "
+
trans
[
i
].
modeWeights
[
j
]);
}
}
...
...
@@ -3284,7 +3291,14 @@ public class Simulator {
queueingStrategy
=
Queue
.
FCFS
;
}
else
if
(
"PS"
.
equals
(
queue
.
attributeValue
(
"strategy"
)))
{
queueingStrategy
=
Queue
.
PS
;
}
else
{
}
else
if
(
"RANDOM"
.
equals
(
queue
.
attributeValue
(
"strategy"
)))
{
queueingStrategy
=
Queue
.
RANDOM
;
}
else
if
(
"PRIO"
.
equals
(
queue
.
attributeValue
(
"strategy"
)))
{
queueingStrategy
=
Queue
.
PRIO
;
}
else
{
log
.
error
(
formatDetailMessage
(
"Invalid or missing \"strategy\" (queueing discipline) setting!"
,
"queue-num"
,
Integer
.
toString
(
i
),
...
...
@@ -3385,6 +3399,8 @@ public class Simulator {
dDis
=
Place
.
NORMAL
;
}
else
if
(
"FIFO"
.
equals
(
place
.
attributeValue
(
"departure-discipline"
)))
{
dDis
=
Place
.
FIFO
;
}
else
if
(
"RANDOM"
.
equals
(
place
.
attributeValue
(
"departure-discipline"
)))
{
dDis
=
Place
.
RANDOM
;
}
else
{
log
.
error
(
formatDetailMessage
(
"Invalid departure-discipline setting!"
,
...
...
@@ -3436,13 +3452,16 @@ public class Simulator {
));
throw
new
SimQPNException
();
}
String
[]
colors
=
new
String
[
colorRefs
.
size
()];
String
[]
colors
=
new
String
[
colorRefs
.
size
()];
int
[]
priorities
=
new
int
[
colorRefs
.
size
()];
Iterator
colorRefIterator
=
colorRefs
.
iterator
();
for
(
int
c
=
0
;
colorRefIterator
.
hasNext
();
c
++)
{
Element
colorRef
=
(
Element
)
colorRefIterator
.
next
();
XPath
xpathSelector
=
createXPath
(
"colors/color[(@id='"
+
colorRef
.
attributeValue
(
"color-id"
)
+
"')]"
);
Element
color
=
(
Element
)
xpathSelector
.
selectSingleNode
(
net
);
colors
[
c
]
=
color
.
attributeValue
(
"name"
);
colors
[
c
]
=
color
.
attributeValue
(
"name"
);
priorities
[
c
]
=
(
colorRef
.
attributeValue
(
"priority"
)
==
null
)?
0
:
Integer
.
valueOf
(
colorRef
.
attributeValue
(
"priority"
));
}
if
(
"ordinary-place"
.
equals
(
place
.
attributeValue
(
XSI_TYPE_ATTRIBUTE
)))
{
...
...
@@ -3455,7 +3474,7 @@ public class Simulator {
numProbes
,
statsLevel
,
// stats level
dDis
,
// departure discipline
place
);
// Reference to the place' XML element
place
);
// Reference to the place' XML element
placeToIndexMap
.
put
(
place
,
i
);
if
(
log
.
isDebugEnabled
())
{
log
.
debug
(
"places["
+
i
+
"] = new Place("
...
...
@@ -3483,7 +3502,8 @@ public class Simulator {
statsLevel
,
// stats level
dDis
,
// departure discipline
queue
,
// Reference to the integrated Queue
place
);
// Reference to the place' XML element
place
);
// Reference to the place' XML element
places
[
i
].
priorities
=
priorities
;
placeToIndexMap
.
put
(
place
,
i
);
if
(
log
.
isDebugEnabled
())
{
log
.
debug
(
"places["
+
i
+
"] = new QPlace("
...
...
sources/qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/TokenPrioComparator.java
0 → 100644
View file @
95a621d4
package
de.tud.cs.simqpn.kernel
;
import
java.util.Comparator
;
public
class
TokenPrioComparator
implements
Comparator
<
Token
>
{
@Override
public
int
compare
(
Token
t1
,
Token
t2
)
{
if
(
t1
.
place
.
priorities
[
t1
.
color
]
>
t2
.
place
.
priorities
[
t2
.
color
])
return
-
1
;
if
(
t1
.
place
.
priorities
[
t1
.
color
]
<
t2
.
place
.
priorities
[
t2
.
color
])
return
1
;
return
0
;
}
}
sources/qpme.simqpn.kernel/src/de/tud/cs/simqpn/kernel/Transition.java
View file @
95a621d4
...
...
@@ -77,6 +77,7 @@ public class Transition extends Node {
public
int
[][][]
inFunc
;
// [mode, inPlace, color]
public
int
[][][]
outFunc
;
// [mode, outPlace, color]
public
double
[]
modeWeights
;
// [1..numModes]
public
boolean
[]
dynamicModeWeights
;
// [1..numModes]
public
boolean
[]
modeStatus
;
// [1..numModes] Specifying the current status
// (enabled/disabled) of a mode
...
...
@@ -117,6 +118,7 @@ public class Transition extends Node {
this
.
numModes
=
numModes
;
this
.
transWeight
=
transWeight
;
this
.
modeWeights
=
new
double
[
numModes
];
this
.
dynamicModeWeights
=
new
boolean
[
numModes
];
this
.
inPlaces
=
new
Place
[
numInPlaces
];
this
.
outPlaces
=
new
Place
[
numOutPlaces
];
this
.
inFunc
=
new
int
[
numModes
][
numInPlaces
][];
...
...
@@ -315,7 +317,6 @@ public class Transition extends Node {
* @exception
*/
public
void
fire
()
throws
SimQPNException
{
int
nM
=
numModes
;
// Choose mode to fire based on weights
int
mode
;
...
...
@@ -327,10 +328,42 @@ public class Transition extends Node {
break
;
}
}
}
else
{
}
else
{
double
[]
pdf
=
new
double
[
enModesCnt
];
int
[]
enModesIDs
=
new
int
[
enModesCnt
];
for
(
int
m
=
0
,
e
=
0
;
m
<
nM
;
m
++)
{
// Adjust mode weights
// When initial modeWeight == 0 then the number of available expected tokens of input places with the name starting
// with '$' character will be considered as modeWeight
if
(
modeStatus
[
m
]
&&
dynamicModeWeights
[
m
])
{
//IF (not initial mapped)
//do mappint
//endif
//modeWeights[m] = getMappedPlace(m).availTokens.
modeWeights
[
m
]
=
0
;
int
p
,
c
,
nP
,
nC
;
nP
=
inPlaces
.
length
;
Place
pl
;
for
(
p
=
0
;
p
<
nP
;
p
++)
{
pl
=
inPlaces
[
p
];
nC
=
pl
.
numColors
;
String
[]
nameHierarchy
=
pl
.
name
.
split
(
"\\."
);
String
name
=
nameHierarchy
[
nameHierarchy
.
length
-
1
];
if
(
name
.
startsWith
(
"$"
))
for
(
c
=
0
;
c
<
nC
;
c
++)
{
if
(
inFunc
[
m
][
p
][
c
]
>
0
)
{
modeWeights
[
m
]
+=
pl
.
availTokens
[
c
];
}
}
}
}
if
(
modeStatus
[
m
])
{
pdf
[
e
]
=
modeWeights
[
m
];
enModesIDs
[
e
]
=
m
;
...
...
@@ -338,7 +371,7 @@ public class Transition extends Node {
}
}
randModeGen
.
setState2
(
pdf
);
mode
=
enModesIDs
[
randModeGen
.
nextInt
()];
mode
=
enModesIDs
[
randModeGen
.
nextInt
()];
}
int
p
,
c
,
nP
,
nC
,
prC
,
n
;
int
maxN
=
0
;
...
...
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