Gross stdlib cleanup (part 2) (#1924)

This commit is contained in:
Nikolay Igotti
2018-08-24 10:14:10 +03:00
committed by GitHub
parent 6d4218c3af
commit 59eae5e04b
60 changed files with 135 additions and 165 deletions
+2 -2
View File
@@ -48,7 +48,7 @@ framework("MyCustomFramework") {
### Q: Why do I see `InvalidMutabilityException`?
A: It likely happens, because you are trying to mutate a frozen object. Object could transfer to the
frozen state either explicitly, as objects reachable from objects on which `konan.worker.freeze` is called,
frozen state either explicitly, as objects reachable from objects on which `kotlin.native.concurrent.freeze` is called,
or implicitly (i.e. reachable from `enum` or global singleton object - see next question).
@@ -56,7 +56,7 @@ or implicitly (i.e. reachable from `enum` or global singleton object - see next
A: Currently, singleton objects are immutable (i.e. frozen after creation), and it's generally considered
a good practise to have global state immutable. If for some reasons you need mutable state inside such an
object, use `@konan.ThreadLocal` annotation on the object. Also `konan.worker.AtomicReference` class could be
object, use `@konan.ThreadLocal` annotation on the object. Also `kotlin.native.concurrent.AtomicReference` class could be
used to store different pointers to frozen objects in a frozen object and atomically update those.
### Q: How can I compile my project against Kotlin/Native master?
+1 -1
View File
@@ -5,7 +5,7 @@ important invariant that object is either immutable or
accessible from the single thread at the moment (`mutable XOR global`).
Immutability is the runtime property in Kotlin/Native, and can be applied
to an arbitrary object subgraph using `konan.worker.freeze` function.
to an arbitrary object subgraph using `kotlin.native.concurrent.freeze` function.
It makes all objects reachable from the given one immutable, and
such a transition is a one way operation (object cannot be unfrozen later).
Some naturally immutable objects, such as `kotlin.String`, `kotlin.Int` and
@@ -79,12 +79,12 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns, vararg konanPrimitives:
val staticCFunction = packageScope.getContributedFunctions("staticCFunction").toSet()
val workerPackageScope = builtIns.builtInsModule.getPackage(FqName("kotlin.native.worker")).memberScope
val concurrentPackageScope = builtIns.builtInsModule.getPackage(FqName("kotlin.native.concurrent")).memberScope
val scheduleFunction = workerPackageScope.getContributedClass("Worker")
val scheduleFunction = concurrentPackageScope.getContributedClass("Worker")
.unsubstitutedMemberScope.getContributedFunctions("schedule").single()
val scheduleImplFunction = workerPackageScope.getContributedFunctions("scheduleImpl").single()
val scheduleImplFunction = concurrentPackageScope.getContributedFunctions("scheduleImpl").single()
val signExtend = packageScope.getContributedFunctions("signExtend").single()
@@ -297,10 +297,12 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable, val
context.getInternalFunctions("valueOfForEnum").single())
val enumValues = symbolTable.referenceSimpleFunction(
builtInsPackage("kotlin").getContributedFunctions(Name.identifier("enumValues"), NoLookupLocation.FROM_BACKEND).single())
builtInsPackage("kotlin").getContributedFunctions(
Name.identifier("enumValues"), NoLookupLocation.FROM_BACKEND).single())
val enumValueOf = symbolTable.referenceSimpleFunction(
builtInsPackage("kotlin").getContributedFunctions(Name.identifier("enumValueOf"), NoLookupLocation.FROM_BACKEND).single())
builtInsPackage("kotlin").getContributedFunctions(
Name.identifier("enumValueOf"), NoLookupLocation.FROM_BACKEND).single())
val createUninitializedInstance = symbolTable.referenceSimpleFunction(
context.getInternalFunctions("createUninitializedInstance").single())
@@ -309,14 +311,17 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable, val
context.getInternalFunctions("initInstance").single())
val freeze = symbolTable.referenceSimpleFunction(
builtInsPackage("kotlin", "native", "worker").getContributedFunctions(Name.identifier("freeze"), NoLookupLocation.FROM_BACKEND).single())
builtInsPackage("kotlin", "native", "concurrent").getContributedFunctions(
Name.identifier("freeze"), NoLookupLocation.FROM_BACKEND).single())
val println = symbolTable.referenceSimpleFunction(
builtInsPackage("kotlin", "io").getContributedFunctions(Name.identifier("println"), NoLookupLocation.FROM_BACKEND)
builtInsPackage("kotlin", "io").getContributedFunctions(
Name.identifier("println"), NoLookupLocation.FROM_BACKEND)
.single { it.valueParameters.singleOrNull()?.type == builtIns.stringType })
val anyNToString = symbolTable.referenceSimpleFunction(
builtInsPackage("kotlin").getContributedFunctions(Name.identifier("toString"), NoLookupLocation.FROM_BACKEND)
builtInsPackage("kotlin").getContributedFunctions(
Name.identifier("toString"), NoLookupLocation.FROM_BACKEND)
.single { it.extensionReceiverParameter?.type == builtIns.nullableAnyType})
val getContinuation = symbolTable.referenceSimpleFunction(
@@ -350,10 +355,8 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable, val
.filterNot { it.isExpect }.single().getter!!
)
// removed in Big Kotlin @c62e4b4fcf50e99800e6d5c3a220101b691e1d43
val refClass = symbolTable.referenceClass(context.getInternalClass("Ref"))
val kLocalDelegatedPropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedPropertyImpl)
val kLocalDelegatedMutablePropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedMutablePropertyImpl)
@@ -376,7 +379,7 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable, val
symbolTable.referenceClass(context.getInternalClass(name))
private fun getKonanTestClass(className: String) = symbolTable.referenceClass(
builtInsPackage("kotlin", "native", "test").getContributedClassifier(
builtInsPackage("kotlin", "native", "internal", "test").getContributedClassifier(
Name.identifier(className), NoLookupLocation.FROM_BACKEND
) as ClassDescriptor)
@@ -61,7 +61,7 @@ internal fun findMainEntryPoint(context: Context): FunctionDescriptor? {
}
private val defaultEntryName = "main"
private val testEntryName = "kotlin.native.test.main"
private val testEntryName = "kotlin.native.internal.test.main"
private val defaultEntryPackage = FqName.ROOT
@@ -346,7 +346,7 @@ internal class TestProcessor (val context: KonanBackendContext) {
}
/**
* Builds a method in `[testSuite]` class with anem `[getterName]`
* Builds a method in `[testSuite]` class with name `[getterName]`
* returning a new instance of class referenced by [classSymbol].
*/
private inner class InstanceGetterBuilder(val classSymbol: IrClassSymbol, testSuite: IrClassSymbol, getterName: Name)
@@ -1,7 +1,7 @@
package codegen.enum.isFrozen
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
enum class Zzz(val zzz: String) {
Z1("z1"),
@@ -1,6 +1,6 @@
package runtime.basic.worker_random
import kotlin.native.worker.*
import kotlin.native.concurrent.*
import kotlin.collections.*
import kotlin.random.*
import kotlin.system.*
@@ -2,7 +2,7 @@ package runtime.workers.atomic0
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
fun test1(workers: Array<Worker>) {
val atomic = AtomicInt(15)
@@ -1,7 +1,7 @@
package runtime.workers.enum_identity
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
enum class A {
A, B
@@ -18,7 +18,7 @@ package runtime.workers.freeze0
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
data class SharedDataMember(val double: Double)
@@ -18,7 +18,7 @@ package runtime.workers.freeze1
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
data class Node(var previous: Node?, var data: Int)
@@ -18,7 +18,7 @@ package runtime.workers.freeze2
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
data class Data(var int: Int)
@@ -2,7 +2,7 @@ package runtime.workers.freeze3
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
object Immutable {
var x = 1
@@ -2,7 +2,7 @@ package runtime.workers.freeze4
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
data class Data(val x: Int, val s: String, val next: Data? = null)
@@ -1,6 +1,7 @@
package runtime.workers.freeze5
import kotlin.test.*
object Keys {
internal val myMap: Map<String, List<String>> = mapOf(
"val1" to listOf("a1", "a2", "a3"),
@@ -2,7 +2,7 @@ package runtime.workers.freeze_stress
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
class Random(private var seed: Int) {
fun next(): Int {
@@ -2,7 +2,7 @@ package runtime.workers.lazy0
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
data class Data(val x: Int, val y: String)
@@ -2,7 +2,7 @@ package runtime.workers.lazy1
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
class Leak {
val leak by lazy { this }
@@ -2,11 +2,11 @@ package runtime.workers.worker0
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
@Test fun runTest() {
val worker = startWorker()
val future = worker.schedule(TransferMode.CHECKED, { "Input".shallowCopy()}) {
val future = worker.schedule(TransferMode.CHECKED, { "Input" }) {
input -> input + " processed"
}
future.consume {
@@ -2,7 +2,7 @@ package runtime.workers.worker1
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
@Test fun runTest() {
val COUNT = 5
@@ -10,7 +10,7 @@ import kotlin.native.worker.*
for (attempt in 1 .. 3) {
val futures = Array(workers.size,
{ i -> workers[i].schedule(TransferMode.CHECKED, { "$attempt: Input $i".shallowCopy() })
{ i -> workers[i].schedule(TransferMode.CHECKED, { "$attempt: Input $i" })
{ input -> input + " processed" }
})
futures.forEachIndexed { index, future ->
@@ -2,7 +2,7 @@ package runtime.workers.worker2
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
data class WorkerArgument(val intParam: Int, val stringParam: String)
data class WorkerResult(val intResult: Int, val stringResult: String)
@@ -2,7 +2,7 @@ package runtime.workers.worker3
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
data class DataParam(var int: Int)
data class WorkerArgument(val intParam: Int, val dataParam: DataParam)
@@ -2,7 +2,7 @@ package runtime.workers.worker4
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
@Test fun runTest() {
val worker = startWorker()
@@ -2,11 +2,11 @@ package runtime.workers.worker5
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
@Test fun runTest() {
val worker = startWorker()
val future = worker.schedule(TransferMode.CHECKED, { "zzz".shallowCopy() }) {
val future = worker.schedule(TransferMode.CHECKED, { "zzz" }) {
input -> input.length
}
future.consume {
@@ -2,7 +2,7 @@ package runtime.workers.worker6
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
@Test fun runTest() {
val worker = startWorker()
@@ -2,11 +2,11 @@ package runtime.workers.worker7
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
@Test fun runTest() {
val worker = startWorker()
val future = worker.schedule(TransferMode.CHECKED, { "Input".shallowCopy() }) {
val future = worker.schedule(TransferMode.CHECKED, { "Input" }) {
input -> println(input)
}
future.consume {
@@ -2,7 +2,7 @@ package runtime.workers.worker8
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
data class SharedDataMember(val double: Double)
@@ -2,7 +2,7 @@ package runtime.workers.worker9
import kotlin.test.*
import kotlin.native.worker.*
import kotlin.native.concurrent.*
@Test fun runTest() {
withLock { println("zzz") }
+1 -2
View File
@@ -1,8 +1,7 @@
package kotlin.test.tests
import kotlin.test.*
import kotlin.native.test.*
import kotlin.native.internal.test.*
@Ignore
class IgnoredClass {
+1 -1
View File
@@ -1,7 +1,7 @@
package kotlin.test.tests
import kotlin.test.*
import kotlin.native.test.*
import kotlin.native.internal.test.*
@Test
fun test() {
-28
View File
@@ -415,25 +415,6 @@ KInt schedule(KInt id, KInt transferMode, KRef producer, KNativePtr jobFunction)
return future->id();
}
OBJ_GETTER(shallowCopy, KConstRef object) {
if (object == nullptr) RETURN_OBJ(nullptr);
const TypeInfo* typeInfo = object->type_info();
bool isArray = typeInfo->instanceSize_ < 0;
KRef result = isArray ?
AllocArrayInstance(typeInfo, object->array()->count_, OBJ_RESULT) :
AllocInstance(typeInfo, OBJ_RESULT);
// TODO: what to do when object references exist.
if (isArray) {
RuntimeAssert(object->array()->count_ == 0 || typeInfo != theArrayTypeInfo, "Object array copy unimplemented");
memcpy(result->array() + 1, object->array() + 1, ArrayDataSizeBytes(object->array()));
} else {
RuntimeAssert(typeInfo->objOffsetsCount_ == 0, "Object reference copy unimplemented");
memcpy(result + 1, object + 1, typeInfo->instanceSize_);
}
return result;
}
KInt stateOfFuture(KInt id) {
return theState()->stateOfFutureUnlocked(id);
}
@@ -477,11 +458,6 @@ KInt startWorker() {
return -1;
}
OBJ_GETTER(shallowCopy, KConstRef object) {
ThrowWorkerUnsupported();
RETURN_OBJ(nullptr);
}
KInt stateOfFuture(KInt id) {
ThrowWorkerUnsupported();
return 0;
@@ -540,10 +516,6 @@ KInt Kotlin_Worker_scheduleInternal(KInt id, KInt transferMode, KRef producer, K
return schedule(id, transferMode, producer, job);
}
OBJ_GETTER(Kotlin_Worker_shallowCopyInternal, KConstRef object) {
RETURN_RESULT_OF(shallowCopy, object);
}
KInt Kotlin_Worker_stateOfFuture(KInt id) {
return stateOfFuture(id);
}
+2 -1
View File
@@ -19,7 +19,8 @@ package kotlin
/**
* A vector of bits growing if necessary and allowing one to set/clear/read bits from it by a bit index.
*/
class BitSet(size: Int = ELEMENT_SIZE) {
// TODO: make me internal!
public class BitSet(size: Int = ELEMENT_SIZE) {
companion object {
// Size of one element in the array used to store bits.
+3 -2
View File
@@ -16,8 +16,9 @@
package kotlin
import kotlin.reflect.KProperty
import kotlin.native.concurrent.FreezeAwareLazyImpl
import kotlin.native.internal.FixmeConcurrency
import kotlin.reflect.KProperty
/**
* Creates a new instance of the [Lazy] that uses the specified initialization function [initializer]
@@ -28,7 +29,7 @@ import kotlin.native.internal.FixmeConcurrency
* Note that the returned instance uses itself to synchronize on. Do not synchronize from external code on
* the returned instance as it may cause accidental deadlock. Also this behavior can be changed in the future.
*/
public actual fun <T> lazy(initializer: () -> T): Lazy<T> = kotlin.native.worker.FreezeAwareLazyImpl(initializer)
public actual fun <T> lazy(initializer: () -> T): Lazy<T> = FreezeAwareLazyImpl(initializer)
/**
* Creates a new instance of the [Lazy] that uses the specified initialization function [initializer]
+5 -3
View File
@@ -1182,7 +1182,8 @@ public final class Float private constructor(private val value: kotlin.native.in
}
@SymbolName("Kotlin_Float_bits")
external public fun bits(): Int
@PublishedApi
external internal fun bits(): Int
}
/**
@@ -1398,10 +1399,11 @@ public final class Double private constructor(private val value: kotlin.native.i
public override fun equals(other: Any?): Boolean = other is Double && this.equals(other)
public override fun toString() = NumberConverter.convert(this)
public override fun toString(): String = NumberConverter.convert(this)
public override fun hashCode(): Int = bits().hashCode()
@SymbolName("Kotlin_Double_bits")
external public fun bits(): Long
@PublishedApi
external internal fun bits(): Long
}
@@ -16,7 +16,7 @@
package kotlin.collections
import kotlin.native.worker.isFrozen
import kotlin.native.concurrent.isFrozen
actual class HashMap<K, V> private constructor(
private var keysArray: Array<K>,
@@ -16,7 +16,7 @@
package kotlin.collections
fun Int.highestOneBit() : Int {
internal fun Int.highestOneBit() : Int {
var index = 31
while (index >= 0) {
@@ -29,7 +29,7 @@ fun Int.highestOneBit() : Int {
return 0
}
fun Int.numberOfLeadingZeros() : Int {
internal fun Int.numberOfLeadingZeros() : Int {
var index = 31
while (index >= 0) {
@@ -27,4 +27,4 @@ actual annotation class JvmMultifileClass
actual annotation class JvmField
@Target(AnnotationTarget.FIELD)
actual annotation class Volatile
actual annotation class Volatile
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package kotlin.native.worker
package kotlin.native.concurrent
import kotlin.native.internal.Frozen
import kotlin.native.internal.NoReorderFields
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package kotlin.native.worker
package kotlin.native.concurrent
import kotlin.native.internal.ExportForCppRuntime
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package kotlin.native.worker
package kotlin.native.concurrent
import kotlin.native.SymbolName
import kotlin.native.internal.ExportForCppRuntime
@@ -40,12 +40,11 @@ enum class FutureState(val value: Int) {
/**
* Class representing abstract computation, whose result may become available in the future.
*/
// TODO: make me value class!
class Future<T> internal constructor(val id: FutureId) {
public inline class Future<T>(val id: FutureId) {
/**
* Blocks execution until the future is ready.
*/
inline fun <R> consume(code: (T) -> R) =
public inline fun <R> consume(code: (T) -> R): R =
when (state) {
FutureState.SCHEDULED, FutureState.COMPUTED -> {
val value = @Suppress("UNCHECKED_CAST", "NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") (consumeFuture(id) as T)
@@ -57,21 +56,21 @@ class Future<T> internal constructor(val id: FutureId) {
throw IllegalStateException("Future is cancelled")
}
fun result(): T = consume { it -> it }
public fun result(): T = consume { it -> it }
val state: FutureState
public val state: FutureState
get() = FutureState.values()[stateOfFuture(id)]
override fun equals(other: Any?) = (other is Future<*>) && (id == other.id)
public override fun equals(other: Any?): Boolean = (other is Future<*>) && (id == other.id)
override fun hashCode() = id
public override fun hashCode(): Int = id
}
/**
* Wait for availability of futures in the collection. Returns set with all futures which have
* value available for the consumption.
*/
fun <T> Collection<Future<T>>.waitForMultipleFutures(millis: Int): Set<Future<T>> {
public fun <T> Collection<Future<T>>.waitForMultipleFutures(millis: Int): Set<Future<T>> {
val result = mutableSetOf<Future<T>>()
while (true) {
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package kotlin.native.worker
package kotlin.native.concurrent
import kotlin.native.internal.NoReorderFields
@@ -65,7 +65,9 @@ internal class FreezeAwareLazyImpl<out T>(initializer: () -> T) : Lazy<T> {
}
}
// Racy!
/**
* This operation on shared objects may return value which is no longer reflect the current state of lazy.
*/
override fun isInitialized(): Boolean = (value_ !== UNINITIALIZED) && (value_ !== INITIALIZING)
override fun toString(): String = if (isInitialized())
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package kotlin.native.worker
package kotlin.native.concurrent
import kotlin.native.internal.Frozen
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package kotlin.native.worker
package kotlin.native.concurrent
import kotlinx.cinterop.*
@@ -46,17 +46,6 @@ enum class TransferMode(val value: Int) {
UNCHECKED(1) // USE UNCHECKED MODE ONLY IF ABSOLUTELY SURE WHAT YOU'RE DOING!!!
}
/**
* Creates verbatim *shallow* copy of passed object, use carefully to create disjoint object graph.
*/
inline fun <reified T> T.shallowCopy(): T = shallowCopyInternal(this) as T
/**
* Creates verbatim *deep* copy of passed object's graph, use *VERY* carefully to create disjoint object graph.
* Note that this function could potentially duplicate a lot of objects.
*/
inline fun <reified T> T.deepCopy(): T = TODO()
/**
* Creates stable pointer to object, ensuring associated object subgraph is disjoint in specified mode
* ([TransferMode.CHECKED] by default).
@@ -75,11 +64,9 @@ inline fun <reified T> attachObjectGraph(stable: COpaquePointer?): T =
// Private APIs.
@PublishedApi
@SymbolName("Kotlin_Worker_shallowCopyInternal")
external internal fun shallowCopyInternal(value: Any?): Any?
@PublishedApi
@SymbolName("Kotlin_Worker_detachObjectGraphInternal")
external internal fun detachObjectGraphInternal(mode: Int, producer: () -> Any?): COpaquePointer?
@PublishedApi
@SymbolName("Kotlin_Worker_attachObjectGraphInternal")
external internal fun attachObjectGraphInternal(stable: COpaquePointer?): Any?
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package kotlin.native.worker
package kotlin.native.concurrent
import kotlin.native.SymbolName
import kotlin.native.internal.ExportForCppRuntime
@@ -42,12 +42,12 @@ typealias WorkerId = Int
* Class representing worker.
*/
// TODO: make me value class!
class Worker(val id: WorkerId) {
public class Worker(val id: WorkerId) {
/**
* Requests termination of the worker. `processScheduledJobs` controls is we shall wait
* until all scheduled jobs processed, or terminate immediately.
*/
fun requestTermination(processScheduledJobs: Boolean = true) =
public fun requestTermination(processScheduledJobs: Boolean = true) =
Future<Nothing?>(requestTerminationInternal(id, processScheduledJobs))
/**
@@ -61,7 +61,7 @@ class Worker(val id: WorkerId) {
* the future, can use result of worker's computations.
*/
@Suppress("UNUSED_PARAMETER")
fun <T1, T2> schedule(mode: TransferMode, producer: () -> T1, @VolatileLambda job: (T1) -> T2): Future<T2> =
public fun <T1, T2> schedule(mode: TransferMode, producer: () -> T1, @VolatileLambda job: (T1) -> T2): Future<T2> =
/**
* This function is a magical operation, handled by lowering in the compiler, and replaced with call to
* scheduleImpl(worker, mode, producer, job)
@@ -69,9 +69,9 @@ class Worker(val id: WorkerId) {
*/
throw RuntimeException("Shall not be called directly")
override fun equals(other: Any?) = (other is Worker) && (id == other.id)
override public fun equals(other: Any?): Boolean = (other is Worker) && (id == other.id)
override fun hashCode() = id
override public fun hashCode(): Int = id
}
/**
@@ -79,7 +79,7 @@ class Worker(val id: WorkerId) {
* Typically new worker may be needed for computations offload to another core, for IO it may be
* better to use non-blocking IO combined with more lightweight coroutines.
*/
fun startWorker(): Worker = Worker(startInternal())
public fun startWorker(): Worker = Worker(startInternal())
// Private APIs.
@kotlin.native.internal.ExportForCompiler
@@ -14,9 +14,9 @@
* limitations under the License.
*/
package kotlin.native.test
package kotlin.native.internal.test
class GTestLogger : TestLoggerWithStatistics() {
internal class GTestLogger : TestLoggerWithStatistics() {
private val Collection<TestSuite>.totalTestsNotIgnored: Int
get() = asSequence().filter { !it.ignored }.sumBy { it.testCases.values.count { !it.ignored } }
@@ -14,14 +14,14 @@
* limitations under the License.
*/
package kotlin.native.test
package kotlin.native.internal.test
import kotlin.system.exitProcess
@ThreadLocal
private val _generatedSuites = mutableListOf<TestSuite>()
internal fun registerSuite(suite: TestSuite): Unit {
public fun registerSuite(suite: TestSuite): Unit {
_generatedSuites.add(suite)
}
@@ -14,11 +14,11 @@
* limitations under the License.
*/
package kotlin.native.test
package kotlin.native.internal.test
import kotlin.text.StringBuilder
class TeamCityLogger : BaseTestLogger() {
internal class TeamCityLogger : BaseTestLogger() {
private fun String.escapeForTC(): String = StringBuilder(length).apply {
for(char in this@escapeForTC) {
@@ -14,9 +14,9 @@
* limitations under the License.
*/
package kotlin.native.test
package kotlin.native.internal.test
interface TestListener {
internal interface TestListener {
fun startTesting(runner: TestRunner)
fun finishTesting(runner: TestRunner, timeMillis: Long)
@@ -33,7 +33,7 @@ interface TestListener {
fun ignore(testCase: TestCase)
}
open class BaseTestListener: TestListener {
internal open class BaseTestListener: TestListener {
override fun startTesting(runner: TestRunner) {}
override fun finishTesting(runner: TestRunner, timeMillis: Long) {}
override fun startIteration(runner: TestRunner, iteration: Int, suites: Collection<TestSuite>) {}
@@ -14,14 +14,14 @@
* limitations under the License.
*/
package kotlin.native.test
package kotlin.native.internal.test
interface TestLogger: TestListener {
internal interface TestLogger: TestListener {
fun logTestList(runner: TestRunner, suites: Collection<TestSuite>)
fun log(message: String)
}
open class BaseTestLogger: BaseTestListener(), TestLogger {
internal open class BaseTestLogger: BaseTestListener(), TestLogger {
override fun log(message: String) = println(message)
override fun logTestList(runner: TestRunner, suites: Collection<TestSuite>) {
suites.forEach { suite ->
@@ -33,7 +33,7 @@ open class BaseTestLogger: BaseTestListener(), TestLogger {
}
}
open class TestLoggerWithStatistics: BaseTestLogger() {
internal open class TestLoggerWithStatistics: BaseTestLogger() {
protected val statistics = MutableTestStatistics()
@@ -46,13 +46,13 @@ open class TestLoggerWithStatistics: BaseTestLogger() {
override fun ignore(testCase: TestCase) = statistics.registerIgnore()
}
class SilentTestLogger: BaseTestLogger() {
internal class SilentTestLogger: BaseTestLogger() {
override fun logTestList(runner: TestRunner, suites: Collection<TestSuite>) {}
override fun log(message: String) {}
override fun fail(testCase: TestCase, e: Throwable, timeMillis: Long) = e.printStackTrace()
}
class SimpleTestLogger: BaseTestLogger() {
internal class SimpleTestLogger: BaseTestLogger() {
override fun startTesting(runner: TestRunner) = println("Starting testing")
override fun finishTesting(runner: TestRunner, timeMillis: Long) = println("Testing finished")
@@ -14,14 +14,14 @@
* limitations under the License.
*/
package kotlin.native.test
package kotlin.native.internal.test
import kotlin.IllegalArgumentException
import kotlin.system.getTimeMillis
import kotlin.system.measureTimeMillis
import kotlin.text.StringBuilder
class TestRunner(val suites: List<TestSuite>, args: Array<String>) {
internal class TestRunner(val suites: List<TestSuite>, args: Array<String>) {
private val filters = mutableListOf<(TestCase) -> Boolean>()
private val listeners = mutableSetOf<TestListener>()
private var logger: TestLogger = GTestLogger()
@@ -14,9 +14,9 @@
* limitations under the License.
*/
package kotlin.native.test
package kotlin.native.internal.test
interface TestStatistics {
internal interface TestStatistics {
val total: Int
val passed: Int
val failed: Int
@@ -28,7 +28,7 @@ interface TestStatistics {
val hasFailedTests: Boolean
}
class MutableTestStatistics: TestStatistics {
internal class MutableTestStatistics: TestStatistics {
override var total: Int = 0; private set
override var passed: Int = 0; private set
@@ -14,13 +14,13 @@
* limitations under the License.
*/
package kotlin.native.test
package kotlin.native.internal.test
import kotlin.IllegalArgumentException
import kotlin.system.getTimeMillis
import kotlin.system.measureTimeMillis
interface TestCase {
public interface TestCase {
val name: String
val ignored: Boolean
val suite: TestSuite
@@ -30,7 +30,7 @@ interface TestCase {
internal val TestCase.prettyName get() = "${suite.name}.$name"
interface TestSuite {
public interface TestSuite {
val name: String
val ignored: Boolean
val testCases: Map<String, TestCase>
@@ -40,14 +40,14 @@ interface TestSuite {
fun doAfterClass()
}
enum class TestFunctionKind {
public enum class TestFunctionKind {
BEFORE_EACH,
AFTER_EACH,
BEFORE_CLASS,
AFTER_CLASS
}
abstract class AbstractTestSuite<F: Function<Unit>>(override val name: String, override val ignored: Boolean)
public abstract class AbstractTestSuite<F: Function<Unit>>(override val name: String, override val ignored: Boolean)
: TestSuite {
override fun toString(): String = name
@@ -80,7 +80,7 @@ abstract class AbstractTestSuite<F: Function<Unit>>(override val name: String, o
get() = testCases.size
}
abstract class BaseClassSuite<INSTANCE, COMPANION>(name: String, ignored: Boolean)
public abstract class BaseClassSuite<INSTANCE, COMPANION>(name: String, ignored: Boolean)
: AbstractTestSuite<INSTANCE.() -> Unit>(name, ignored) {
class TestCase<INSTANCE, COMPANION>(name: String,
@@ -145,7 +145,7 @@ abstract class BaseClassSuite<INSTANCE, COMPANION>(name: String, ignored: Boolea
private typealias TopLevelFun = () -> Unit
class TopLevelSuite(name: String): AbstractTestSuite<TopLevelFun>(name, false) {
public class TopLevelSuite(name: String): AbstractTestSuite<TopLevelFun>(name, false) {
class TestCase(name: String, override val suite: TopLevelSuite, testFunction: TopLevelFun, ignored: Boolean)
: BasicTestCase<TopLevelFun>(name, suite, testFunction, ignored) {
@@ -21,7 +21,7 @@ package kotlin.native.ref
* retrieve a strong reference to an object, or return null, if object was already destoyed by
* the memory manager.
*/
class WeakReference<T : Any> {
public class WeakReference<T : Any> {
/**
* Creates a weak reference object pointing to an object. Weak reference doesn't prevent
* removing object, and is nullified once object is collected.
@@ -42,9 +42,10 @@ class WeakReference<T : Any> {
public fun clear() {
pointer = null
}
/**
* Returns either reference to an object or null, if it was collected.
*/
public fun get(): T? = pointer?.get() as T?
}
/**
* Returns either reference to an object or null, if it was collected.
*/
public inline fun <reified T : Any> WeakReference<T>.get() = pointer?.get() as T?
@@ -15,7 +15,7 @@
*/
package kotlin.random
import kotlin.native.worker.AtomicLong
import kotlin.native.concurrent.AtomicLong
import kotlin.system.getTimeNanos
abstract class NativeRandom {
@@ -33,10 +33,9 @@
package kotlin.text.regex
import kotlin.native.worker.AtomicReference
import kotlin.collections.associate
import kotlin.native.worker.freeze
import kotlin.native.concurrent.AtomicReference
import kotlin.native.concurrent.freeze
/**
* Unicode category (i.e. Ll, Lu).
@@ -15,9 +15,10 @@
*/
import global.*
import kotlin.native.concurrent.*
import kotlinx.cinterop.*
import platform.posix.*
import kotlin.native.worker.*
inline fun Int.ensureUnixCallResult(op: String, predicate: (Int) -> Boolean = { x -> x == 0} ): Int {
if (!predicate(this)) {
@@ -49,7 +50,7 @@ fun main(args: Array<String>) {
sharedData.f = 0.5f
sharedData.string = "Hello Kotlin!".cstr.getPointer(arena)
// Here we create detached mutable object, which could be later reattached by another thread.
sharedData.kotlinObject = kotlin.native.worker.detachObjectGraph {
sharedData.kotlinObject = detachObjectGraph {
SharedData("A string", 42, SharedDataMember(2.39))
}
// Here we create shared frozen object reference,
@@ -66,12 +67,12 @@ fun main(args: Array<String>) {
argC ->
initRuntimeIfNeeded()
dumpShared("thread2")
val kotlinObject = kotlin.native.worker.attachObjectGraph<SharedData>(sharedData.kotlinObject)
val arg = kotlin.native.worker.attachObjectGraph<SharedDataMember>(argC)
val kotlinObject = attachObjectGraph<SharedData>(sharedData.kotlinObject)
val arg = attachObjectGraph<SharedDataMember>(argC)
println("thread arg is $arg Kotlin object is $kotlinObject frozen is $globalObject")
// Workaround for compiler issue.
null as COpaquePointer?
}, kotlin.native.worker.detachObjectGraph { SharedDataMember(3.14)} ).ensureUnixCallResult("pthread_create")
}, detachObjectGraph { SharedDataMember(3.14)} ).ensureUnixCallResult("pthread_create")
pthread_join(thread.value, null).ensureUnixCallResult("pthread_join")
}
+4 -2
View File
@@ -1,3 +1,5 @@
import kotlin.native.concurrent.attachObjectGraph
import kotlin.native.concurrent.detachObjectGraph
import kotlinx.cinterop.*
import platform.AppKit.*
import platform.Foundation.*
@@ -30,12 +32,12 @@ private class Controller : NSObject() {
@ObjCAction
fun onClick() {
// Execute some async action on button click.
dispatch_async_f(asyncQueue, kotlin.native.worker.detachObjectGraph {
dispatch_async_f(asyncQueue, detachObjectGraph {
Data(clock_gettime_nsec_np(CLOCK_REALTIME))
}, staticCFunction {
it ->
initRuntimeIfNeeded()
val data = kotlin.native.worker.attachObjectGraph<Data>(it)
val data = attachObjectGraph<Data>(it)
println("in async: $data")
})
}
@@ -15,8 +15,8 @@
*/
import ffmpeg.*
import kotlin.native.concurrent.*
import kotlinx.cinterop.*
import kotlin.native.worker.*
import platform.posix.memcpy
// This global variable only set to != null value in the decoding worker.
@@ -329,7 +329,7 @@ class DecoderWorker : Disposable {
// All the real state must be stored on the worker's side.
private val worker: Worker
constructor() { worker = kotlin.native.worker.startWorker() }
constructor() { worker = startWorker() }
constructor(id: WorkerId) { worker = Worker(id) }
override fun dispose() {
+1 -1
View File
@@ -1,4 +1,4 @@
import kotlin.native.worker.*
import kotlin.native.concurrent.*
data class WorkerArgument(val intParam: Int, val stringParam: String)
data class WorkerResult(val intResult: Int, val stringResult: String)