Documentation fixes to stdlib (#2026)
This commit is contained in:
committed by
Nikolay Igotti
parent
78aac03c10
commit
db8555b561
+3
-2
@@ -78,12 +78,13 @@
|
||||
<a name="detach"></a>
|
||||
## Object subgraph detachment
|
||||
|
||||
An object subgraph without external references can be disconnected using `detachObjectGraph` to
|
||||
An object subgraph without external references can be disconnected using `DetachedObjectGraph<T>` to
|
||||
a `COpaquePointer` value, which could be stored in `void*` data, so the disconnected object subgraphs
|
||||
can be stored in a C data structure, and later attached back with `attachObjectGraph<T>` in an arbitrary thread
|
||||
can be stored in a C data structure, and later attached back with `DetachedObjectGraph<T>.attach()` in an arbitrary thread
|
||||
or a worker. Combining it with [raw memory sharing](#shared) it allows side channel object transfer between
|
||||
concurrent threads, if the worker mechanisms are insufficient for a particular task.
|
||||
|
||||
|
||||
<a name="shared"></a>
|
||||
## Raw shared memory
|
||||
|
||||
|
||||
+6
-6
@@ -188,7 +188,7 @@ i.e. the value located in memory rather than simple immutable self-contained
|
||||
value. Think C++ references, as similar concept.
|
||||
For structs (and `typedef`s to structs) this representation is the main one
|
||||
and has the same name as the struct itself, for Kotlin enums it is named
|
||||
`${type}.Var`, for `CPointer<T>` it is `CPointerVar<T>`, and for most other
|
||||
`${type}Var`, for `CPointer<T>` it is `CPointerVar<T>`, and for most other
|
||||
types it is `${type}Var`.
|
||||
|
||||
For those types that have both representations, the "lvalue" one has mutable
|
||||
@@ -343,7 +343,7 @@ In all cases the C string is supposed to be encoded as UTF-8.
|
||||
### Scope-local pointers ###
|
||||
|
||||
It is possible to create scope-stable pointer of C representation of `CValues<T>`
|
||||
instance using `CValues<T>.ptr` extension property available under memScoped { ... }.
|
||||
instance using `CValues<T>.ptr` extension property available under `memScoped { ... }`.
|
||||
It allows to use APIs which requires C pointers with lifetime bound to certain `MemScope`. For example:
|
||||
```
|
||||
memScoped {
|
||||
@@ -400,11 +400,11 @@ provided by user when configuring the callback. It is passed to some C function
|
||||
However references to Kotlin objects can't be directly passed to C.
|
||||
So they require wrapping before configuring callback and then unwrapping in
|
||||
the callback itself, to safely swim from Kotlin to Kotlin through the C world.
|
||||
Such wrapping is possible with `StableObjPtr` class.
|
||||
Such wrapping is possible with `StableRef` class.
|
||||
|
||||
To wrap the reference:
|
||||
```
|
||||
val stablePtr = StableObjPtr.create(kotlinReference)
|
||||
val stablePtr = StableRef.create(kotlinReference)
|
||||
val voidPtr = stablePtr.value
|
||||
```
|
||||
where the `voidPtr` is `COpaquePointer` and can be passed to the C function.
|
||||
@@ -412,13 +412,13 @@ where the `voidPtr` is `COpaquePointer` and can be passed to the C function.
|
||||
To unwrap the reference:
|
||||
|
||||
```
|
||||
val stablePtr = StableObjPtr.fromValue(voidPtr)
|
||||
val stablePtr = StableRef.fromValue(voidPtr)
|
||||
val kotlinReference = stablePtr.get()
|
||||
```
|
||||
where `kotlinReference` is the original wrapped reference (however it's type is
|
||||
`Any` so it may require casting).
|
||||
|
||||
The created `StableObjPtr` should eventually be manually disposed using
|
||||
The created `StableRef` should eventually be manually disposed using
|
||||
`.dispose()` method to prevent memory leaks:
|
||||
|
||||
```
|
||||
|
||||
@@ -49,6 +49,11 @@ inline fun <reified T : NativePointed> interpretNullablePointed(ptr: NativePtr):
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a [CPointer] from the raw pointer of [NativePtr].
|
||||
*
|
||||
* @return a [CPointer] representation, or `null` if the [rawValue] represents native `nullptr`.
|
||||
*/
|
||||
fun <T : CPointed> interpretCPointer(rawValue: NativePtr) =
|
||||
if (rawValue == nativeNullPtr) {
|
||||
null
|
||||
|
||||
@@ -33,12 +33,15 @@ inline val nativeNullPtr: NativePtr
|
||||
fun <T : CVariable> typeOf(): CVariable.Type = throw Error("typeOf() is called with erased argument")
|
||||
|
||||
/**
|
||||
* Returns interpretation of entity with given pointer, or `null` if it is null.
|
||||
* Performs type cast of the native pointer to given interop type, including null values.
|
||||
*
|
||||
* @param T must not be abstract
|
||||
*/
|
||||
@Intrinsic external fun <T : NativePointed> interpretNullablePointed(ptr: NativePtr): T?
|
||||
|
||||
/**
|
||||
* Performs type cast of the [CPointer] from the given raw pointer.
|
||||
*/
|
||||
@Intrinsic external fun <T : CPointed> interpretCPointer(rawValue: NativePtr): CPointer<T>?
|
||||
|
||||
@Intrinsic external fun NativePointed.getRawPointer(): NativePtr
|
||||
@@ -47,6 +50,12 @@ fun <T : CVariable> typeOf(): CVariable.Type = throw Error("typeOf() is called w
|
||||
|
||||
internal fun CPointer<*>.cPointerToString() = "CPointer(raw=$rawValue)"
|
||||
|
||||
/**
|
||||
* Returns a pointer to C function which calls given Kotlin *static* function.
|
||||
*
|
||||
* @param function must be *static*, i.e. an (unbound) reference to a Kotlin function or
|
||||
* a closure which doesn't capture any variable
|
||||
*/
|
||||
@Intrinsic external fun <R> staticCFunction(@VolatileLambda function: () -> R): CPointer<CFunction<() -> R>>
|
||||
|
||||
@Intrinsic external fun <P1, R> staticCFunction(@VolatileLambda function: (P1) -> R): CPointer<CFunction<(P1) -> R>>
|
||||
|
||||
@@ -10,9 +10,19 @@ import kotlin.native.internal.ExportTypeInfo
|
||||
import kotlin.native.internal.InlineConstructor
|
||||
import kotlin.native.internal.PointsTo
|
||||
|
||||
/**
|
||||
* Represents an array. Array instances can be created using the constructor, [arrayOf], [arrayOfNulls] and [emptyArray]
|
||||
* standard library functions.
|
||||
* See [Kotlin language documentation](http://kotlinlang.org/docs/reference/basic-types.html#arrays)
|
||||
* for more information on arrays.
|
||||
*/
|
||||
@ExportTypeInfo("theArrayTypeInfo")
|
||||
public final class Array<T> {
|
||||
|
||||
/**
|
||||
* Creates a new array with the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function. The [init] function returns an array element given its index.
|
||||
*/
|
||||
@InlineConstructor
|
||||
@Suppress("TYPE_PARAMETER_AS_REIFIED")
|
||||
public constructor(size: Int, init: (Int) -> T): this(size) {
|
||||
@@ -26,17 +36,37 @@ public final class Array<T> {
|
||||
@ExportForCompiler
|
||||
internal constructor(@Suppress("UNUSED_PARAMETER") size: Int) {}
|
||||
|
||||
/**
|
||||
* Returns the number of elements in the array.
|
||||
*/
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
/**
|
||||
* Returns the array element at the specified [index]. This method can be called using the
|
||||
* index operator:
|
||||
* ```
|
||||
* value = arr[index]
|
||||
* ```
|
||||
*/
|
||||
@SymbolName("Kotlin_Array_get")
|
||||
@PointsTo(0b0100, 0, 0b0001) // <this> points to <return>, <return> points to <this>.
|
||||
external public operator fun get(index: Int): T
|
||||
|
||||
/**
|
||||
* Sets the array element at the specified [index] to the specified [value]. This method can
|
||||
* be called using the index operator:
|
||||
* ```
|
||||
* arr[index] = value
|
||||
* ```
|
||||
*/
|
||||
@SymbolName("Kotlin_Array_set")
|
||||
@PointsTo(0b0100, 0, 0b0001) // <this> points to <value>, <value> points to <this>.
|
||||
external public operator fun set(index: Int, value: T): Unit
|
||||
|
||||
/**
|
||||
* Creates an [Iterator] for iterating over the elements of the array.
|
||||
*/
|
||||
public operator fun iterator(): kotlin.collections.Iterator<T> {
|
||||
return IteratorImpl(this)
|
||||
}
|
||||
@@ -58,7 +88,9 @@ private class IteratorImpl<T>(val collection: Array<T>) : Iterator<T> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array containing all elements of the original array and then all elements of the given [elements] array.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <T> Array<T>.plus(elements: Array<T>): Array<T> {
|
||||
val result = copyOfUninitializedElements(this.size + elements.size)
|
||||
|
||||
@@ -87,6 +87,7 @@ public final class CharArray {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
@@ -138,6 +139,7 @@ public final class ShortArray {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
@@ -189,6 +191,7 @@ public final class IntArray {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
@@ -240,6 +243,7 @@ public final class LongArray {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
@@ -291,6 +295,7 @@ public final class FloatArray {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
@@ -338,6 +343,7 @@ public final class DoubleArray {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
@@ -385,6 +391,7 @@ public final class BooleanArray {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
public val size: Int
|
||||
get() = getArrayLength()
|
||||
|
||||
|
||||
@@ -17,14 +17,6 @@ public abstract class Enum<E: Enum<E>>(public val name: String, public val ordin
|
||||
|
||||
public override final fun compareTo(other: E): Int { return ordinal - other.ordinal }
|
||||
|
||||
/**
|
||||
* Throws an exception since enum constants cannot be cloned.
|
||||
* This method prevents enum classes from inheriting from [Cloneable].
|
||||
*/
|
||||
protected final fun clone(): Any {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
public override final fun equals(other: Any?): Boolean {
|
||||
return this === other
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ package kotlin
|
||||
|
||||
import kotlin.native.internal.ExportTypeInfo
|
||||
|
||||
/**
|
||||
* The type with only one value: the `Unit` object.
|
||||
*/
|
||||
@ExportTypeInfo("theUnitTypeInfo")
|
||||
public object Unit {
|
||||
override fun toString() = "kotlin.Unit"
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
|
||||
package kotlin.collections
|
||||
|
||||
/**
|
||||
* Provides a skeletal implementation of the [MutableCollection] interface.
|
||||
*
|
||||
* @param E the type of elements contained in the collection. The collection is invariant on its element type.
|
||||
*/
|
||||
public abstract class AbstractMutableCollection<E> protected constructor(): MutableCollection<E>, AbstractCollection<E>() {
|
||||
|
||||
// Bulk Modification Operations
|
||||
|
||||
@@ -9,7 +9,7 @@ import kotlin.comparisons.*
|
||||
import kotlin.internal.InlineOnly
|
||||
import kotlin.random.*
|
||||
|
||||
// Copies typed varargs array to an array of objects
|
||||
/** Copies typed varargs array to an array of objects */
|
||||
internal actual fun <T> Array<out T>.copyToArrayOfAny(isVarargs: Boolean): Array<out Any?> =
|
||||
if (isVarargs)
|
||||
// if the array came from varargs and already is array of Any, copying isn't required.
|
||||
|
||||
@@ -5,5 +5,7 @@
|
||||
|
||||
package kotlin.collections
|
||||
|
||||
// A marker interface indicating the fast indexed access support
|
||||
/**
|
||||
* Marker interface indicating that the [List] implementation supports fast indexed access.
|
||||
*/
|
||||
public actual interface RandomAccess
|
||||
|
||||
@@ -5,95 +5,32 @@
|
||||
|
||||
package kotlin.io
|
||||
|
||||
/** Prints the given [message] to the standard output stream. */
|
||||
@SymbolName("Kotlin_io_Console_print")
|
||||
external public fun print(message: String)
|
||||
|
||||
/* TODO: use something like that.
|
||||
public fun<T> print(message: T) {
|
||||
print(message.toString())
|
||||
} */
|
||||
|
||||
/** Prints the given [message] to the standard output stream. */
|
||||
public actual fun print(message: Any?) {
|
||||
print(message.toString())
|
||||
}
|
||||
|
||||
public fun print(message: Byte) {
|
||||
print(message.toString())
|
||||
}
|
||||
|
||||
public fun print(message: Short) {
|
||||
print(message.toString())
|
||||
}
|
||||
|
||||
public fun print(message: Char) {
|
||||
print(message.toString())
|
||||
}
|
||||
|
||||
public fun print(message: Int) {
|
||||
print(message.toString())
|
||||
}
|
||||
|
||||
public fun print(message: Long) {
|
||||
print(message.toString())
|
||||
}
|
||||
|
||||
public fun print(message: Float) {
|
||||
print(message.toString())
|
||||
}
|
||||
|
||||
public fun print(message: Double) {
|
||||
print(message.toString())
|
||||
}
|
||||
|
||||
public fun print(message: Boolean) {
|
||||
print(message.toString())
|
||||
}
|
||||
|
||||
/** Prints the given [message] and newline to the standard output stream. */
|
||||
@SymbolName("Kotlin_io_Console_println")
|
||||
external public fun println(message: String)
|
||||
|
||||
/** Prints the given [message] and newline to the standard output stream. */
|
||||
public actual fun println(message: Any?) {
|
||||
println(message.toString())
|
||||
}
|
||||
|
||||
public fun println(message: Byte) {
|
||||
println(message.toString())
|
||||
}
|
||||
|
||||
public fun println(message: Short) {
|
||||
println(message.toString())
|
||||
}
|
||||
|
||||
public fun println(message: Char) {
|
||||
println(message.toString())
|
||||
}
|
||||
|
||||
public fun println(message: Int) {
|
||||
println(message.toString())
|
||||
}
|
||||
|
||||
public fun println(message: Long) {
|
||||
println(message.toString())
|
||||
}
|
||||
|
||||
public fun println(message: Float) {
|
||||
println(message.toString())
|
||||
}
|
||||
|
||||
public fun println(message: Double) {
|
||||
println(message.toString())
|
||||
}
|
||||
|
||||
public fun println(message: Boolean) {
|
||||
println(message.toString())
|
||||
}
|
||||
/* TODO: use something like that.
|
||||
public fun<T> println(message: T) {
|
||||
print(message.toString())
|
||||
} */
|
||||
|
||||
/** Prints newline to the standard output stream. */
|
||||
@SymbolName("Kotlin_io_Console_println0")
|
||||
external public actual fun println()
|
||||
|
||||
/**
|
||||
* Reads a line of input from the standard input stream.
|
||||
*
|
||||
* @return the line read or `null` if the input is empty.
|
||||
*/
|
||||
@SymbolName("Kotlin_io_Console_readLine")
|
||||
external public fun readLine(): String?
|
||||
|
||||
@@ -60,8 +60,9 @@ public annotation class SharedImmutable
|
||||
|
||||
/**
|
||||
* Makes top level function available from C/C++ code with the given name.
|
||||
* `externName` controls the name of top level function, `shortName` controls the short name.
|
||||
* If `externName` is empty, no top level declaration is being created.
|
||||
*
|
||||
* [externName] controls the name of top level function, [shortName] controls the short name.
|
||||
* If [externName] is empty, no top level declaration is being created.
|
||||
*/
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
|
||||
@@ -7,11 +7,14 @@ package kotlin.native
|
||||
|
||||
/**
|
||||
* A vector of bits growing if necessary and allowing one to set/clear/read bits from it by a bit index.
|
||||
*
|
||||
* @constructor creates an empty bit set with the specified [size]
|
||||
* @param seze the size of one element in the array used to store bits.
|
||||
*/
|
||||
public class BitSet(size: Int = ELEMENT_SIZE) {
|
||||
|
||||
companion object {
|
||||
// Size of one element in the array used to store bits.
|
||||
// Default size of one element in the array used to store bits.
|
||||
private const val ELEMENT_SIZE = 64
|
||||
private const val MAX_BIT_OFFSET = ELEMENT_SIZE - 1
|
||||
private const val ALL_TRUE = -1L // 0xFFFF_FFFF_FFFF_FFFF
|
||||
@@ -35,8 +38,9 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
|
||||
var size: Int = size
|
||||
private set
|
||||
|
||||
// TODO: Add more constructors.
|
||||
|
||||
/**
|
||||
* Creates a bit set of given [length] filling elements using [initializer]
|
||||
*/
|
||||
constructor(length: Int, initializer: (Int) -> Boolean): this(length) {
|
||||
for (i in 0 until length) {
|
||||
set(i, initializer(i))
|
||||
@@ -111,7 +115,7 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
|
||||
|
||||
/**
|
||||
* Checks if index is valid and extends the `bits` array if the index exceeds its size.
|
||||
* Throws [IndexOutOfBoundsException] if [index] < 0.
|
||||
* @throws [IndexOutOfBoundsException] if [index] < 0.
|
||||
*/
|
||||
private fun ensureCapacity(index: Int) {
|
||||
if (index < 0) {
|
||||
@@ -220,7 +224,7 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
|
||||
* (if [lookFor] == false) bit after [startIndex] (inclusive).
|
||||
* Returns -1 (for [lookFor] == true) or [size] (for lookFor == false)
|
||||
* if there is no such bits between [startIndex] and [size] - 1.
|
||||
* Throws IndexOutOfBoundException if [startIndex] < 0.
|
||||
* @throws IndexOutOfBoundException if [startIndex] < 0.
|
||||
*/
|
||||
private fun nextBit(startIndex: Int, lookFor: Boolean): Int {
|
||||
if (startIndex < 0) {
|
||||
@@ -254,7 +258,7 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
|
||||
/**
|
||||
* Returns an index of a next bit which value is `true` after [startIndex] (inclusive).
|
||||
* Returns -1 if there is no such bits after [startIndex].
|
||||
* Throws IndexOutOfBoundException if [startIndex] < 0.
|
||||
* @throws IndexOutOfBoundException if [startIndex] < 0.
|
||||
*/
|
||||
fun nextSetBit(startIndex: Int = 0): Int = nextBit(startIndex, true)
|
||||
|
||||
@@ -262,7 +266,7 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
|
||||
* Returns an index of a next bit which value is `false` after [startIndex] (inclusive).
|
||||
* Returns [size] if there is no such bits between [startIndex] and [size] - 1 assuming that the set has an infinite
|
||||
* sequence of `false` bits after (size - 1)-th.
|
||||
* Throws IndexOutOfBoundException if [startIndex] < 0.
|
||||
* @throws IndexOutOfBoundException if [startIndex] < 0.
|
||||
*/
|
||||
fun nextClearBit(startIndex: Int = 0): Int = nextBit(startIndex, false)
|
||||
|
||||
@@ -315,7 +319,7 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
|
||||
* Returns the biggest index of a bit which value is `true` before [startIndex] (inclusive).
|
||||
* Returns -1 if there is no such bits before [startIndex] or if [startIndex] == -1.
|
||||
* If [startIndex] >= size will search from (size - 1)-th bit.
|
||||
* Throws IndexOutOfBoundException if [startIndex] < -1.
|
||||
* @throws IndexOutOfBoundException if [startIndex] < -1.
|
||||
*/
|
||||
fun previousSetBit(startIndex: Int): Int = previousBit(startIndex, true)
|
||||
|
||||
@@ -324,7 +328,7 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
|
||||
* Returns -1 if there is no such bits before [startIndex] or if [startIndex] == -1.
|
||||
* If [startIndex] >= size will return [startIndex] assuming that the set has an infinite
|
||||
* sequence of `false` bits after (size - 1)-th.
|
||||
* Throws IndexOutOfBoundException if [startIndex] < -1.
|
||||
* @throws IndexOutOfBoundException if [startIndex] < -1.
|
||||
*/
|
||||
fun previousClearBit(startIndex: Int): Int = previousBit(startIndex, false)
|
||||
|
||||
|
||||
@@ -42,26 +42,30 @@ private class ImmutableBlobIteratorImpl(val blob: ImmutableBlob) : ByteIterator(
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates new ByteArray or UByteArray and copies the data from blob.
|
||||
* Allocates new [ByteArray] and copies the data from blob starting from [start]
|
||||
* and with [count] amount of bytes.
|
||||
*/
|
||||
@SymbolName("Kotlin_ImmutableBlob_toByteArray")
|
||||
public external fun ImmutableBlob.toByteArray(start: Int = 0, count: Int = size): ByteArray
|
||||
|
||||
/**
|
||||
* Allocates new [UByteArray] and copies the data from blob starting from [start]
|
||||
* and with [count] amount of bytes.
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
@SymbolName("Kotlin_ImmutableBlob_toByteArray")
|
||||
public external fun ImmutableBlob.toUByteArray(start: Int = 0, count: Int = size): UByteArray
|
||||
|
||||
/**
|
||||
* Returns stable C pointer to data at certain offset, useful as a way to pass resource
|
||||
* Returns stable C pointer to data at certain [offset], useful as a way to pass resource
|
||||
* to C APIs.
|
||||
* @see kotlinx.cinterop.CPointer
|
||||
*/
|
||||
public fun ImmutableBlob.asCPointer(offset: Int = 0): CPointer<ByteVar> =
|
||||
interpretCPointer<ByteVar>(asCPointerImpl(offset))!!
|
||||
|
||||
/*
|
||||
public fun ImmutableBlob.asUCPointer(offset: Int = 0): CPointer<UByteVar> =
|
||||
interpretCPointer<UByteVar>(asCPointerImpl(offset))!!
|
||||
*/
|
||||
|
||||
@SymbolName("Kotlin_ImmutableBlob_asCPointerImpl")
|
||||
private external fun ImmutableBlob.asCPointerImpl(offset: Int): kotlin.native.internal.NativePtr
|
||||
|
||||
@@ -17,6 +17,10 @@ public annotation class Volatile
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
public annotation class Synchronized
|
||||
|
||||
/**
|
||||
* An actual implementation of `synchronized` method. This method is not supported in Kotlin/Native
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public actual inline fun <R> synchronized(@Suppress("UNUSED_PARAMETER") lock: Any, block: () -> R): R =
|
||||
throw UnsupportedOperationException("synchronized() is unsupported")
|
||||
@@ -11,7 +11,7 @@ package kotlin.native
|
||||
external public fun initRuntimeIfNeeded(): Unit
|
||||
|
||||
/**
|
||||
* Deiitializes Kotlin runtime for the current thread, if was inited.
|
||||
* Deinitializes Kotlin runtime for the current thread, if was inited.
|
||||
*/
|
||||
@SymbolName("Kotlin_deinitRuntimeIfNeeded")
|
||||
external public fun deinitRuntimeIfNeeded(): Unit
|
||||
|
||||
@@ -15,7 +15,8 @@ public fun ByteArray.stringFromUtf8(start: Int = 0, size: Int = this.size) : Str
|
||||
private external fun ByteArray.stringFromUtf8Impl(start: Int, size: Int) : String
|
||||
|
||||
/**
|
||||
* Converts an UTF-8 array into a [String]. Throws [IllegalCharacterConversionException] if the input is invalid.
|
||||
* Converts an UTF-8 array into a [String].
|
||||
* @throws [IllegalCharacterConversionException] if the input is invalid.
|
||||
*/
|
||||
public fun ByteArray.stringFromUtf8OrThrow(start: Int = 0, size: Int = this.size) : String =
|
||||
stringFromUtf8OrThrowImpl(start, size)
|
||||
@@ -33,7 +34,8 @@ public fun String.toUtf8(start: Int = 0, size: Int = this.length) : ByteArray =
|
||||
private external fun String.toUtf8Impl(start: Int, size: Int) : ByteArray
|
||||
|
||||
/**
|
||||
* Converts a [String] into an UTF-8 array. Throws [IllegalCharacterConversionException] if the input is invalid.
|
||||
* Converts a [String] into an UTF-8 array.
|
||||
* @throws [IllegalCharacterConversionException] if the input is invalid.
|
||||
*/
|
||||
public fun String.toUtf8OrThrow(start: Int = 0, size: Int = this.length) : ByteArray =
|
||||
toUtf8OrThrowImpl(start, size)
|
||||
|
||||
@@ -7,68 +7,152 @@ package kotlin.native
|
||||
import kotlin.native.SymbolName
|
||||
|
||||
/**
|
||||
* Those operations allows to extract primitive values out of the byte buffers.
|
||||
* Those operations allows to extract primitive values out of the [ByteArray] byte buffers.
|
||||
* Data is treated as if it was in Least-Significant-Byte first (little-endian) byte order.
|
||||
* If index is outside of array boundaries - ArrayIndexOutOfBoundsException is thrown.
|
||||
* If index is outside of array boundaries - [ArrayIndexOutOfBoundsException] is thrown.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets [UByte] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun ByteArray.ubyteAt(index: Int): UByte = UByte(get(index))
|
||||
|
||||
/**
|
||||
* Gets [Char] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_getCharAt")
|
||||
public external fun ByteArray.charAt(index: Int): Char
|
||||
|
||||
/**
|
||||
* Gets [Short] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_getShortAt")
|
||||
public external fun ByteArray.shortAt(index: Int): Short
|
||||
|
||||
/**
|
||||
* Gets [UShort] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_getShortAt")
|
||||
@ExperimentalUnsignedTypes
|
||||
public external fun ByteArray.ushortAt(index: Int): UShort
|
||||
|
||||
/**
|
||||
* Gets [Int] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_getIntAt")
|
||||
public external fun ByteArray.intAt(index: Int): Int
|
||||
|
||||
/**
|
||||
* Gets [UInt] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_getIntAt")
|
||||
@ExperimentalUnsignedTypes
|
||||
public external fun ByteArray.uintAt(index: Int): UInt
|
||||
|
||||
/**
|
||||
* Gets [Long] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_getLongAt")
|
||||
public external fun ByteArray.longAt(index: Int): Long
|
||||
|
||||
/**
|
||||
* Gets [ULong] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_getLongAt")
|
||||
@ExperimentalUnsignedTypes
|
||||
public external fun ByteArray.ulongAt(index: Int): ULong
|
||||
|
||||
/**
|
||||
* Gets [Float] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_getFloatAt")
|
||||
public external fun ByteArray.floatAt(index: Int): Float
|
||||
|
||||
/**
|
||||
* Gets [Double] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_getDoubleAt")
|
||||
public external fun ByteArray.doubleAt(index: Int): Double
|
||||
|
||||
/**
|
||||
* Sets [UByte] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_set")
|
||||
public external fun ByteArray.setUByteAt(index: Int, value: UByte)
|
||||
|
||||
/**
|
||||
* Sets [Char] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_setCharAt")
|
||||
public external fun ByteArray.setCharAt(index: Int, value: Char)
|
||||
|
||||
/**
|
||||
* Sets [Short] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_setShortAt")
|
||||
public external fun ByteArray.setShortAt(index: Int, value: Short)
|
||||
|
||||
/**
|
||||
* Sets [UShort] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_setShortAt")
|
||||
@ExperimentalUnsignedTypes
|
||||
public external fun ByteArray.setUShortAt(index: Int, value: UShort)
|
||||
|
||||
/**
|
||||
* Sets [Int] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_setIntAt")
|
||||
public external fun ByteArray.setIntAt(index: Int, value: Int)
|
||||
|
||||
/**
|
||||
* Sets [UInt] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_setIntAt")
|
||||
public external fun ByteArray.setUIntAt(index: Int, value: UInt)
|
||||
|
||||
/**
|
||||
* Sets [Long] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_setLongAt")
|
||||
public external fun ByteArray.setLongAt(index: Int, value: Long)
|
||||
|
||||
/**
|
||||
* Sets [ULong] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_setLongAt")
|
||||
@ExperimentalUnsignedTypes
|
||||
public external fun ByteArray.setULongAt(index: Int, value: ULong)
|
||||
|
||||
/**
|
||||
* Sets [Float] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_setFloatAt")
|
||||
public external fun ByteArray.setFloatAt(index: Int, value: Float)
|
||||
|
||||
/**
|
||||
* Sets [Double] out of the [ByteArray] byte buffer at specified index [index]
|
||||
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
|
||||
*/
|
||||
@SymbolName("Kotlin_ByteArray_setDoubleAt")
|
||||
public external fun ByteArray.setDoubleAt(index: Int, value: Double)
|
||||
|
||||
@@ -17,27 +17,38 @@ import kotlinx.cinterop.NativePtr
|
||||
*/
|
||||
@Frozen
|
||||
public class AtomicInt(private var value_: Int) {
|
||||
|
||||
/**
|
||||
* The value being held by this class.
|
||||
*/
|
||||
public var value: Int
|
||||
get() = getImpl()
|
||||
set(new) = setImpl(new)
|
||||
|
||||
/**
|
||||
* Increments the value by [delta] and returns the new value.
|
||||
*
|
||||
* @param delta the value to add
|
||||
* @return the new value
|
||||
*/
|
||||
@SymbolName("Kotlin_AtomicInt_addAndGet")
|
||||
external public fun addAndGet(delta: Int): Int
|
||||
|
||||
/**
|
||||
* Compares value with [expected] and replaces it with [new] value if values matches.
|
||||
* Returns the old value.
|
||||
*
|
||||
* @param expected the expected value
|
||||
* @param new the new value
|
||||
* @return the old value
|
||||
*/
|
||||
@SymbolName("Kotlin_AtomicInt_compareAndSwap")
|
||||
external public fun compareAndSwap(expected: Int, new: Int): Int
|
||||
|
||||
/**
|
||||
* Compares value with [expected] and replaces it with [new] value if values matches.
|
||||
* Returns true if successful.
|
||||
*
|
||||
* @param expected the expected value
|
||||
* @param new the new value
|
||||
* @return true if successful
|
||||
*/
|
||||
@SymbolName("Kotlin_AtomicInt_compareAndSet")
|
||||
external public fun compareAndSet(expected: Int, new: Int): Boolean
|
||||
@@ -58,6 +69,8 @@ public class AtomicInt(private var value_: Int) {
|
||||
|
||||
/**
|
||||
* Returns the string representation of this object.
|
||||
*
|
||||
* @return the string representation
|
||||
*/
|
||||
public override fun toString(): String = value.toString()
|
||||
|
||||
@@ -71,32 +84,46 @@ public class AtomicInt(private var value_: Int) {
|
||||
|
||||
@Frozen
|
||||
public class AtomicLong(private var value_: Long = 0) {
|
||||
|
||||
/**
|
||||
* The value being held by this class.
|
||||
*/
|
||||
public var value: Long
|
||||
get() = getImpl()
|
||||
set(new) = setImpl(new)
|
||||
|
||||
/**
|
||||
* Increments the value by [delta] and returns the new value.
|
||||
*
|
||||
* @param delta the value to add
|
||||
* @return the new value
|
||||
*/
|
||||
@SymbolName("Kotlin_AtomicLong_addAndGet")
|
||||
external public fun addAndGet(delta: Long): Long
|
||||
|
||||
/**
|
||||
* Increments the value by [delta] and returns the new value.
|
||||
*
|
||||
* @param delta the value to add
|
||||
* @return the new value
|
||||
*/
|
||||
public fun addAndGet(delta: Int): Long = addAndGet(delta.toLong())
|
||||
|
||||
/**
|
||||
* Compares value with [expected] and replaces it with [new] value if values matches.
|
||||
* Returns the old value.
|
||||
*
|
||||
* @param expected the expected value
|
||||
* @param new the new value
|
||||
* @return the old value
|
||||
*/
|
||||
@SymbolName("Kotlin_AtomicLong_compareAndSwap")
|
||||
external public fun compareAndSwap(expected: Long, new: Long): Long
|
||||
|
||||
/**
|
||||
* Compares value with [expected] and replaces it with [new] value if values matches.
|
||||
* Returns true if successful.
|
||||
*
|
||||
* @param expected the expected value
|
||||
* @param new the new value
|
||||
* @return true if successful, false if state is unchanged
|
||||
*/
|
||||
@SymbolName("Kotlin_AtomicLong_compareAndSet")
|
||||
external public fun compareAndSet(expected: Long, new: Long): Boolean
|
||||
@@ -117,6 +144,8 @@ public class AtomicLong(private var value_: Long = 0) {
|
||||
|
||||
/**
|
||||
* Returns the string representation of this object.
|
||||
*
|
||||
* @return the string representation of this object
|
||||
*/
|
||||
public override fun toString(): String = value.toString()
|
||||
|
||||
@@ -130,26 +159,39 @@ public class AtomicLong(private var value_: Long = 0) {
|
||||
|
||||
@Frozen
|
||||
public class AtomicNativePtr(private var value_: NativePtr) {
|
||||
|
||||
/**
|
||||
* The value being held by this class.
|
||||
*/
|
||||
public var value: NativePtr
|
||||
get() = getImpl()
|
||||
set(new) = setImpl(new)
|
||||
|
||||
/**
|
||||
* Compares value with [expected] and replaces it with [new] value if values matches.
|
||||
* Returns the old value.
|
||||
* If [new] value is not null, it must be frozen or permanent object.
|
||||
*
|
||||
* @param expected the expected value
|
||||
* @param new the new value
|
||||
* @throws InvalidMutabilityException if [new] is not frozen or a permanent object
|
||||
* @return the old value
|
||||
*/
|
||||
@SymbolName("Kotlin_AtomicNativePtr_compareAndSwap")
|
||||
external public fun compareAndSwap(expected: NativePtr, new: NativePtr): NativePtr
|
||||
|
||||
/**
|
||||
* Compares value with [expected] and replaces it with [new] value if values matches.
|
||||
*
|
||||
* @param expected the expected value
|
||||
* @param new the new value
|
||||
* @return true if successful
|
||||
*/
|
||||
@SymbolName("Kotlin_AtomicNativePtr_compareAndSet")
|
||||
external public fun compareAndSet(expected: NativePtr, new: NativePtr): Boolean
|
||||
|
||||
/**
|
||||
* Returns the string representation of this object.
|
||||
*
|
||||
* @return string representation of this object
|
||||
*/
|
||||
public override fun toString(): String = value.toString()
|
||||
|
||||
@@ -173,17 +215,19 @@ public class AtomicReference<T>(private var value_: T) {
|
||||
private var lock: Int = 0
|
||||
|
||||
/**
|
||||
* Creates a new atomic reference pointing to given [ref]. If reference is not frozen,
|
||||
* @InvalidMutabilityException is thrown.
|
||||
* Creates a new atomic reference pointing to given [ref].
|
||||
* @throws InvalidMutabilityException if reference is not frozen.
|
||||
*/
|
||||
init {
|
||||
checkIfFrozen(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value to [new] value
|
||||
* If [new] value is not null, it must be frozen or permanent object, otherwise an
|
||||
* @InvalidMutabilityException is thrown.
|
||||
* The referenced value.
|
||||
* Gets the value or sets the [new] value. If [new] value is not null,
|
||||
* it must be frozen or permanent object.
|
||||
*
|
||||
* @throws InvalidMutabilityException if the value is not frozen or a permanent object
|
||||
*/
|
||||
public var value: T
|
||||
get() = @Suppress("UNCHECKED_CAST")(getImpl() as T)
|
||||
@@ -191,18 +235,30 @@ public class AtomicReference<T>(private var value_: T) {
|
||||
|
||||
/**
|
||||
* Compares value with [expected] and replaces it with [new] value if values matches.
|
||||
* If [new] value is not null, it must be frozen or permanent object, otherwise an
|
||||
* @InvalidMutabilityException is thrown.
|
||||
* Returns the old value.
|
||||
* If [new] value is not null, it must be frozen or permanent object.
|
||||
*
|
||||
* @param expected the expected value
|
||||
* @param new the new value
|
||||
* @throws InvalidMutabilityException if the value is not frozen or a permanent object
|
||||
* @return the old value
|
||||
*/
|
||||
@SymbolName("Kotlin_AtomicReference_compareAndSwap")
|
||||
external public fun compareAndSwap(expected: T, new: T): T
|
||||
|
||||
/**
|
||||
* Compares value with [expected] and replaces it with [new] value if values matches.
|
||||
*
|
||||
* @param expected the expected value
|
||||
* @param new the new value
|
||||
* @return true if successful
|
||||
*/
|
||||
@SymbolName("Kotlin_AtomicReference_compareAndSet")
|
||||
external public fun compareAndSet(expected: T, new: T): Boolean
|
||||
|
||||
/**
|
||||
* Returns the string representation of this object.
|
||||
*
|
||||
* @return string representation of this object
|
||||
*/
|
||||
public override fun toString(): String = "Atomic reference to $value"
|
||||
|
||||
|
||||
@@ -7,13 +7,17 @@ package kotlin.native.concurrent
|
||||
|
||||
/**
|
||||
* Exception thrown whenever freezing is not possible.
|
||||
* [blocker] is an object preventing freezing, usually one marked with [ensureNeverFrozen] earlier.
|
||||
*
|
||||
* @param toFreeze an object intended to be frozen.
|
||||
* @param blocker an object preventing freezing, usually one marked with [ensureNeverFrozen] earlier.
|
||||
*/
|
||||
public class FreezingException(toFreeze: Any, blocker: Any) :
|
||||
RuntimeException("freezing of $toFreeze has failed, first blocker is $blocker")
|
||||
|
||||
/**
|
||||
* Exception thrown whenever we attempt to mutate frozen objects.
|
||||
*
|
||||
* @param where a frozen object that was attempted to mutate
|
||||
*/
|
||||
public class InvalidMutabilityException(where: Any) :
|
||||
RuntimeException("mutation attempt of frozen $where (hash is 0x${where.hashCode().toString(16)})")
|
||||
@@ -21,6 +25,10 @@ public class InvalidMutabilityException(where: Any) :
|
||||
/**
|
||||
* Freezes object subgraph reachable from this object. Frozen objects can be freely
|
||||
* shared between threads/workers.
|
||||
*
|
||||
* @throws FreezingException if freezing is not possible
|
||||
* @return the object itself
|
||||
* @see ensureNeverFrozen
|
||||
*/
|
||||
public fun <T> T.freeze(): T {
|
||||
freezeInternal(this)
|
||||
@@ -29,13 +37,18 @@ public fun <T> T.freeze(): T {
|
||||
|
||||
/**
|
||||
* Checks if given object is null or frozen or permanent (i.e. instantiated at compile-time).
|
||||
*
|
||||
* @return true if given object is null or frozen or permanent
|
||||
*/
|
||||
public val Any?.isFrozen
|
||||
get() = isFrozenInternal(this)
|
||||
|
||||
/**
|
||||
* This function ensures that if we see such an object during freezing attempt - freeze fails and
|
||||
* [FreezingException] is thrown. Is object is already frozen - [FreezingException] is thrown immediately.
|
||||
* [FreezingException] is thrown.
|
||||
*
|
||||
* @throws FreezingException thrown immediately if this object is already frozen
|
||||
* @see freeze
|
||||
*/
|
||||
@SymbolName("Kotlin_Worker_ensureNeverFrozen")
|
||||
public external fun Any.ensureNeverFrozen()
|
||||
@@ -12,11 +12,11 @@ import kotlin.native.internal.Frozen
|
||||
*/
|
||||
enum class FutureState(val value: Int) {
|
||||
INVALID(0),
|
||||
// Future is scheduled for execution.
|
||||
/** Future is scheduled for execution. */
|
||||
SCHEDULED(1),
|
||||
// Future result is computed.
|
||||
/** Future result is computed. */
|
||||
COMPUTED(2),
|
||||
// Future is cancelled.
|
||||
/** Future is cancelled. */
|
||||
CANCELLED(3)
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@ enum class FutureState(val value: Int) {
|
||||
public class Future<T> internal constructor(val id: Int) {
|
||||
/**
|
||||
* Blocks execution until the future is ready.
|
||||
*
|
||||
* @return the execution result of [code] consumed futures's computaiton
|
||||
* @throws IllegalStateException if current future has [FutureState.INVALID] or [FutureState.CANCELLED] state
|
||||
*/
|
||||
public inline fun <R> consume(code: (T) -> R): R =
|
||||
when (state) {
|
||||
@@ -41,11 +44,15 @@ public class Future<T> internal constructor(val id: Int) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The result of the future computation.
|
||||
* Blocks execution until the future is ready. Second attempt to get will result in an error.
|
||||
*/
|
||||
public val result: T
|
||||
get() = consume { it -> it }
|
||||
|
||||
/**
|
||||
* A [FutureState] of this future
|
||||
*/
|
||||
public val state: FutureState
|
||||
get() = FutureState.values()[stateOfFuture(id)]
|
||||
|
||||
@@ -58,7 +65,9 @@ public class Future<T> internal constructor(val id: Int) {
|
||||
|
||||
/**
|
||||
* Wait for availability of futures in the collection. Returns set with all futures which have
|
||||
* value available for the consumption.
|
||||
* value available for the consumption, i.e. [FutureState.COMPUTED]
|
||||
*
|
||||
* @param millis the amount of time to wait for the computed future
|
||||
*/
|
||||
public fun <T> Collection<Future<T>>.waitForMultipleFutures(millis: Int): Set<Future<T>> {
|
||||
val result = mutableSetOf<Future<T>>()
|
||||
|
||||
@@ -114,7 +114,7 @@ internal class AtomicLazyImpl<out T>(initializer: () -> T) : Lazy<T> {
|
||||
|
||||
/**
|
||||
* Atomic lazy initializer, could be used in frozen objects, freezes initializing lambda,
|
||||
* so use very carefully. Also, as with other uses of an @AtomicReference may potentially
|
||||
* so use very carefully. Also, as with other uses of an [AtomicReference] may potentially
|
||||
* leak memory, so it is recommended to use `atomicLazy` in cases of objects living forever,
|
||||
* such as object signletons, or in cases where it's guaranteed not to have cyclical garbage.
|
||||
*/
|
||||
|
||||
@@ -9,13 +9,13 @@ import kotlinx.cinterop.*
|
||||
import kotlin.native.internal.Frozen
|
||||
|
||||
/**
|
||||
* Object Transfer Basics.
|
||||
* ## Object Transfer Basics.
|
||||
*
|
||||
* Objects can be passed between threads in one of two possible modes.
|
||||
*
|
||||
* - SAFE - object subgraph is checked to be not reachable by other globals or locals, and passed
|
||||
* - [SAFE] - object subgraph is checked to be not reachable by other globals or locals, and passed
|
||||
* if so, otherwise an exception is thrown
|
||||
* - UNSAFE - object is blindly passed to another worker, if there are references
|
||||
* - [UNSAFE] - object is blindly passed to another worker, if there are references
|
||||
* left in the passing worker - it may lead to crash or program malfunction
|
||||
*
|
||||
* Safe mode checks if object is no longer used in passing worker, using memory-management
|
||||
@@ -28,14 +28,26 @@ import kotlin.native.internal.Frozen
|
||||
* ownership without further checks.
|
||||
*
|
||||
* Note, that for some cases cycle collection need to be done to ensure that dead cycles do not affect
|
||||
* reachability of passed object graph. See `[kotlin.native.internal.GC.collect]`.
|
||||
* reachability of passed object graph.
|
||||
*
|
||||
* @see [kotlin.native.internal.GC.collect].
|
||||
*/
|
||||
public enum class TransferMode(val value: Int) {
|
||||
/**
|
||||
* Reachibility check is performed.
|
||||
*/
|
||||
SAFE(0),
|
||||
UNSAFE(1) // USE UNSAFE MODE ONLY IF ABSOLUTELY SURE WHAT YOU'RE DOING!!!
|
||||
/**
|
||||
* Skip reachibility check, can lead to mysterious crashes in an application.
|
||||
* USE UNSAFE MODE ONLY IF ABSOLUTELY SURE WHAT YOU'RE DOING!!!
|
||||
*/
|
||||
UNSAFE(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Detached object graph encapsulates transferrable detached subgraph which cannot be accessed
|
||||
* externally, until it is attached with the [attach] extension function.
|
||||
*/
|
||||
@Frozen
|
||||
public class DetachedObjectGraph<T> internal constructor(pointer: NativePtr) {
|
||||
@PublishedApi
|
||||
@@ -55,14 +67,14 @@ public class DetachedObjectGraph<T> internal constructor(pointer: NativePtr) {
|
||||
public constructor(pointer: COpaquePointer?) : this(pointer?.rawValue ?: NativePtr.NULL)
|
||||
|
||||
/**
|
||||
* Returns raw C pointer value.
|
||||
* Returns raw C pointer value, usable for interoperability with C scenarious.
|
||||
*/
|
||||
public fun asCPointer(): COpaquePointer? = interpretCPointer<COpaque>(stable.value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches previously detached with [detachObjectGraph] object subgraph.
|
||||
* Please note, that once object graph is attached, the stable pointer does not have sense anymore,
|
||||
* Attaches previously detached object subgraph created by [DetachedObjectGraph].
|
||||
* Please note, that once object graph is attached, the [DetachedObjectGraph.stable] pointer does not have sense anymore,
|
||||
* and shall be discarded.
|
||||
*/
|
||||
public inline fun <reified T> DetachedObjectGraph<T>.attach(): T {
|
||||
|
||||
@@ -11,12 +11,12 @@ import kotlin.native.internal.VolatileLambda
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
/**
|
||||
* Workers: theory of operations.
|
||||
* ## Workers: theory of operations.
|
||||
*
|
||||
* Worker represent asynchronous and concurrent computation, usually performed by other threads
|
||||
* [Worker] represents asynchronous and concurrent computation, usually performed by other threads
|
||||
* in the same process. Object passing between workers is performed using transfer operation, so that
|
||||
* object graph belongs to one worker at the time, but can be disconnected and reconnected as needed.
|
||||
* See 'Object Transfer Basics' below for more details on how objects shall be transferred.
|
||||
* See 'Object Transfer Basics' and [TransferMode] for more details on how objects shall be transferred.
|
||||
* This approach ensures that no concurrent access happens to same object, while data may flow between
|
||||
* workers as needed.
|
||||
*/
|
||||
@@ -36,25 +36,29 @@ public class Worker private constructor(val id: Int) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests termination of the worker. `processScheduledJobs` controls is we shall wait
|
||||
* until all scheduled jobs processed, or terminate immediately.
|
||||
* Requests termination of the worker.
|
||||
*
|
||||
* @param processScheduledJobs controls is we shall wait until all scheduled jobs processed,
|
||||
* or terminate immediately.
|
||||
*/
|
||||
public fun requestTermination(processScheduledJobs: Boolean = true) =
|
||||
Future<Unit>(requestTerminationInternal(id, processScheduledJobs))
|
||||
|
||||
/**
|
||||
* Plan job for further execution in the worker. Execute is a two-phase operation,
|
||||
* first `producer` function is executed, and resulting object and whatever it refers to
|
||||
* Plan job for further execution in the worker. Execute is a two-phase operation:
|
||||
* - first [producer] function is executed, and resulting object and whatever it refers to
|
||||
* is analyzed for being an isolated object subgraph, if in checked mode.
|
||||
* Afterwards, this disconnected object graph and `job` function pointer is being added to jobs queue
|
||||
* of the selected worker. Note that `job` must not capture any state itself, so that whole state is
|
||||
* explicitly stored in object produced by `producer`. Scheduled job is being executed by the worker,
|
||||
* - Afterwards, this disconnected object graph and [job] function pointer is being added to jobs queue
|
||||
* of the selected worker. Note that [job] must not capture any state itself, so that whole state is
|
||||
* explicitly stored in object produced by [producer]. Scheduled job is being executed by the worker,
|
||||
* and result of such a execution is being disconnected from worker's object graph. Whoever will consume
|
||||
* the future, can use result of worker's computations.
|
||||
*
|
||||
* @return the future with the computation result of [job]
|
||||
*/
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
public fun <T1, T2> execute(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
|
||||
* executeImpl(worker, mode, producer, job)
|
||||
* but first ensuring that `job` parameter doesn't capture any state.
|
||||
|
||||
@@ -26,17 +26,10 @@ import kotlin.comparisons.*
|
||||
* represents and multiplying by 10 raised to the power of the
|
||||
* exponent. Returns the closest double value to the real number.
|
||||
|
||||
* @param s
|
||||
* * the String that will be parsed to a floating point
|
||||
* *
|
||||
* @param e
|
||||
* * an int represent the 10 to part
|
||||
* *
|
||||
* @param s the String that will be parsed to a floating point
|
||||
* @param e an int represent the 10 to part
|
||||
* @return the double closest to the real number
|
||||
* *
|
||||
* *
|
||||
* @exception NumberFormatException
|
||||
* * if the String doesn't represent a positive integer value
|
||||
* @exception NumberFormatException if the String doesn't represent a positive integer value
|
||||
*/
|
||||
@SymbolName("Kotlin_native_FloatingPointParser_parseDoubleImpl")
|
||||
private external fun parseDoubleImpl(s: String, e: Int): Double
|
||||
@@ -48,17 +41,10 @@ private external fun parseDoubleImpl(s: String, e: Int): Double
|
||||
* represents and multiplying by 10 raised to the power of the
|
||||
* exponent. Returns the closest float value to the real number.
|
||||
|
||||
* @param s
|
||||
* * the String that will be parsed to a floating point
|
||||
* *
|
||||
* @param e
|
||||
* * an int represent the 10 to part
|
||||
* *
|
||||
* @param s the String that will be parsed to a floating point
|
||||
* @param e an int represent the 10 to part
|
||||
* @return the float closest to the real number
|
||||
* *
|
||||
* *
|
||||
* @exception NumberFormatException
|
||||
* * if the String doesn't represent a positive integer value
|
||||
* @exception NumberFormatException if the String doesn't represent a positive integer value
|
||||
*/
|
||||
@SymbolName("Kotlin_native_FloatingPointParser_parseFloatImpl")
|
||||
private external fun parseFloatImpl(s: String, e: Int): Float
|
||||
@@ -89,14 +75,9 @@ object FloatingPointParser {
|
||||
* taking the positive integer the String represents and multiplying by 10
|
||||
* raised to the power of the exponent.
|
||||
|
||||
* @param string
|
||||
* * the String that will be parsed to a floating point
|
||||
* *
|
||||
* @param string the String that will be parsed to a floating point
|
||||
* @return a StringExponentPair with necessary values
|
||||
* *
|
||||
* *
|
||||
* @exception NumberFormatException
|
||||
* * if the String doesn't pass basic tests
|
||||
* @exception NumberFormatException if the String doesn't pass basic tests
|
||||
*/
|
||||
private fun initialParse(string: String): StringExponentPair {
|
||||
var s = string
|
||||
@@ -306,15 +287,10 @@ object FloatingPointParser {
|
||||
|
||||
/**
|
||||
* Returns the closest double value to the real number in the string.
|
||||
|
||||
* @param string
|
||||
* * the String that will be parsed to a floating point
|
||||
* *
|
||||
*
|
||||
* @param string the String that will be parsed to a floating point
|
||||
* @return the double closest to the real number
|
||||
* *
|
||||
* *
|
||||
* @exception NumberFormatException
|
||||
* * if the String doesn't represent a double
|
||||
* @exception NumberFormatException if the String doesn't represent a double
|
||||
*/
|
||||
fun parseDouble(string: String): Double {
|
||||
var s = string
|
||||
@@ -358,15 +334,10 @@ object FloatingPointParser {
|
||||
|
||||
/**
|
||||
* Returns the closest float value to the real number in the string.
|
||||
|
||||
* @param s
|
||||
* * the String that will be parsed to a floating point
|
||||
* *
|
||||
*
|
||||
* @param s the String that will be parsed to a floating point
|
||||
* @return the float closest to the real number
|
||||
* *
|
||||
* *
|
||||
* @exception NumberFormatException
|
||||
* * if the String doesn't represent a float
|
||||
* @exception NumberFormatException if the String doesn't represent a float
|
||||
*/
|
||||
fun parseFloat(string: String): Float {
|
||||
var s = string
|
||||
|
||||
@@ -5,46 +5,60 @@
|
||||
|
||||
package kotlin.native.internal
|
||||
|
||||
// Cycle garbage collector interface.
|
||||
//
|
||||
// Konan relies upon reference counting for object management, however it could
|
||||
// not collect cyclical garbage, so we perform periodic garbage collection.
|
||||
// This may slow down application, so this interface provides control over how
|
||||
// garbage collector activates and runs.
|
||||
// Garbage collector can be in one of the following states:
|
||||
// * running
|
||||
// * suspended (so cycle candidates are collected, but GC is not performed until resume)
|
||||
// * stopped (all cyclical garbage is hopelessly lost)
|
||||
// Immediately after startup GC is in running state.
|
||||
// Depending on application needs it may select to suspend GC for certain phases of
|
||||
// its lifetime, and resume it later on, or just completely turn it off, if GC pauses
|
||||
// are less desirable than cyclical garbage leaks.
|
||||
/**
|
||||
* ## Cycle garbage collector interface.
|
||||
*
|
||||
* Konan relies upon reference counting for object management, however it could
|
||||
* not collect cyclical garbage, so we perform periodic garbage collection.
|
||||
* This may slow down application, so this interface provides control over how
|
||||
* garbage collector activates and runs.
|
||||
* Garbage collector can be in one of the following states:
|
||||
* - running
|
||||
* - suspended (so cycle candidates are collected, but GC is not performed until resume)
|
||||
* - stopped (all cyclical garbage is hopelessly lost)
|
||||
* Immediately after startup GC is in running state.
|
||||
* Depending on application needs it may select to suspend GC for certain phases of
|
||||
* its lifetime, and resume it later on, or just completely turn it off, if GC pauses
|
||||
* are less desirable than cyclical garbage leaks.
|
||||
*/
|
||||
object GC {
|
||||
// To force garbage collection immediately, unless collector is stopped
|
||||
// with stop() operation. Even if GC is suspended, collect() still triggers collection.
|
||||
/**
|
||||
* To force garbage collection immediately, unless collector is stopped
|
||||
* with [stop] operation. Even if GC is suspended, [collect] still triggers collection.
|
||||
*/
|
||||
@SymbolName("Kotlin_native_internal_GC_collect")
|
||||
external fun collect()
|
||||
|
||||
// Suspend garbage collection. Release candidates are still collected, but
|
||||
// GC algorithm is not executed.
|
||||
/**
|
||||
* Suspend garbage collection. Release candidates are still collected, but
|
||||
* GC algorithm is not executed.
|
||||
*/
|
||||
@SymbolName("Kotlin_native_internal_GC_suspend")
|
||||
external fun suspend()
|
||||
|
||||
// Resume garbage collection. Can potentially lead to GC immediately.
|
||||
/**
|
||||
* Resume garbage collection. Can potentially lead to GC immediately.
|
||||
*/
|
||||
@SymbolName("Kotlin_native_internal_GC_resume")
|
||||
external fun resume()
|
||||
|
||||
// Stop garbage collection. Cyclical garbage is no longer collected.
|
||||
/**
|
||||
* Stop garbage collection. Cyclical garbage is no longer collected.
|
||||
*/
|
||||
@SymbolName("Kotlin_native_internal_GC_stop")
|
||||
external fun stop()
|
||||
|
||||
// Start garbage collection. Cyclical garbage produced while GC was stopped
|
||||
// cannot be reclaimed, but all new garbage is collected.
|
||||
/**
|
||||
* Start garbage collection. Cyclical garbage produced while GC was stopped
|
||||
* cannot be reclaimed, but all new garbage is collected.
|
||||
*/
|
||||
@SymbolName("Kotlin_native_internal_GC_start")
|
||||
external fun start()
|
||||
|
||||
// GC threshold, controlling how frequenly GC is activated, and how much time GC
|
||||
// takes. Bigger values lead to longer GC pauses, but less GCs.
|
||||
/**
|
||||
* GC threshold, controlling how frequenly GC is activated, and how much time GC
|
||||
* takes. Bigger values lead to longer GC pauses, but less GCs.
|
||||
*/
|
||||
var threshold: Int
|
||||
get() = getThreshold()
|
||||
set(value) = setThreshold(value)
|
||||
|
||||
@@ -24,6 +24,9 @@ private external fun bigIntDigitGeneratorInstImpl(results: IntArray, uArray: Int
|
||||
@SymbolName("Kotlin_native_NumberConverter_ceil")
|
||||
private external fun ceil(x: Double): Double
|
||||
|
||||
/**
|
||||
* Converts [Float] or [Double] numbers to the [String] representation
|
||||
*/
|
||||
class NumberConverter {
|
||||
|
||||
private var setCount: Int = 0 // Number of times u and k have been gotten.
|
||||
|
||||
@@ -7,10 +7,11 @@ package kotlin.system
|
||||
|
||||
/**
|
||||
* Terminates the currently running process.
|
||||
* The argument serves as a status code; by convention,
|
||||
*
|
||||
* @param status serves as a status code; by convention,
|
||||
* a nonzero status code indicates abnormal termination.
|
||||
*
|
||||
* This method never returns normally.
|
||||
* @return This method never returns normally.
|
||||
*/
|
||||
@SymbolName("Kotlin_system_exitProcess")
|
||||
public external fun exitProcess(status: Int): Nothing
|
||||
@@ -5,30 +5,39 @@
|
||||
|
||||
package kotlin.system
|
||||
|
||||
/**
|
||||
* Gets current system time in milliseconds since epoch
|
||||
*/
|
||||
@SymbolName("Kotlin_system_getTimeMillis")
|
||||
public external fun getTimeMillis() : Long
|
||||
|
||||
/**
|
||||
* Gets current system time in nanoseconds since epoch
|
||||
*/
|
||||
@SymbolName("Kotlin_system_getTimeNanos")
|
||||
public external fun getTimeNanos() : Long
|
||||
|
||||
/**
|
||||
* Gets current system time in microseconds since epoch
|
||||
*/
|
||||
@SymbolName("Kotlin_system_getTimeMicros")
|
||||
public external fun getTimeMicros() : Long
|
||||
|
||||
/** Executes the given block and returns elapsed time in milliseconds. */
|
||||
/** Executes the given [block] and returns elapsed time in milliseconds. */
|
||||
public inline fun measureTimeMillis(block: () -> Unit) : Long {
|
||||
val start = getTimeMillis()
|
||||
block()
|
||||
return getTimeMillis() - start
|
||||
}
|
||||
|
||||
/** Executes the given block and returns elapsed time in microseconds (Kotlin/Native only). */
|
||||
/** Executes the given [block] and returns elapsed time in microseconds (Kotlin/Native only). */
|
||||
public inline fun measureTimeMicros(block: () -> Unit) : Long {
|
||||
val start = getTimeMicros()
|
||||
block()
|
||||
return getTimeMicros() - start
|
||||
}
|
||||
|
||||
/** Executes the given block and returns elapsed time in nanoseconds. */
|
||||
/** Executes the given [block] and returns elapsed time in nanoseconds. */
|
||||
public inline fun measureNanoTime(block: () -> Unit) : Long {
|
||||
val start = getTimeNanos()
|
||||
block()
|
||||
|
||||
Reference in New Issue
Block a user