Kotlin/Native samples ported to MPP Gradle DSL (#2261)

This commit is contained in:
Dmitriy Dolovov
2018-10-26 12:16:13 +07:00
committed by GitHub
parent 7d2aede90e
commit daf1a5fb8c
255 changed files with 2161 additions and 2461 deletions
+13 -9
View File
@@ -1,11 +1,11 @@
# Workers
This example shows how one could implement computation offload to other workers
This example shows how one could implement computation offload to other workers
(usually mapped to OS threads) and transfer data back and forth between workers.
Idea of workers is to avoid most common problems with concurrent programming, related
to simultaneous computations on the same data. Instead, each object belongs to
one or other worker's object graph, but could be disconnected from one worker
and connected to other worker. This relies on fact that memory management
and connected to other worker. This relies on the fact that memory management
engine can ensure, that one worker doesn't keep references to certain object and
whatever it refers to, and so the object could be safely transferred to another worker.
@@ -15,11 +15,13 @@ between workers, as long, as they do not refer to objects, having external refer
The transfer is implemented with the function `execute()` having the following signature
fun <T1, T2> execute(mode: TransferMode,
producer: () -> T1,
@VolatileLambda job: (T1) -> T2): Future<T2>
fun <T1, T2> execute(
mode: TransferMode,
producer: () -> T1,
@VolatileLambda job: (T1) -> T2
): Future<T2>
Kotlin/Native runtime invokes `producer()` function, and makes sure object it produces
Kotlin/Native runtime invokes `producer()` function, and makes sure object it produces
have a property, that no external references to subgraph rooted by this object, exists.
If property doesn't hold, either (depending on `mode` argument) exception is being thrown
or program may crash unexpectedly.
@@ -29,11 +31,13 @@ is being created. Once worker peeks the job from the queue, it executes stateles
with object provided, and stores stable pointer to result in future's data. Whenever
future is being consumed, object is passed to the consumer's callback.
This particular example starts several workers, and gives them some computational jobs.
This particular example starts several workers, and gives them some computational jobs.
Then it continues execution, and waits on future objects encapsulating the
computation results. Afterwards, worker execution termination is requested with the
`requestTermination()` operation.
To build use `./build.sh` or `./gradlew assemble`
To build use `../gradlew assemble`.
To run use `./build/exe/main/release/workers.kexe`
To run use `../gradlew runProgram` or execute the program directly:
./build/bin/workers/main/release/executable/workers.kexe
+13 -4
View File
@@ -1,5 +1,14 @@
apply plugin: 'org.jetbrains.kotlin.platform.native'
plugins {
id 'kotlin-multiplatform'
}
components.main {
outputKinds = [ EXECUTABLE ]
}
kotlin {
targets {
fromPreset(MPPTools.defaultHostPreset(project), 'workers') {
compilations.main.outputKinds 'EXECUTABLE'
compilations.main.entryPoint 'sample.workers.main'
}
}
}
MPPTools.createRunTask(project, 'runProgram', kotlin.targets.workers)
-29
View File
@@ -1,29 +0,0 @@
#!/usr/bin/env bash
DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$DIR/../konan.sh"
SUFFIX=kexe
if [ x$TARGET == x ]; then
case "$OSTYPE" in
darwin*) TARGET=macbook ;;
linux*) TARGET=linux ;;
msys*) TARGET=mingw; SUFFIX=exe ;;
*) echo "unknown: $OSTYPE" && exit 1;;
esac
fi
var=CFLAGS_${TARGET}
CFLAGS=${!var}
var=LINKER_ARGS_${TARGET}
LINKER_ARGS=${!var}
var=COMPILER_ARGS_${TARGET}
COMPILER_ARGS=${!var} # add -opt for an optimized build.
mkdir -p $DIR/build/bin/
konanc $COMPILER_ARGS -target $TARGET $DIR/src/main/kotlin/Workers.kt \
-o $DIR/build/bin/Workers || exit 1
echo "Artifact could be found at $DIR/build/bin/Workers.$SUFFIX"
+2
View File
@@ -0,0 +1,2 @@
kotlin.code.style=official
kotlin.import.noCommonSourceSets=true
@@ -1,22 +1,31 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package sample.workers
import kotlin.native.concurrent.*
data class WorkerArgument(val intParam: Int, val stringParam: String)
data class WorkerResult(val intResult: Int, val stringResult: String)
fun main(args: Array<String>) {
fun main() {
val COUNT = 5
val workers = Array(COUNT, { _ -> Worker.start()})
val workers = Array(COUNT, { _ -> Worker.start() })
for (attempt in 1 .. 3) {
val futures = Array(workers.size, { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, {
WorkerArgument(workerIndex, "attempt $attempt") }) { input ->
for (attempt in 1..3) {
val futures = Array(workers.size) { workerIndex ->
workers[workerIndex].execute(TransferMode.SAFE, {
WorkerArgument(workerIndex, "attempt $attempt")
}) { input ->
var sum = 0
for (i in 0..input.intParam * 1000) {
sum += i
}
WorkerResult(sum, input.stringParam + " result")
}
})
}
val futureSet = futures.toSet()
var consumed = 0
while (consumed < futureSet.size) {
@@ -32,5 +41,5 @@ fun main(args: Array<String>) {
workers.forEach {
it.requestTermination().result
}
println("OK")
println("Workers: OK")
}