summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt2
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowMapper.kt75
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt1
-rw-r--r--opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt16
-rw-r--r--opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt2
-rw-r--r--opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt2
-rw-r--r--opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt18
-rw-r--r--opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt6
-rw-r--r--opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt6
-rw-r--r--opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt4
10 files changed, 97 insertions, 35 deletions
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt
index 8400c225..62d91c0b 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt
@@ -80,7 +80,7 @@ public class SimPsu(
update()
}
- override fun createConsumer(): FlowSource = object : FlowSource {
+ override fun createSource(): FlowSource = object : FlowSource {
override fun onStart(conn: FlowConnection, now: Long) {
_ctx = conn
}
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowMapper.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowMapper.kt
new file mode 100644
index 00000000..6867bcef
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/FlowMapper.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2021 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.simulator.flow
+
+/**
+ * A [FlowConsumer] that maps the pushed flow through [transform].
+ *
+ * @param source The source of the flow.
+ * @param transform The method to transform the flow.
+ */
+public class FlowMapper(
+ private val source: FlowSource,
+ private val transform: (FlowConnection, Double) -> Double
+) : FlowSource {
+
+ /**
+ * The current active connection.
+ */
+ private var _conn: Connection? = null
+
+ override fun onStart(conn: FlowConnection, now: Long) {
+ check(_conn == null) { "Concurrent access" }
+ val delegate = Connection(conn, transform)
+ _conn = delegate
+ source.onStart(delegate, now)
+ }
+
+ override fun onStop(conn: FlowConnection, now: Long, delta: Long) {
+ val delegate = checkNotNull(_conn) { "Invariant violation" }
+ _conn = null
+ source.onStop(delegate, now, delta)
+ }
+
+ override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long {
+ val delegate = checkNotNull(_conn) { "Invariant violation" }
+ return source.onPull(delegate, now, delta)
+ }
+
+ override fun onConverge(conn: FlowConnection, now: Long, delta: Long) {
+ val delegate = _conn ?: return
+ source.onConverge(delegate, now, delta)
+ }
+
+ /**
+ * The wrapper [FlowConnection] that is used to transform the flow.
+ */
+ private class Connection(
+ private val delegate: FlowConnection,
+ private val transform: (FlowConnection, Double) -> Double
+ ) : FlowConnection by delegate {
+ override fun push(rate: Double) {
+ delegate.push(transform(this, rate))
+ }
+ }
+}
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt
index c235b9ae..55fa92df 100644
--- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt
+++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/internal/FlowConsumerContextImpl.kt
@@ -127,6 +127,7 @@ internal class FlowConsumerContextImpl(
engine.batch {
source.onStart(this, _clock.millis())
_state = State.Active
+
pull()
}
}
diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt
index c33f5186..d536f22d 100644
--- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt
+++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt
@@ -57,17 +57,9 @@ public class SimPdu(
mux.addOutput(forwarder)
}
- override fun createConsumer(): FlowSource = object : FlowSource by forwarder {
- override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long {
- val duration = forwarder.onPull(conn, now, delta)
- val loss = computePowerLoss(conn.demand)
- val newLimit = conn.demand + loss
-
- conn.push(newLimit)
- return duration
- }
-
- override fun toString(): String = "SimPdu.Consumer"
+ override fun createSource(): FlowSource = FlowMapper(forwarder) { _, rate ->
+ val loss = computePowerLoss(rate)
+ rate + loss
}
override fun toString(): String = "SimPdu"
@@ -85,7 +77,7 @@ public class SimPdu(
*/
public class Outlet(private val switch: FlowMultiplexer, private val provider: FlowConsumer) : SimPowerOutlet(), AutoCloseable {
override fun onConnect(inlet: SimPowerInlet) {
- provider.startConsumer(inlet.createConsumer())
+ provider.startConsumer(inlet.createSource())
}
override fun onDisconnect(inlet: SimPowerInlet) {
diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt
index 851b28a5..de587b7f 100644
--- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt
+++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt
@@ -44,5 +44,5 @@ public abstract class SimPowerInlet {
/**
* Create a [FlowSource] which represents the consumption of electricity from the power outlet.
*/
- public abstract fun createConsumer(): FlowSource
+ public abstract fun createSource(): FlowSource
}
diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt
index 7faebd75..07e9f52e 100644
--- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt
+++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt
@@ -43,7 +43,7 @@ public class SimPowerSource(engine: FlowEngine, public val capacity: Double) : S
get() = source.rate
override fun onConnect(inlet: SimPowerInlet) {
- source.startConsumer(inlet.createConsumer())
+ source.startConsumer(inlet.createSource())
}
override fun onDisconnect(inlet: SimPowerInlet) {
diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt
index 5eaa91af..312f1d0f 100644
--- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt
+++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt
@@ -59,17 +59,13 @@ public class SimUps(
}
override fun onConnect(inlet: SimPowerInlet) {
- val consumer = inlet.createConsumer()
- provider.startConsumer(object : FlowSource by consumer {
- override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long {
- val duration = consumer.onPull(conn, now, delta)
- val loss = computePowerLoss(conn.demand)
- val newLimit = conn.demand + loss
+ val source = inlet.createSource()
+ val mapper = FlowMapper(source) { _, rate ->
+ val loss = computePowerLoss(rate)
+ rate + loss
+ }
- conn.push(newLimit)
- return duration
- }
- })
+ provider.startConsumer(mapper)
}
override fun onDisconnect(inlet: SimPowerInlet) {
@@ -88,7 +84,7 @@ public class SimUps(
* A UPS inlet.
*/
public inner class Inlet(private val forwarder: FlowForwarder) : SimPowerInlet(), AutoCloseable {
- override fun createConsumer(): FlowSource = forwarder
+ override fun createSource(): FlowSource = forwarder
/**
* Remove the inlet from the PSU.
diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt
index 85b9ab01..eb823eb1 100644
--- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt
+++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt
@@ -25,7 +25,6 @@ package org.opendc.simulator.power
import io.mockk.spyk
import io.mockk.verify
import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.opendc.simulator.core.runBlockingSimulation
@@ -79,7 +78,7 @@ internal class SimPduTest {
source.connect(pdu)
val consumer = spyk(FixedFlowSource(100.0, utilization = 1.0))
val inlet = object : SimPowerInlet() {
- override fun createConsumer(): FlowSource = consumer
+ override fun createSource(): FlowSource = consumer
}
val outlet = pdu.newOutlet()
@@ -90,7 +89,6 @@ internal class SimPduTest {
}
@Test
- @Disabled
fun testLoss() = runBlockingSimulation {
val engine = FlowEngine(coroutineContext, clock)
val source = SimPowerSource(engine, capacity = 100.0)
@@ -116,6 +114,6 @@ internal class SimPduTest {
}
class SimpleInlet : SimPowerInlet() {
- override fun createConsumer(): FlowSource = FixedFlowSource(100.0, utilization = 0.5)
+ override fun createSource(): FlowSource = FixedFlowSource(100.0, utilization = 0.5)
}
}
diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt
index 20677633..76142103 100644
--- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt
+++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt
@@ -79,7 +79,7 @@ internal class SimPowerSourceTest {
val source = SimPowerSource(engine, capacity = 100.0)
val consumer = spyk(FixedFlowSource(100.0, utilization = 1.0))
val inlet = object : SimPowerInlet() {
- override fun createConsumer(): FlowSource = consumer
+ override fun createSource(): FlowSource = consumer
}
source.connect(inlet)
@@ -95,7 +95,7 @@ internal class SimPowerSourceTest {
val inlet = mockk<SimPowerInlet>(relaxUnitFun = true)
every { inlet.isConnected } returns false
every { inlet._outlet } returns null
- every { inlet.createConsumer() } returns FixedFlowSource(100.0, utilization = 1.0)
+ every { inlet.createSource() } returns FixedFlowSource(100.0, utilization = 1.0)
source.connect(inlet)
@@ -131,6 +131,6 @@ internal class SimPowerSourceTest {
}
class SimpleInlet : SimPowerInlet() {
- override fun createConsumer(): FlowSource = FixedFlowSource(100.0, utilization = 1.0)
+ override fun createSource(): FlowSource = FixedFlowSource(100.0, utilization = 1.0)
}
}
diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt
index c6e0605a..a764a368 100644
--- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt
+++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt
@@ -86,7 +86,7 @@ internal class SimUpsTest {
source2.connect(ups.newInlet())
val consumer = spyk(FixedFlowSource(100.0, utilization = 1.0))
val inlet = object : SimPowerInlet() {
- override fun createConsumer(): FlowSource = consumer
+ override fun createSource(): FlowSource = consumer
}
ups.connect(inlet)
@@ -96,6 +96,6 @@ internal class SimUpsTest {
}
class SimpleInlet : SimPowerInlet() {
- override fun createConsumer(): FlowSource = FixedFlowSource(100.0, utilization = 0.5)
+ override fun createSource(): FlowSource = FixedFlowSource(100.0, utilization = 0.5)
}
}