diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2018-01-11 16:27:05 +0100 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2018-01-11 16:52:17 +0100 |
| commit | b1c4d1f94e35445bdba5a56b614d0ec28a332624 (patch) | |
| tree | f2a7244fd52a85f0bd5a4a51f8b3243d10005878 /opendc-stdlib | |
| parent | 8666a78b86a40c1d8dab28dd18e841318c01f97f (diff) | |
refactor(#18): Redesign core simulation API
This change contains the redesign of the core simulation API and
provides a cleaner interface for developing simulation models for the
users.
Diffstat (limited to 'opendc-stdlib')
23 files changed, 491 insertions, 876 deletions
diff --git a/opendc-stdlib/build.gradle b/opendc-stdlib/build.gradle index a0c92459..ea463f5a 100644 --- a/opendc-stdlib/build.gradle +++ b/opendc-stdlib/build.gradle @@ -24,7 +24,7 @@ /* Build configuration */ buildscript { - ext.kotlin_version = '1.1.4-3' + ext.kotlin_version = '1.2.10' ext.dokka_version = '0.9.15' repositories { @@ -68,8 +68,8 @@ dokka { } /* Project configuration */ -group 'nl.atlarge.opendc' -version '1.0' +group 'com.atlarge.opendc' +version '1.1' repositories { jcenter() diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/AdjacencyList.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/AdjacencyList.kt new file mode 100644 index 00000000..c042a2d5 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/AdjacencyList.kt @@ -0,0 +1,260 @@ +/* + * MIT License + * + * Copyright (c) 2017 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 com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.model.topology.Edge as BaseEdge +import java.util.concurrent.atomic.AtomicInteger + +/** + * This module provides a [Topology] implementation backed internally by an adjacency list. + * + * This implementation is best suited for sparse graphs, where an adjacency matrix would take up too much space with + * empty cells. + * + * *Note that this implementation is not synchronized.* + */ +object AdjacencyList { + /** + * Return a [TopologyBuilder] that constructs the topology represents as an adjacency list. + * + * @return A [TopologyBuilder] instance. + */ + fun builder(): TopologyBuilder = AdjacencyListTopologyBuilder() +} + +/** + * A builder for [Topology] instances, which is backed by an adjacency list. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +internal class AdjacencyListTopologyBuilder : TopologyBuilder { + /** + * Build a [Topology] instance from the current state of this builder. + * + * @return The graph built from this builder. + */ + override fun create(): MutableTopology = AdjacencyListTopology() +} + +/** + * A [Topology] whose graph is represented as adjacency list. + */ +internal class AdjacencyListTopology : MutableTopology { + /** + * The identifier for the next node in the graph. + */ + private var nextId: AtomicInteger = AtomicInteger(0) + + /** + * A mapping of nodes to their internal representation with the edges of the nodes. + */ + private var nodes: MutableMap<Entity<*, Topology>, Node> = HashMap() + + // Topology + + /** + * The listeners of this topology. + */ + override val listeners: MutableSet<TopologyListener> = HashSet() + + /** + * A unique identifier of this node within the topology. + */ + override val Entity<*, Topology>.id: Int + get() = nodes[this]!!.id + + /** + * The set of ingoing edges of this node. + */ + override val Entity<*, Topology>.ingoingEdges: MutableSet<BaseEdge<*>> + get() = nodes[this]!!.ingoingEdges + + /** + * The set of outgoing edges of this node. + */ + override val Entity<*, Topology>.outgoingEdges: MutableSet<BaseEdge<*>> + get() = nodes[this]!!.outgoingEdges + + // MutableTopology + + /** + * Create a directed edge between two [Node]s in the topology. + * + * @param from The source of the edge. + * @param to The destination of the edge. + * @param label The label of the edge. + * @param tag The tag of the edge that uniquely identifies the relationship the edge represents. + * @return The edge that has been created. + */ + override fun <T> connect(from: Entity<*, Topology>, to: Entity<*, Topology>, label: T, tag: String?): BaseEdge<T> { + if (!contains(from) || !contains(to)) + throw IllegalArgumentException("One of the entities is not part of the topology") + val edge = Edge(label, tag, from, to) + from.outgoingEdges.add(edge) + to.ingoingEdges.add(edge) + listeners.forEach { it.run { this@AdjacencyListTopology.onEdgeAdded(edge) } } + return edge + } + + // Cloneable + + /** + * Create a copy of the graph. + * + * @return A new [Topology] instance with a copy of the graph. + */ + override fun clone(): Topology { + val copy = AdjacencyListTopology() + copy.nextId = AtomicInteger(nextId.get()) + copy.nodes = HashMap(nodes) + return copy + } + + // Set + + /** + * Returns the size of the collection. + */ + override val size: Int = nodes.size + + /** + * Checks if the specified element is contained in this collection. + */ + override fun contains(element: Entity<*, Topology>): Boolean = nodes.contains(element) + + /** + * Checks if all elements in the specified collection are contained in this collection. + */ + override fun containsAll(elements: Collection<Entity<*, Topology>>): Boolean = + elements.all { nodes.containsKey(it) } + + /** + * Returns `true` if the collection is empty (contains no elements), `false` otherwise. + */ + override fun isEmpty(): Boolean = nodes.isEmpty() + + // MutableSet + + /** + * Add a node to the graph. + * + * @param element The element to add to this graph. + * @return `true` if the graph has changed, `false` otherwise. + */ + override fun add(element: Entity<*, Topology>): Boolean { + if (nodes.putIfAbsent(element, Node(nextId.getAndIncrement())) == null) { + listeners.forEach { it.run { this@AdjacencyListTopology.onNodeAdded(element) } } + return true + } + return false + } + + /** + * Add all nodes in the specified collection to the graph. + * + * @param elements The nodes to add to this graph. + * @return `true` if the graph has changed, `false` otherwise. + */ + override fun addAll(elements: Collection<Entity<*, Topology>>): Boolean = elements.any { add(it) } + + /** + * Remove all nodes and their respective edges from the graph. + */ + override fun clear() = nodes.clear() + + /** + * Remove the given node and its edges from the graph. + * + * @param element The element to remove from the graph. + * @return `true` if the graph has changed, `false` otherwise. + */ + override fun remove(element: Entity<*, Topology>): Boolean { + nodes[element]?.ingoingEdges?.forEach { + it.from.outgoingEdges.remove(it) + } + nodes[element]?.outgoingEdges?.forEach { + it.to.ingoingEdges.remove(it) + } + if (nodes.keys.remove(element)) { + listeners.forEach { it.run { this@AdjacencyListTopology.onNodeRemoved(element) } } + return true + } + return false + } + + + /** + * Remove all nodes in the given collection from the graph. + * + * @param elements The elements to remove from the graph. + * @return `true` if the graph has changed, `false` otherwise. + */ + override fun removeAll(elements: Collection<Entity<*, Topology>>): Boolean = elements.any(this::remove) + + /** + * Remove all nodes in the graph, except those in the specified collection. + * + * Take note that this method currently only guarantees a maximum runtime complexity of O(n^2). + * + * @param elements The elements to retain in the graph. + */ + override fun retainAll(elements: Collection<Entity<*, Topology>>): Boolean { + val iterator = nodes.keys.iterator() + var changed = false + while (iterator.hasNext()) { + val entity = iterator.next() + + if (entity !in elements) { + iterator.remove() + changed = true + } + } + return changed + } + + /** + * Return a mutable iterator over the nodes of the graph. + * + * @return A [MutableIterator] over the nodes of the graph. + */ + override fun iterator(): MutableIterator<Entity<*, Topology>> = nodes.keys.iterator() + + /** + * The internal representation of a node within the graph. + */ + internal data class Node(val id: Int) { + val ingoingEdges: MutableSet<BaseEdge<*>> = HashSet() + val outgoingEdges: MutableSet<BaseEdge<*>> = HashSet() + } + + /** + * The internal representation of an edge within the graph. + */ + internal class Edge<out T>(override val label: T, + override val tag: String?, + override val from: Entity<*, Topology>, + override val to: Entity<*, Topology>) : BaseEdge<T> +} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Bootstrap.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Bootstrap.kt new file mode 100644 index 00000000..de9a41d5 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Bootstrap.kt @@ -0,0 +1,23 @@ +package com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Bootstrap +import com.atlarge.opendc.simulator.Entity + +/** + * Create a [Bootstrap] procedure for the given [Topology]. + * + * @return A bootstrap procedure for the topology. + */ +fun <T: Topology> T.bootstrap(): Bootstrap<T> = Bootstrap.create { ctx -> + forEach { ctx.register(it) } + listeners += object : TopologyListener { + override fun Topology.onNodeAdded(node: Entity<*, Topology>) { + ctx.register(node) + } + + override fun Topology.onNodeRemoved(node: Entity<*, Topology>) { + ctx.deregister(node) + } + } + this +} diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Trace.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Component.kt index 6dd2efb8..5e8611a0 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Trace.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Component.kt @@ -22,16 +22,12 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform.workload +package com.atlarge.opendc.model.topology /** - * A timestamped sequence of jobs received in a cloud network. - * + * A component within a [Topology], which is either a node or an [Edge] representing the relationship between + * entities within a logical topology of a cloud network. + ** * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Trace { - /** - * The [Job]s in the trace. - */ - val jobs: Set<Job> -} +interface Component diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Edge.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Edge.kt new file mode 100644 index 00000000..3e507887 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Edge.kt @@ -0,0 +1,61 @@ +/* + * MIT License + * + * Copyright (c) 2017 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 com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity + +/** + * An edge that represents a directed relationship between exactly two nodes in a logical topology of a cloud network. + * + * @param T The relationship type the edge represents within a logical topology. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Edge<out T> : Component { + /** + * The label of this edge. + */ + val label: T + + /** + * A tag to uniquely identify the relationship this edge represents. + */ + val tag: String? + + /** + * The source of the edge. + * + * This property is not guaranteed to have a runtime complexity of <code>O(1)</code>, but must be at least + * <code>O(n)</code>, with respect to the size of the topology. + */ + val from: Entity<*, Topology> + + /** + * The destination of the edge. + * + * This property is not guaranteed to have a runtime complexity of <code>O(1)</code>, but must be at least + * <code>O(n)</code>, with respect to the size of the topology. + */ + val to: Entity<*, Topology> +} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/MutableTopology.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/MutableTopology.kt new file mode 100644 index 00000000..ac1b4ba5 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/MutableTopology.kt @@ -0,0 +1,65 @@ +/* + * MIT License + * + * Copyright (c) 2017 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 com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity + +/** + * A subinterface of [Topology] which adds mutation methods. When mutation is not required, users + * should prefer the [Topology] interface. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface MutableTopology : Topology, MutableSet<Entity<*, Topology>> { + /** + * Create a directed, labeled edge between two nodes in the topology. + * + * @param from The source of the edge. + * @param to The destination of the edge. + * @param label The label of the edge. + * @param tag The tag of the edge that uniquely identifies the relationship the edge represents. + * @return The edge that has been created. + */ + fun <T> connect(from: Entity<*, Topology>, to: Entity<*, Topology>, label: T, tag: String? = null): Edge<T> + + /** + * Create a directed, unlabeled edge between two nodes in the topology. + * + * @param from The source of the edge. + * @param to The destination of the edge. + * @param tag The tag of the edge that uniquely identifies the relationship the edge represents. + * @return The edge that has been created. + */ + fun connect(from: Entity<*, Topology>, to: Entity<*, Topology>, tag: String? = null): Edge<Unit> = + connect(from, to, Unit, tag) + + /** + * Create a directed, unlabeled edge between two nodes in the topology. + * + * @param dest The destination of the edge. + * @return The edge that has been created. + */ + infix fun Entity<*, Topology>.to(dest: Entity<*, Topology>): Edge<Unit> = connect(this, dest) +} diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Job.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Topology.kt index df2f2b6a..1e5a404f 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Job.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Topology.kt @@ -22,32 +22,29 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform.workload +package com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity /** - * A bag of tasks which are submitted by a [User] to the cloud network. + * A graph data structure which represents the logical topology of a cloud network consisting of one or more + * datacenters. + * + * A topology is [Iterable] and allows implementation-dependent iteration of the nodes in the topology. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Job { - /** - * A unique identifier of the job. - */ - val id: Int - +interface Topology : TopologyContext, Cloneable, Set<Entity<*, Topology>> { /** - * The owner of this job. + * The listeners of this topology. */ - val owner: User + val listeners: MutableSet<TopologyListener> /** - * The tasks this job consists of. + * Create a copy of the topology. + * + * @return A new [Topology] with a copy of the graph. */ - val tasks: Set<Task> - - /** - * A flag to indicate the job has finished. - */ - val finished: Boolean - get() = !tasks.any { !it.finished } + public override fun clone(): Topology } + diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/User.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyBuilder.kt index d827fee5..44b1cb4e 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/User.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyBuilder.kt @@ -22,24 +22,19 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform.workload +package com.atlarge.opendc.model.topology /** - * A user of a cloud network that provides [Job]s for the simulation. - * - * Each user in a simulation has its own logical view of the cloud network which is used to route its jobs in the - * physical network. + * A builder for [Topology] instances. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface User { - /** - * The unique identifier of the user. - */ - val id: Int - +interface TopologyBuilder : TopologyFactory { /** - * The name of this user. + * Construct a [Topology] from the given block and return it. + * + * @param block The block to construct the topology. + * @return The topology that has been built. */ - val name: String + fun construct(block: MutableTopology.() -> Unit): MutableTopology = create().apply(block) } diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyContext.kt index abc8608b..2bf87a39 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyContext.kt @@ -22,28 +22,29 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.machine +package com.atlarge.opendc.model.topology -import nl.atlarge.opendc.topology.Entity +import com.atlarge.opendc.simulator.Entity /** - * An interface representing a generic processing unit which is placed into a [Machine]. + * A [TopologyContext] represents the context for entities in a specific topology, providing access to the identifier + * and ingoing and outgoing edges of the [Entity] within a [Topology]. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface ProcessingUnit : Entity<Unit> { +interface TopologyContext { /** - * The speed of this [ProcessingUnit] per core in MHz. + * A unique identifier of an [Entity] within the topology. */ - val clockRate: Int + val Entity<*, Topology>.id: Int /** - * The amount of cores within this [ProcessingUnit]. + * The set of ingoing edges of an [Entity]. */ - val cores: Int + val Entity<*, Topology>.ingoingEdges: Set<Edge<*>> /** - * The energy consumption of this [ProcessingUnit] in Watt. + * The set of outgoing edges of an [Entity]. */ - val energyConsumption: Double + val Entity<*, Topology>.outgoingEdges: Set<Edge<*>> } diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Rack.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyFactory.kt index 25429f71..35cfa97a 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Rack.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyFactory.kt @@ -22,14 +22,19 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.container - -import nl.atlarge.opendc.topology.Entity +package com.atlarge.opendc.model.topology /** - * A type of physical steel and electronic framework that is designed to house servers, networking devices, cables and - * other datacenter computing equipment. + * An interface for producing [Topology] instances. Implementors of this interface provide a way of generating a + * topology based on the state of the factory. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Rack : Entity<Unit> +interface TopologyFactory { + /** + * Create a [MutableTopology] instance. + * + * @return A mutable topology. + */ + fun create(): MutableTopology +} diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/Scheduler.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyListener.kt index 578bef9c..93108cc0 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/Scheduler.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyListener.kt @@ -22,50 +22,42 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform.scheduler +package com.atlarge.opendc.model.topology; -import nl.atlarge.opendc.kernel.Context -import nl.atlarge.opendc.platform.workload.Task -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.machine.Machine +import com.atlarge.opendc.simulator.Entity /** - * A task scheduler that is coupled to an [Entity] in the topology of the cloud network. + * A listener interface for [Topology] instances. The methods of this interface are invoked on + * mutation of the topology the listener is listening to. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Scheduler { +interface TopologyListener { /** - * The name of this scheduler. - */ - val name: String - - /** - * (Re)schedule the tasks submitted to the scheduler over the specified set of machines. + * This method is invoked when an [Entity] is added to the [Topology]. * - * This method should be invoked at some interval to allow the scheduler to reschedule existing tasks and schedule - * new tasks. + * @param node The entity that has been added to the [Topology]. */ - suspend fun <E: Entity<*>> Context<E>.schedule() + fun Topology.onNodeAdded(node: Entity<*, Topology>) {} /** - * Submit a [Task] to this scheduler. + * This method is invoked when an [Entity] is removed from the [Topology]. * - * @param task The task to submit to the scheduler. + * @param node The entity that has been removed from the [Topology]. */ - fun submit(task: Task) + fun Topology.onNodeRemoved(node: Entity<*, Topology>) {} /** - * Register a [Machine] to this scheduler. + * This method is invoked when an [Edge] is added to the [Topology]. * - * @param machine The machine to register. + * @param edge The edge that has been added to the [Topology]. */ - fun register(machine: Machine) + fun Topology.onEdgeAdded(edge: Edge<*>) {} /** - * Deregister a [Machine] from this scheduler. + * This method is invoked when an [Edge] is removed from the [Topology]. * - * @param machine The machine to deregister. + * @param edge The entity that has been removed from the [Topology]. */ - fun deregister(machine: Machine) + fun Topology.onEdgeRemoved(edge: Edge<*>) {} } diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Room.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Traversable.kt index 3b338899..23720c46 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Room.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Traversable.kt @@ -22,13 +22,20 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.container +package com.atlarge.opendc.model.topology -import nl.atlarge.opendc.topology.Entity +/** + * Filter a [Set] of [Edge]s based on the tag of the edges and return the origin nodes casted to type `T`. + * + * @param tag The tag of the edges to get. + * @return An [Iterable] of the specified type `T` with the given tag. + */ +inline fun <reified T> Set<Edge<*>>.origins(tag: String) = filter { it.tag == tag }.map { it.from as T } /** - * A physical room in a datacenter with relationships to the entities within the room. + * Filter a [Set] of [Edge]s based on the tag of the edges and return the destination nodes casted to type `T`. * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + * @param tag The tag of the edges to get. + * @return An [Iterable] of the specified type `T` with the given tag. */ -interface Room : Entity<Unit> +inline fun <reified T> Set<Edge<*>>.destinations(tag: String) = filter { it.tag == tag }.map { it.to as T } diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/FifoScheduler.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/FifoScheduler.kt deleted file mode 100644 index 6f5db211..00000000 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/FifoScheduler.kt +++ /dev/null @@ -1,120 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 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 nl.atlarge.opendc.platform.scheduler - -import nl.atlarge.opendc.kernel.Context -import nl.atlarge.opendc.platform.workload.Job -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.machine.Machine -import nl.atlarge.opendc.platform.workload.Task -import java.util.* - -/** - * A [Scheduler] that distributes work according to the first-in-first-out principle. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -class FifoScheduler : Scheduler { - /** - * The name of this scheduler. - */ - override val name: String = "FIFO" - - /** - * The set of machines the scheduler knows of. - */ - val machines: MutableSet<Machine> = HashSet() - - /** - * The queue of [Task]s that need to be scheduled. - */ - val queue: Queue<Task> = ArrayDeque() - - /** - * (Re)schedule the tasks submitted to the scheduler over the specified set of machines. - */ - override suspend fun <E : Entity<*>> Context<E>.schedule() { - if (queue.isEmpty()) { - return - } - - // The tasks that need to be rescheduled - val rescheduled = ArrayDeque<Task>() - val iterator = queue.iterator() - - machines - .filter { it.state.status != Machine.Status.HALT } - .forEach { machine -> - while (iterator.hasNext()) { - val task = iterator.next() - - // TODO What to do with tasks that are not ready yet to be processed - if (!task.ready) { - iterator.remove() - rescheduled.add(task) - continue - } else if (task.finished) { - iterator.remove() - continue - } - - machine.send(task) - break - } - } - - // Reschedule all tasks that are not ready yet - while (!rescheduled.isEmpty()) { - queue.add(rescheduled.poll()) - } - } - - /** - * Submit a [Task] to this scheduler. - * - * @param task The task to submit to the scheduler. - */ - override fun submit(task: Task) { - queue.add(task) - } - - /** - * Register a [Machine] to this scheduler. - * - * @param machine The machine to register. - */ - override fun register(machine: Machine) { - machines.add(machine) - } - - /** - * Deregister a [Machine] from this scheduler. - * - * @param machine The machine to deregister. - */ - override fun deregister(machine: Machine) { - machines.remove(machine) - } -} diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/SrtfScheduler.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/SrtfScheduler.kt deleted file mode 100644 index 1fbf8c04..00000000 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/SrtfScheduler.kt +++ /dev/null @@ -1,111 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 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 nl.atlarge.opendc.platform.scheduler - -import nl.atlarge.opendc.kernel.Context -import nl.atlarge.opendc.platform.workload.Task -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.machine.Machine -import java.util.* - -/** - * A [Scheduler] that distributes work according to the shortest job first policy. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -class SrtfScheduler : Scheduler { - /** - * The name of this scheduler. - */ - override val name: String = "SRTF" - - /** - * The set of machines the scheduler knows of. - */ - val machines: MutableSet<Machine> = HashSet() - - /** - * The set of [Task]s that need to be scheduled. - */ - val tasks: MutableSet<Task> = HashSet() - - /** - * (Re)schedule the tasks submitted to the scheduler over the specified set of machines. - */ - override suspend fun <E : Entity<*>> Context<E>.schedule() { - if (tasks.isEmpty()) { - return - } - - val iterator = tasks.sortedBy { it.remaining }.iterator() - - machines - .filter { it.state.status != Machine.Status.HALT } - .forEach { machine -> - while (iterator.hasNext()) { - val task = iterator.next() - - // TODO What to do with tasks that are not ready yet to be processed - if (!task.ready) { - tasks.add(task) - continue - } else if (task.finished) { - tasks.remove(task) - continue - } - - machine.send(task) - break - } - } - } - - /** - * Submit a [Task] to this scheduler. - * - * @param task The task to submit to the scheduler. - */ - override fun submit(task: Task) { - tasks.add(task) - } - - /** - * Register a [Machine] to this scheduler. - * - * @param machine The machine to register. - */ - override fun register(machine: Machine) { - machines.add(machine) - } - - /** - * Deregister a [Machine] from this scheduler. - * - * @param machine The machine to deregister. - */ - override fun deregister(machine: Machine) { - machines.remove(machine) - } -} diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Task.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Task.kt deleted file mode 100644 index e740cdd8..00000000 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Task.kt +++ /dev/null @@ -1,92 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 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 nl.atlarge.opendc.platform.workload - -import nl.atlarge.opendc.kernel.time.Instant -import nl.atlarge.opendc.topology.machine.Machine - -/** - * A task that runs as part of a [Job] on a [Machine]. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Task { - /** - * The unique identifier of the task. - */ - val id: Int - - /** - * The amount of flops for this task. - */ - val flops: Long - - /** - * The dependencies of the task. - */ - val dependencies: Set<Task> - - /** - * A flag to indicate the task is parallelizable. - */ - val parallelizable: Boolean - - /** - * The remaining flops for this task. - */ - val remaining: Long - - /** - * The state of the task. - */ - val state: TaskState - - /** - * A flag to indicate whether the task is ready to be started. - */ - val ready: Boolean - get() = !dependencies.any { !it.finished } - - /** - * A flag to indicate whether the task has finished. - */ - val finished: Boolean - get() = state is TaskState.Finished - - /** - * This method is invoked when a task has arrived at a datacenter. - * - * @param time The moment in time the task has arrived at the datacenter. - */ - fun arrive(time: Instant) - - /** - * Consume the given amount of flops of this task. - * - * @param time The current moment in time of the consumption. - * @param flops The total amount of flops to consume. - */ - fun consume(time: Instant, flops: Long) -} diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/TaskState.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/TaskState.kt deleted file mode 100644 index d1f908af..00000000 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/TaskState.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 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 nl.atlarge.opendc.platform.workload - -import nl.atlarge.opendc.kernel.time.Instant - - -/** - * This class hierarchy describes the states of a [Task]. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -sealed class TaskState { - /** - * A state to indicate the task has not yet arrived at the [Datacenter]. - */ - object Underway : TaskState() - - /** - * A state to indicate the task has arrived at the [Datacenter]. - * - * @property at The moment in time the task has arrived. - */ - data class Queued(val at: Instant) : TaskState() - - /** - * A state to indicate the task has started running on a machine. - * - * @property previous The previous state of the task. - * @property at The moment in time the task started. - */ - data class Running(val previous: Queued, val at: Instant) : TaskState() - - /** - * A state to indicate the task has finished. - * - * @property previous The previous state of the task. - * @property at The moment in time the task finished. - */ - data class Finished(val previous: Running, val at: Instant) : TaskState() - - /** - * A state to indicate the task has failed. - * - * @property previous The previous state of the task. - * @property at The moment in time the task failed. - * @property reason The reason of the failure. - */ - data class Failed(val previous: Running, val at: Instant, val reason: String) : TaskState() -} diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt deleted file mode 100644 index f7eb29d8..00000000 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt +++ /dev/null @@ -1,102 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 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 nl.atlarge.opendc.topology.container - -import mu.KotlinLogging -import nl.atlarge.opendc.topology.destinations -import nl.atlarge.opendc.kernel.Context -import nl.atlarge.opendc.kernel.Process -import nl.atlarge.opendc.kernel.time.Duration -import nl.atlarge.opendc.platform.scheduler.Scheduler -import nl.atlarge.opendc.platform.workload.Task -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.machine.Machine -import java.util.* - -/** - * A representation of a facility used to house computer systems and associated components. - * - * @property scheduler The tasks scheduler the datacenter uses. - * @property interval The interval at which task will be (re)scheduled. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Datacenter : Entity<Unit>, Process<Datacenter> { - /** - * The task scheduler the datacenter uses. - */ - val scheduler: Scheduler - - /** - * The interval at which task will be (re)scheduled. - */ - val interval: Duration - - /** - * This method is invoked to start the simulation an [Entity] associated with this [Process]. - * - * This method is assumed to be running during a simulation, but should hand back control to the simulator at - * some point by suspending the process. This allows other processes to do work in the current tick of the - * simulation. - * Suspending the process can be achieved by calling suspending method in the context: - * - [Context.tick] - Wait for the next tick to occur - * - [Context.wait] - Wait for `n` amount of ticks before resuming execution. - * - [Context.receive] - Wait for a message to be received in the mailbox of the [Entity] before resuming - * execution. - * - * If this method exits early, before the simulation has finished, the entity is assumed to be shutdown and its - * simulation will not run any further. - */ - suspend override fun Context<Datacenter>.run() { - val logger = KotlinLogging.logger {} - - // The queue of messages to be processed after a cycle - val queue: Queue<Any> = ArrayDeque() - // Find all machines in the datacenter - val machines = outgoingEdges.destinations<Room>("room").asSequence() - .flatMap { it.outgoingEdges.destinations<Rack>("rack").asSequence() } - .flatMap { it.outgoingEdges.destinations<Machine>("machine").asSequence() }.toList() - - logger.info { "Initialising datacenter with ${machines.size} machines" } - - // Register all machines to the scheduler - machines.forEach(scheduler::register) - - while (true) { - // Process all messages in the queue - while (queue.isNotEmpty()) { - val msg = queue.poll() - if (msg is Task) { - msg.arrive(time) - scheduler.submit(msg) - } - } - // (Re)schedule the tasks - scheduler.run { schedule() } - - // Sleep a time quantum - wait(interval, queue) - } - } -} diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt deleted file mode 100644 index f97e73e9..00000000 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 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 nl.atlarge.opendc.topology.machine - -/** - * A central processing unit. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Cpu : ProcessingUnit diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt deleted file mode 100644 index 15c5263f..00000000 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 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 nl.atlarge.opendc.topology.machine - -/** - * A graphics processing unit. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Gpu : ProcessingUnit - diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt deleted file mode 100644 index b5016adb..00000000 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt +++ /dev/null @@ -1,123 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 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 nl.atlarge.opendc.topology.machine - -import mu.KotlinLogging -import nl.atlarge.opendc.topology.destinations -import nl.atlarge.opendc.platform.workload.Task -import nl.atlarge.opendc.kernel.Context -import nl.atlarge.opendc.kernel.Process -import nl.atlarge.opendc.kernel.time.Duration -import nl.atlarge.opendc.topology.Entity - -/** - * A Physical Machine (PM) inside a rack of a datacenter. It has a speed, and can be given a workload on which it will - * work until finished or interrupted. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -open class Machine : Entity<Machine.State>, Process<Machine> { - /** - * The logger instance to use for the simulator. - */ - private val logger = KotlinLogging.logger {} - - /** - * The status of a machine. - */ - enum class Status { - HALT, IDLE, RUNNING - } - - /** - * The shape of the state of a [Machine] entity. - * - * @property status The status of the machine. - * @property task The task assign to the machine. - * @property memory The memory usage of the machine (defaults to 50mb for the kernel) - * @property load The load on the machine (defaults to 0.0) - * @property temperature The temperature of the machine (defaults to 23 degrees Celcius) - */ - data class State(val status: Status, - val task: Task? = null, - val memory: Int = 50, - val load: Double = 0.0, - val temperature: Double = 23.0) - - /** - * The initial state of a [Machine] entity. - */ - override val initialState = State(Status.HALT) - - /** - * Run the simulation kernel for this entity. - */ - override suspend fun Context<Machine>.run() { - update(State(Status.IDLE)) - - val interval: Duration = 10 - val cpus = outgoingEdges.destinations<Cpu>("cpu") - val speed = cpus.fold(0, { acc, cpu -> acc + cpu.clockRate * cpu.cores }) - - // Halt the machine if it has not processing units (see bug #4) - if (cpus.isEmpty()) { - update(State(Status.HALT)) - return - } - - var task: Task = receiveTask() - update(State(Status.RUNNING, task, load = 1.0, memory = state.memory + 50, temperature = 30.0)) - - while (true) { - if (task.finished) { - logger.info { "${entity.id}: Task ${task.id} finished. Machine idle at $time" } - update(State(Status.IDLE)) - task = receiveTask() - } else { - task.consume(time, speed * delta) - } - - // Check if we have received a new order in the meantime. - val msg = receive(interval) - if (msg is Task) { - task = msg - update(State(Status.RUNNING, task, load = 1.0, memory = state.memory + 50, temperature = 30.0)) - } - } - } - - /** - * Wait for a [Task] to be received by the [Process] and discard all other messages received in the meantime. - * - * @return The task that has been received. - */ - private suspend fun Context<Machine>.receiveTask(): Task { - while (true) { - val msg = receive() - if (msg is Task) - return msg - } - } -} diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/network/NetworkUnit.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/network/NetworkUnit.kt deleted file mode 100644 index d3a9eefe..00000000 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/network/NetworkUnit.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 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 nl.atlarge.opendc.topology.network - -import nl.atlarge.opendc.topology.Entity - -/** - * A generic interface for a network unit in a cloud network. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface NetworkUnit : Entity<Unit> diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt deleted file mode 100644 index b9602e55..00000000 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 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 nl.atlarge.opendc.topology.power - -import nl.atlarge.opendc.topology.Entity - -/** - * An [Entity] which provides power for other entities a cloud network to run. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface PowerUnit : Entity<Unit> diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/storage/StorageUnit.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/storage/StorageUnit.kt deleted file mode 100644 index f719f152..00000000 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/storage/StorageUnit.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 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 nl.atlarge.opendc.topology.storage - -import nl.atlarge.opendc.topology.Entity - -/** - * A generic interface for a storage unit in a cloud network. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface StorageUnit : Entity<Unit> |
