summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt2
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt77
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt81
3 files changed, 79 insertions, 81 deletions
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt
index c39c1aca..991cda7a 100644
--- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMin.kt
@@ -45,7 +45,7 @@ public class SimResourceAggregatorMaxMin(
val command = if (grantedWork > 0.0 && grantedSpeed > 0.0)
SimResourceCommand.Consume(grantedWork, grantedSpeed, deadline)
else
- SimResourceCommand.Idle(deadline)
+ SimResourceCommand.Idle()
input.push(command)
}
}
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt
index f7c5c5d7..d8fc8cb6 100644
--- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt
@@ -65,7 +65,7 @@ public class SimResourceDistributorMaxMin(
/* SimResourceConsumer */
override fun onNext(ctx: SimResourceContext): SimResourceCommand {
- return doNext(ctx.capacity)
+ return doNext(ctx)
}
override fun onEvent(ctx: SimResourceContext, event: SimResourceEvent) {
@@ -94,12 +94,13 @@ public class SimResourceDistributorMaxMin(
/**
* Schedule the work of the outputs.
*/
- private fun doNext(capacity: Double): SimResourceCommand {
+ private fun doNext(ctx: SimResourceContext): SimResourceCommand {
// If there is no work yet, mark the input as idle.
if (activeOutputs.isEmpty()) {
return SimResourceCommand.Idle()
}
+ val capacity = ctx.capacity
var duration: Double = Double.MAX_VALUE
var deadline: Long = Long.MAX_VALUE
var availableSpeed = capacity
@@ -112,7 +113,7 @@ public class SimResourceDistributorMaxMin(
output.pull()
// Remove outputs that have finished
- if (output.isFinished) {
+ if (!output.isActive) {
outputIterator.remove()
}
}
@@ -125,33 +126,23 @@ public class SimResourceDistributorMaxMin(
var remaining = activeOutputs.size
for (output in activeOutputs) {
val availableShare = availableSpeed / remaining--
+ val grantedSpeed = min(output.allowedSpeed, availableShare)
+ deadline = min(deadline, output.deadline)
- when (val command = output.activeCommand) {
- is SimResourceCommand.Idle -> {
- deadline = min(deadline, command.deadline)
- output.actualSpeed = 0.0
- }
- is SimResourceCommand.Consume -> {
- val grantedSpeed = min(output.allowedSpeed, availableShare)
- deadline = min(deadline, command.deadline)
-
- // Ignore idle computation
- if (grantedSpeed <= 0.0 || command.work <= 0.0) {
- output.actualSpeed = 0.0
- continue
- }
+ // Ignore idle computation
+ if (grantedSpeed <= 0.0 || output.work <= 0.0) {
+ output.actualSpeed = 0.0
+ continue
+ }
- totalRequestedSpeed += command.limit
- totalRequestedWork += command.work
+ totalRequestedSpeed += output.limit
+ totalRequestedWork += output.work
- output.actualSpeed = grantedSpeed
- availableSpeed -= grantedSpeed
+ output.actualSpeed = grantedSpeed
+ availableSpeed -= grantedSpeed
- // The duration that we want to run is that of the shortest request of an output
- duration = min(duration, command.work / grantedSpeed)
- }
- SimResourceCommand.Exit -> assert(false) { "Did not expect output to be stopped" }
- }
+ // The duration that we want to run is that of the shortest request of an output
+ duration = min(duration, output.work / grantedSpeed)
}
assert(deadline >= interpreter.clock.millis()) { "Deadline already passed" }
@@ -189,9 +180,19 @@ public class SimResourceDistributorMaxMin(
private var isClosed: Boolean = false
/**
- * The current command that is processed by the resource.
+ * The current requested work.
+ */
+ var work: Double = 0.0
+
+ /**
+ * The requested limit.
*/
- var activeCommand: SimResourceCommand = SimResourceCommand.Idle()
+ var limit: Double = 0.0
+
+ /**
+ * The current deadline.
+ */
+ var deadline: Long = Long.MAX_VALUE
/**
* The processing speed that is allowed by the model constraints.
@@ -204,12 +205,6 @@ public class SimResourceDistributorMaxMin(
var actualSpeed: Double = 0.0
/**
- * A flag to indicate that the output is finished.
- */
- val isFinished
- get() = activeCommand is SimResourceCommand.Exit
-
- /**
* The timestamp at which we received the last command.
*/
private var lastCommandTimestamp: Long = Long.MIN_VALUE
@@ -238,15 +233,19 @@ public class SimResourceDistributorMaxMin(
/* SimResourceProviderLogic */
override fun onIdle(ctx: SimResourceControllableContext, deadline: Long): Long {
allowedSpeed = 0.0
- activeCommand = SimResourceCommand.Idle(deadline)
+ this.deadline = deadline
+ work = 0.0
+ limit = 0.0
lastCommandTimestamp = ctx.clock.millis()
return Long.MAX_VALUE
}
override fun onConsume(ctx: SimResourceControllableContext, work: Double, limit: Double, deadline: Long): Long {
- allowedSpeed = ctx.speed
- activeCommand = SimResourceCommand.Consume(work, limit, deadline)
+ allowedSpeed = min(ctx.capacity, limit)
+ this.work = work
+ this.limit = limit
+ this.deadline = deadline
lastCommandTimestamp = ctx.clock.millis()
return Long.MAX_VALUE
@@ -257,7 +256,9 @@ public class SimResourceDistributorMaxMin(
}
override fun onFinish(ctx: SimResourceControllableContext) {
- activeCommand = SimResourceCommand.Exit
+ work = 0.0
+ limit = 0.0
+ deadline = Long.MAX_VALUE
lastCommandTimestamp = ctx.clock.millis()
}
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt
index 5c3f95e8..90c7bc75 100644
--- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/impl/SimResourceContextImpl.kt
@@ -212,11 +212,15 @@ internal class SimResourceContextImpl(
// 2. The resource capacity cannot satisfy the demand.
// 3. The resource consumer should be interrupted (e.g., someone called .interrupt())
if ((isConsume && remainingWork == 0.0) || _deadline <= timestamp || isInterrupted) {
- next(timestamp)
+ when (val command = consumer.onNext(this)) {
+ is SimResourceCommand.Idle -> interpretIdle(timestamp, command.deadline)
+ is SimResourceCommand.Consume -> interpretConsume(timestamp, command.work, command.limit, command.deadline)
+ is SimResourceCommand.Exit -> interpretExit()
+ }
} else if (isConsume) {
- interpret(SimResourceCommand.Consume(remainingWork, _limit, _deadline), timestamp)
+ interpretConsume(timestamp, remainingWork, _limit, _deadline)
} else {
- interpret(SimResourceCommand.Idle(_deadline), timestamp)
+ interpretIdle(timestamp, _deadline)
}
}
}
@@ -249,57 +253,50 @@ internal class SimResourceContextImpl(
}
/**
- * Interpret the specified [SimResourceCommand] that was submitted by the resource consumer.
+ * Interpret the [SimResourceCommand.Consume] command.
*/
- private fun interpret(command: SimResourceCommand, now: Long): SimResourceState {
- return when (command) {
- is SimResourceCommand.Idle -> {
- val deadline = command.deadline
-
- require(deadline >= now) { "Deadline already passed" }
-
- _speed = 0.0
- _work = 0.0
- _limit = 0.0
- _deadline = deadline
+ private fun interpretConsume(now: Long, work: Double, limit: Double, deadline: Long): SimResourceState {
+ require(deadline >= now) { "Deadline already passed" }
- val timestamp = logic.onIdle(this, deadline)
- scheduleUpdate(timestamp)
+ _speed = min(capacity, limit)
+ _work = work
+ _limit = limit
+ _deadline = deadline
- SimResourceState.Active
- }
- is SimResourceCommand.Consume -> {
- val work = command.work
- val limit = command.limit
- val deadline = command.deadline
+ val timestamp = logic.onConsume(this, work, limit, deadline)
+ scheduleUpdate(timestamp)
- require(deadline >= now) { "Deadline already passed" }
+ return SimResourceState.Active
+ }
- _speed = min(capacity, limit)
- _work = work
- _limit = limit
- _deadline = deadline
+ /**
+ * Interpret the [SimResourceCommand.Idle] command.
+ */
+ private fun interpretIdle(now: Long, deadline: Long): SimResourceState {
+ require(deadline >= now) { "Deadline already passed" }
- val timestamp = logic.onConsume(this, work, limit, deadline)
- scheduleUpdate(timestamp)
+ _speed = 0.0
+ _work = 0.0
+ _limit = 0.0
+ _deadline = deadline
- SimResourceState.Active
- }
- is SimResourceCommand.Exit -> {
- _speed = 0.0
- _work = 0.0
- _limit = 0.0
- _deadline = Long.MAX_VALUE
+ val timestamp = logic.onIdle(this, deadline)
+ scheduleUpdate(timestamp)
- SimResourceState.Stopped
- }
- }
+ return SimResourceState.Active
}
/**
- * Request the workload for more work.
+ * Interpret the [SimResourceCommand.Exit] command.
*/
- private fun next(now: Long): SimResourceState = interpret(consumer.onNext(this), now)
+ private fun interpretExit(): SimResourceState {
+ _speed = 0.0
+ _work = 0.0
+ _limit = 0.0
+ _deadline = Long.MAX_VALUE
+
+ return SimResourceState.Stopped
+ }
private var _remainingWork: Double = 0.0
private var _remainingWorkFlush: Long = Long.MIN_VALUE