summaryrefslogtreecommitdiff
path: root/opendc-simulator/opendc-simulator-compute/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-simulator/opendc-simulator-compute/src/main')
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt27
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt144
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt67
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt11
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt38
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorCounters.kt48
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt5
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt17
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt5
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimVirtualMachine.kt50
10 files changed, 284 insertions, 128 deletions
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt
index 0bcf5957..9140d31b 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt
@@ -28,6 +28,7 @@ import org.opendc.simulator.compute.model.ProcessingUnit
import org.opendc.simulator.compute.power.PowerDriver
import org.opendc.simulator.flow.*
import org.opendc.simulator.flow.FlowEngine
+import kotlin.math.max
/**
* A simulated bare-metal machine that is able to run a single workload.
@@ -49,10 +50,18 @@ public class SimBareMetalMachine(
parent: FlowConvergenceListener? = null,
) : SimAbstractMachine(engine, parent, model) {
/**
- * The power draw of the machine onto the PSU.
+ * The current power usage of the machine (without PSU loss) in W.
*/
- public val powerDraw: Double
- get() = powerDriverLogic.computePower()
+ public val powerUsage: Double
+ get() = _powerUsage
+ private var _powerUsage = 0.0
+
+ /**
+ * The total energy usage of the machine (without PSU loss) in Joules.
+ */
+ public val energyUsage: Double
+ get() = _energyUsage
+ private var _energyUsage = 0.0
/**
* The processing units of the machine.
@@ -66,8 +75,20 @@ public class SimBareMetalMachine(
*/
private val powerDriverLogic = powerDriver.createLogic(this, cpus)
+ private var _lastConverge = Long.MAX_VALUE
+
override fun onConverge(now: Long, delta: Long) {
+ // Update the PSU stage
psu.update()
+
+ val lastConverge = _lastConverge
+ _lastConverge = now
+ val duration = max(0, now - lastConverge)
+ if (duration > 0) {
+ // Compute the power and energy usage of the machine
+ _energyUsage += _powerUsage * (duration / 1000.0)
+ _powerUsage = powerDriverLogic.computePower()
+ }
}
init {
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt
index bcba8e8e..aac8b959 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt
@@ -30,6 +30,7 @@ import org.opendc.simulator.compute.model.MachineModel
import org.opendc.simulator.compute.model.ProcessingUnit
import org.opendc.simulator.flow.*
import org.opendc.simulator.flow.mux.FlowMultiplexer
+import kotlin.math.roundToLong
/**
* Abstract implementation of the [SimHypervisor] interface.
@@ -39,18 +40,19 @@ import org.opendc.simulator.flow.mux.FlowMultiplexer
*/
public abstract class SimAbstractHypervisor(
protected val engine: FlowEngine,
- private val scalingGovernor: ScalingGovernor? = null,
+ private val listener: FlowConvergenceListener?,
+ private val scalingGovernor: ScalingGovernor?,
protected val interferenceDomain: VmInterferenceDomain? = null
-) : SimHypervisor {
+) : SimHypervisor, FlowConvergenceListener {
/**
* The machine on which the hypervisor runs.
*/
- private lateinit var context: SimMachineContext
+ protected lateinit var context: SimMachineContext
/**
* The resource switch to use.
*/
- private lateinit var mux: FlowMultiplexer
+ protected abstract val mux: FlowMultiplexer
/**
* The virtual machines running on this hypervisor.
@@ -62,39 +64,73 @@ public abstract class SimAbstractHypervisor(
/**
* The resource counters associated with the hypervisor.
*/
- public override val counters: FlowCounters
- get() = mux.counters
+ public override val counters: SimHypervisorCounters
+ get() = _counters
+ private val _counters = object : SimHypervisorCounters {
+ @JvmField var d = 1.0 // Number of CPUs divided by total CPU capacity
+
+ override var cpuActiveTime: Long = 0L
+ override var cpuIdleTime: Long = 0L
+ override var cpuStealTime: Long = 0L
+ override var cpuLostTime: Long = 0L
+
+ private var _previousDemand = 0.0
+ private var _previousActual = 0.0
+ private var _previousRemaining = 0.0
+ private var _previousInterference = 0.0
+
+ /**
+ * Record the CPU time of the hypervisor.
+ */
+ fun record() {
+ val counters = mux.counters
+ val demand = counters.demand
+ val actual = counters.actual
+ val remaining = counters.remaining
+ val interference = counters.interference
+
+ val demandDelta = demand - _previousDemand
+ val actualDelta = actual - _previousActual
+ val remainingDelta = remaining - _previousRemaining
+ val interferenceDelta = interference - _previousInterference
+
+ _previousDemand = demand
+ _previousActual = actual
+ _previousRemaining = remaining
+ _previousInterference = interference
+
+ cpuActiveTime += (actualDelta * d).roundToLong()
+ cpuIdleTime += (remainingDelta * d).roundToLong()
+ cpuStealTime += ((demandDelta - actualDelta) * d).roundToLong()
+ cpuLostTime += (interferenceDelta * d).roundToLong()
+ }
+ }
/**
- * The scaling governors attached to the physical CPUs backing this hypervisor.
+ * The CPU capacity of the hypervisor in MHz.
*/
- private val governors = mutableListOf<ScalingGovernor.Logic>()
+ override val cpuCapacity: Double
+ get() = mux.capacity
/**
- * Construct the [FlowMultiplexer] implementation that performs the actual scheduling of the CPUs.
+ * The CPU demand of the hypervisor in MHz.
*/
- public abstract fun createMultiplexer(ctx: SimMachineContext): FlowMultiplexer
+ override val cpuDemand: Double
+ get() = mux.demand
/**
- * Check whether the specified machine model fits on this hypervisor.
+ * The CPU usage of the hypervisor in MHz.
*/
- public abstract fun canFit(model: MachineModel, switch: FlowMultiplexer): Boolean
+ override val cpuUsage: Double
+ get() = mux.rate
/**
- * Trigger the governors to recompute the scaling limits.
+ * The scaling governors attached to the physical CPUs backing this hypervisor.
*/
- protected fun triggerGovernors(load: Double) {
- for (governor in governors) {
- governor.onLimit(load)
- }
- }
+ private val governors = mutableListOf<ScalingGovernor.Logic>()
/* SimHypervisor */
- override fun canFit(model: MachineModel): Boolean {
- return canFit(model, mux)
- }
-
- override fun createMachine(model: MachineModel, interferenceId: String?): SimMachine {
+ override fun createMachine(model: MachineModel, interferenceId: String?): SimVirtualMachine {
require(canFit(model)) { "Machine does not fit" }
val vm = VirtualMachine(model, interferenceId)
_vms.add(vm)
@@ -104,7 +140,13 @@ public abstract class SimAbstractHypervisor(
/* SimWorkload */
override fun onStart(ctx: SimMachineContext) {
context = ctx
- mux = createMultiplexer(ctx)
+
+ _cpuCount = ctx.cpus.size
+ _cpuCapacity = ctx.cpus.sumOf { it.model.frequency }
+ _counters.d = _cpuCount / _cpuCapacity * 1000L
+
+ // Clear the existing outputs of the multiplexer
+ mux.clearOutputs()
for (cpu in ctx.cpus) {
val governor = scalingGovernor?.createLogic(ScalingPolicyImpl(cpu))
@@ -113,16 +155,31 @@ public abstract class SimAbstractHypervisor(
governor.onStart()
}
- mux.addOutput(cpu)
+ cpu.startConsumer(mux.newOutput())
}
}
+ private var _cpuCount = 0
+ private var _cpuCapacity = 0.0
+
+ /* FlowConvergenceListener */
+ override fun onConverge(now: Long, delta: Long) {
+ _counters.record()
+
+ val load = cpuDemand / cpuCapacity
+ for (governor in governors) {
+ governor.onLimit(load)
+ }
+
+ listener?.onConverge(now, delta)
+ }
+
/**
* A virtual machine running on the hypervisor.
*
* @param model The machine model of the virtual machine.
*/
- private inner class VirtualMachine(model: MachineModel, interferenceId: String? = null) : SimAbstractMachine(engine, parent = null, model) {
+ private inner class VirtualMachine(model: MachineModel, interferenceId: String? = null) : SimAbstractMachine(engine, parent = null, model), SimVirtualMachine {
/**
* The interference key of this virtual machine.
*/
@@ -133,6 +190,41 @@ public abstract class SimAbstractHypervisor(
*/
override val cpus = model.cpus.map { VCpu(mux, mux.newInput(interferenceKey), it) }
+ /**
+ * The resource counters associated with the hypervisor.
+ */
+ override val counters: SimHypervisorCounters
+ get() = _counters
+ private val _counters = object : SimHypervisorCounters {
+ private val d = cpus.size / cpus.sumOf { it.model.frequency } * 1000
+
+ override val cpuActiveTime: Long
+ get() = (cpus.sumOf { it.counters.actual } * d).roundToLong()
+ override val cpuIdleTime: Long
+ get() = (cpus.sumOf { it.counters.actual + it.counters.remaining } * d).roundToLong()
+ override val cpuStealTime: Long
+ get() = (cpus.sumOf { it.counters.demand - it.counters.actual } * d).roundToLong()
+ override val cpuLostTime: Long = 0L
+ }
+
+ /**
+ * The CPU capacity of the hypervisor in MHz.
+ */
+ override val cpuCapacity: Double
+ get() = cpus.sumOf(FlowConsumer::capacity)
+
+ /**
+ * The CPU demand of the hypervisor in MHz.
+ */
+ override val cpuDemand: Double
+ get() = cpus.sumOf(FlowConsumer::demand)
+
+ /**
+ * The CPU usage of the hypervisor in MHz.
+ */
+ override val cpuUsage: Double
+ get() = cpus.sumOf(FlowConsumer::rate)
+
override fun close() {
super.close()
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt
index b0515c6e..36f76650 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt
@@ -23,7 +23,6 @@
package org.opendc.simulator.compute.kernel
import org.opendc.simulator.compute.SimMachine
-import org.opendc.simulator.compute.SimMachineContext
import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor
import org.opendc.simulator.compute.kernel.interference.VmInterferenceDomain
import org.opendc.simulator.compute.model.MachineModel
@@ -38,64 +37,20 @@ import org.opendc.simulator.flow.mux.MaxMinFlowMultiplexer
* concurrently using weighted fair sharing.
*
* @param engine The [FlowEngine] to manage the machine's resources.
- * @param parent The parent simulation system.
+ * @param listener The listener for the convergence of the system.
* @param scalingGovernor The CPU frequency scaling governor to use for the hypervisor.
* @param interferenceDomain The resource interference domain to which the hypervisor belongs.
- * @param listener The hypervisor listener to use.
*/
public class SimFairShareHypervisor(
engine: FlowEngine,
- private val parent: FlowConvergenceListener? = null,
- scalingGovernor: ScalingGovernor? = null,
- interferenceDomain: VmInterferenceDomain? = null,
- private val listener: SimHypervisor.Listener? = null
-) : SimAbstractHypervisor(engine, scalingGovernor, interferenceDomain) {
-
- override fun canFit(model: MachineModel, switch: FlowMultiplexer): Boolean = true
-
- override fun createMultiplexer(ctx: SimMachineContext): FlowMultiplexer {
- return SwitchSystem(ctx).switch
- }
-
- private inner class SwitchSystem(private val ctx: SimMachineContext) : FlowConvergenceListener {
- val switch = MaxMinFlowMultiplexer(engine, this, interferenceDomain)
-
- private var lastCpuUsage = 0.0
- private var lastCpuDemand = 0.0
- private var lastDemand = 0.0
- private var lastActual = 0.0
- private var lastOvercommit = 0.0
- private var lastInterference = 0.0
- private var lastReport = Long.MIN_VALUE
-
- override fun onConverge(now: Long, delta: Long) {
- val listener = listener ?: return
- val counters = switch.counters
-
- if (now > lastReport) {
- listener.onSliceFinish(
- this@SimFairShareHypervisor,
- counters.demand - lastDemand,
- counters.actual - lastActual,
- counters.overcommit - lastOvercommit,
- counters.interference - lastInterference,
- lastCpuUsage,
- lastCpuDemand
- )
- }
- lastReport = now
-
- lastCpuDemand = switch.outputs.sumOf { it.demand }
- lastCpuUsage = switch.outputs.sumOf { it.rate }
- lastDemand = counters.demand
- lastActual = counters.actual
- lastOvercommit = counters.overcommit
- lastInterference = counters.interference
-
- val load = lastCpuDemand / ctx.cpus.sumOf { it.model.frequency }
- triggerGovernors(load)
-
- parent?.onConverge(now, delta)
- }
- }
+ listener: FlowConvergenceListener?,
+ scalingGovernor: ScalingGovernor?,
+ interferenceDomain: VmInterferenceDomain?,
+) : SimAbstractHypervisor(engine, listener, scalingGovernor, interferenceDomain) {
+ /**
+ * The multiplexer that distributes the computing capacity.
+ */
+ override val mux: FlowMultiplexer = MaxMinFlowMultiplexer(engine, this, interferenceDomain)
+
+ override fun canFit(model: MachineModel): Boolean = true
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt
index e0a70926..3136f4c8 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt
@@ -35,15 +35,8 @@ public class SimFairShareHypervisorProvider : SimHypervisorProvider {
override fun create(
engine: FlowEngine,
- parent: FlowConvergenceListener?,
+ listener: FlowConvergenceListener?,
scalingGovernor: ScalingGovernor?,
interferenceDomain: VmInterferenceDomain?,
- listener: SimHypervisor.Listener?
- ): SimHypervisor = SimFairShareHypervisor(
- engine,
- parent,
- scalingGovernor = scalingGovernor,
- interferenceDomain = interferenceDomain,
- listener = listener
- )
+ ): SimHypervisor = SimFairShareHypervisor(engine, listener, scalingGovernor, interferenceDomain)
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt
index 1b11ca6b..57d4cf20 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt
@@ -25,7 +25,6 @@ package org.opendc.simulator.compute.kernel
import org.opendc.simulator.compute.SimMachine
import org.opendc.simulator.compute.model.MachineModel
import org.opendc.simulator.compute.workload.SimWorkload
-import org.opendc.simulator.flow.FlowCounters
/**
* A SimHypervisor facilitates the execution of multiple concurrent [SimWorkload]s, while acting as a single workload
@@ -40,7 +39,22 @@ public interface SimHypervisor : SimWorkload {
/**
* The resource counters associated with the hypervisor.
*/
- public val counters: FlowCounters
+ public val counters: SimHypervisorCounters
+
+ /**
+ * The CPU usage of the hypervisor in MHz.
+ */
+ public val cpuUsage: Double
+
+ /**
+ * The CPU usage of the hypervisor in MHz.
+ */
+ public val cpuDemand: Double
+
+ /**
+ * The CPU capacity of the hypervisor in MHz.
+ */
+ public val cpuCapacity: Double
/**
* Determine whether the specified machine characterized by [model] can fit on this hypervisor at this moment.
@@ -53,23 +67,5 @@ public interface SimHypervisor : SimWorkload {
* @param model The machine to create.
* @param interferenceId An identifier for the interference model.
*/
- public fun createMachine(model: MachineModel, interferenceId: String? = null): SimMachine
-
- /**
- * Event listener for hypervisor events.
- */
- public interface Listener {
- /**
- * This method is invoked when a slice is finished.
- */
- public fun onSliceFinish(
- hypervisor: SimHypervisor,
- totalWork: Double,
- grantedWork: Double,
- overcommittedWork: Double,
- interferedWork: Double,
- cpuUsage: Double,
- cpuDemand: Double
- )
- }
+ public fun createMachine(model: MachineModel, interferenceId: String? = null): SimVirtualMachine
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorCounters.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorCounters.kt
new file mode 100644
index 00000000..030d9c5f
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorCounters.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.compute.kernel
+
+/**
+ * Performance counters of a [SimHypervisor].
+ */
+public interface SimHypervisorCounters {
+ /**
+ * The amount of time (in milliseconds) the CPUs of the hypervisor were actively running.
+ */
+ public val cpuActiveTime: Long
+
+ /**
+ * The amount of time (in milliseconds) the CPUs of the hypervisor were idle.
+ */
+ public val cpuIdleTime: Long
+
+ /**
+ * The amount of CPU time (in milliseconds) that virtual machines were ready to run, but were not able to.
+ */
+ public val cpuStealTime: Long
+
+ /**
+ * The amount of CPU time (in milliseconds) that was lost due to interference between virtual machines.
+ */
+ public val cpuLostTime: Long
+}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt
index dad2cc3b..483217af 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt
@@ -40,13 +40,12 @@ public interface SimHypervisorProvider {
public val id: String
/**
- * Create a [SimHypervisor] instance with the specified [listener].
+ * Create a new [SimHypervisor] instance.
*/
public fun create(
engine: FlowEngine,
- parent: FlowConvergenceListener? = null,
+ listener: FlowConvergenceListener? = null,
scalingGovernor: ScalingGovernor? = null,
interferenceDomain: VmInterferenceDomain? = null,
- listener: SimHypervisor.Listener? = null
): SimHypervisor
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt
index 883e0d82..82f8df38 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt
@@ -22,8 +22,9 @@
package org.opendc.simulator.compute.kernel
-import org.opendc.simulator.compute.SimMachineContext
+import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor
import org.opendc.simulator.compute.model.MachineModel
+import org.opendc.simulator.flow.FlowConvergenceListener
import org.opendc.simulator.flow.FlowEngine
import org.opendc.simulator.flow.mux.FlowMultiplexer
import org.opendc.simulator.flow.mux.ForwardingFlowMultiplexer
@@ -31,12 +32,14 @@ import org.opendc.simulator.flow.mux.ForwardingFlowMultiplexer
/**
* A [SimHypervisor] that allocates its sub-resources exclusively for the virtual machine that it hosts.
*/
-public class SimSpaceSharedHypervisor(engine: FlowEngine) : SimAbstractHypervisor(engine) {
- override fun canFit(model: MachineModel, switch: FlowMultiplexer): Boolean {
- return switch.outputs.size - switch.inputs.size >= model.cpus.size
- }
+public class SimSpaceSharedHypervisor(
+ engine: FlowEngine,
+ listener: FlowConvergenceListener?,
+ scalingGovernor: ScalingGovernor?,
+) : SimAbstractHypervisor(engine, listener, scalingGovernor) {
+ override val mux: FlowMultiplexer = ForwardingFlowMultiplexer(engine)
- override fun createMultiplexer(ctx: SimMachineContext): FlowMultiplexer {
- return ForwardingFlowMultiplexer(engine)
+ override fun canFit(model: MachineModel): Boolean {
+ return mux.outputs.size - mux.inputs.size >= model.cpus.size
}
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt
index 93921eb9..dd6fb0b1 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt
@@ -35,9 +35,8 @@ public class SimSpaceSharedHypervisorProvider : SimHypervisorProvider {
override fun create(
engine: FlowEngine,
- parent: FlowConvergenceListener?,
+ listener: FlowConvergenceListener?,
scalingGovernor: ScalingGovernor?,
interferenceDomain: VmInterferenceDomain?,
- listener: SimHypervisor.Listener?
- ): SimHypervisor = SimSpaceSharedHypervisor(engine)
+ ): SimHypervisor = SimSpaceSharedHypervisor(engine, listener, scalingGovernor)
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimVirtualMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimVirtualMachine.kt
new file mode 100644
index 00000000..36219ef2
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimVirtualMachine.kt
@@ -0,0 +1,50 @@
+/*
+ * 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.compute.kernel
+
+import org.opendc.simulator.compute.SimMachine
+
+/**
+ * A virtual [SimMachine] running on top of another [SimMachine].
+ */
+public interface SimVirtualMachine : SimMachine {
+ /**
+ * The resource counters associated with the virtual machine.
+ */
+ public val counters: SimHypervisorCounters
+
+ /**
+ * The CPU usage of the VM in MHz.
+ */
+ public val cpuUsage: Double
+
+ /**
+ * The CPU usage of the VM in MHz.
+ */
+ public val cpuDemand: Double
+
+ /**
+ * The CPU capacity of the VM in MHz.
+ */
+ public val cpuCapacity: Double
+}