Add a test
This commit is contained in:
@@ -2675,6 +2675,11 @@ task initializers5(type: KonanLocalTest) {
|
|||||||
source = "runtime/basic/initializers5.kt"
|
source = "runtime/basic/initializers5.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task initializers6(type: KonanLocalTest) {
|
||||||
|
disabled = project.testTarget == 'wasm32' // Needs workers.
|
||||||
|
source = "runtime/basic/initializers6.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task expression_as_statement(type: KonanLocalTest) {
|
task expression_as_statement(type: KonanLocalTest) {
|
||||||
expectedFail = (project.testTarget == 'wasm32') // uses exceptions.
|
expectedFail = (project.testTarget == 'wasm32') // uses exceptions.
|
||||||
goldValue = "Ok\n"
|
goldValue = "Ok\n"
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package runtime.basic.initializers6
|
||||||
|
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
import kotlin.native.concurrent.*
|
||||||
|
|
||||||
|
val aWorkerId = 2
|
||||||
|
val bWorkersCount = 3
|
||||||
|
|
||||||
|
val aWorkerUnlocker = AtomicInt(0)
|
||||||
|
val bWorkerUnlocker = AtomicInt(0)
|
||||||
|
|
||||||
|
object A {
|
||||||
|
init {
|
||||||
|
// Must be called by aWorker only.
|
||||||
|
assertEquals(aWorkerId, Worker.current.id)
|
||||||
|
// Only allow b workers to run, when a worker has started initialization.
|
||||||
|
bWorkerUnlocker.increment()
|
||||||
|
// Only proceed with initialization, when all b workers have started executing.
|
||||||
|
while (aWorkerUnlocker.value < bWorkersCount) {}
|
||||||
|
// And now wait a bit, to increase probability of races.
|
||||||
|
Worker.current.park(1000 * 1000L)
|
||||||
|
}
|
||||||
|
val a = produceA()
|
||||||
|
val b = produceB()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun produceA(): String {
|
||||||
|
// Must've been called by aWorker only.
|
||||||
|
assertEquals(aWorkerId, Worker.current.id)
|
||||||
|
return "A"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun produceB(): String {
|
||||||
|
// Must've been called by aWorker only.
|
||||||
|
assertEquals(aWorkerId, Worker.current.id)
|
||||||
|
// Also check that it's ok to get A.a while initializing A.b.
|
||||||
|
return "B+${A.a}"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun runTest() {
|
||||||
|
val aWorker = Worker.start()
|
||||||
|
// This test relies on aWorkerId value.
|
||||||
|
assertEquals(aWorkerId, aWorker.id)
|
||||||
|
val bWorkers = Array(bWorkersCount, { _ -> Worker.start() })
|
||||||
|
|
||||||
|
val aFuture = aWorker.execute(TransferMode.SAFE, {}, {
|
||||||
|
A.b
|
||||||
|
})
|
||||||
|
val bFutures = Array(bWorkers.size, {
|
||||||
|
bWorkers[it].execute(TransferMode.SAFE, {}, {
|
||||||
|
// Wait until A has started to initialize.
|
||||||
|
while (bWorkerUnlocker.value < 1) {}
|
||||||
|
// Now allow A initialization to continue.
|
||||||
|
aWorkerUnlocker.increment()
|
||||||
|
// And this should not've tried to init A itself.
|
||||||
|
A.a + A.b
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
for (future in bFutures) {
|
||||||
|
assertEquals("AB+A", future.result)
|
||||||
|
}
|
||||||
|
assertEquals("B+A", aFuture.result)
|
||||||
|
|
||||||
|
for (worker in bWorkers) {
|
||||||
|
worker.requestTermination().result
|
||||||
|
}
|
||||||
|
aWorker.requestTermination().result
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user