v0.3.1 preparations. (#806)

This commit is contained in:
Nikolay Igotti
2017-08-24 15:03:19 +03:00
committed by GitHub
parent 8957320504
commit 69bf28cc23
9 changed files with 171 additions and 28 deletions
+41
View File
@@ -0,0 +1,41 @@
# 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
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.
Workers do not share any state (i.e. globals and Kotlin static objects have different
values in different workers), but share executable code of the program and some
immutable data, such as immutable binary blobs. But Kotlin objects can be transferred
between workers, as long, as they do not refer to objects, having external references.
The transfer is implemented with the function `schedule()` having the following signature
fun <T1, T2>
schedule(mode: TransferMode,
producer: () -> T1,
@VolatileLambda job: (T1) -> T2): Future<T2>
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.
Then, pointer to stateless lambda `job` along with the stable pointer to parameter object
is being added to the target worker's queue, and `Future` object matching to the query
is being created. Once worker peeks the job from the queue, it executes stateless lambda
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.
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`.
To run use `./build/konan/bin/Worker.kexe`
+35
View File
@@ -0,0 +1,35 @@
import konan.worker.*
data class WorkerArgument(val intParam: Int, val stringParam: String)
data class WorkerResult(val intResult: Int, val stringResult: String)
fun main(args: Array<String>) {
val COUNT = 5
val workers = Array(COUNT, { _ -> startWorker()})
for (attempt in 1 .. 3) {
val futures = Array(workers.size, { workerIndex -> workers[workerIndex].schedule(TransferMode.CHECKED, {
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) {
val ready = futureSet.waitForMultipleFutures(10000)
ready.forEach {
it.consume { result ->
if (result.stringResult != "attempt $attempt result") throw Error("Unexpected $result")
consumed++ }
}
}
}
workers.forEach {
it.requestTermination().consume { _ -> }
}
println("OK")
}
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
DIR=$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd )
PATH=$DIR/../../dist/bin:$DIR/../../bin:$PATH
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/Workers.kt \
-o $DIR/build/bin/Workers || exit 1
echo "Artifact could be found at $DIR/build/bin/Workers.$SUFFIX"