Bindings to implement posix thread
This commit is contained in:
parent
c1f96f4915
commit
2b5eed2abe
@ -0,0 +1,35 @@
|
|||||||
|
package ru.landgrafhomyak.bgtu.networks0.low_level.multithreading
|
||||||
|
|
||||||
|
import kotlinx.cinterop.CFunction
|
||||||
|
import kotlinx.cinterop.CPointer
|
||||||
|
import kotlinx.cinterop.CPointerVarOf
|
||||||
|
import kotlinx.cinterop.CValuesRef
|
||||||
|
import kotlinx.cinterop.ExperimentalForeignApi
|
||||||
|
import kotlinx.cinterop.nativeHeap
|
||||||
|
import kotlinx.cinterop.alloc
|
||||||
|
import kotlinx.cinterop.free
|
||||||
|
import kotlinx.cinterop.pointed
|
||||||
|
import kotlinx.cinterop.ptr
|
||||||
|
import kotlinx.cinterop.value
|
||||||
|
import platform.posix.pthread_tVar
|
||||||
|
import platform.posix.pthread_create
|
||||||
|
import platform.posix.pthread_join
|
||||||
|
|
||||||
|
@OptIn(ExperimentalForeignApi::class)
|
||||||
|
internal actual class _PthreadsThreadBindings private constructor(private val _ptr: CPointer<pthread_tVar>) {
|
||||||
|
actual constructor() : this(nativeHeap.alloc<pthread_tVar>().ptr)
|
||||||
|
|
||||||
|
actual fun create(
|
||||||
|
attr: CValuesRef<platform.posix.pthread_attr_t>?,
|
||||||
|
routine: CPointer<CFunction<(CPointer<*>?) -> CPointer<*>?>>?,
|
||||||
|
arg: CValuesRef<*>?
|
||||||
|
): Int = pthread_create(this._ptr, attr, routine, arg)
|
||||||
|
|
||||||
|
actual fun join(
|
||||||
|
routineReturn: CValuesRef<CPointerVarOf<CPointer<*>>>?
|
||||||
|
): Int = pthread_join(this._ptr.pointed.value, routineReturn)
|
||||||
|
|
||||||
|
actual fun free() {
|
||||||
|
nativeHeap.free(this._ptr)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package ru.landgrafhomyak.bgtu.networks0.low_level.multithreading
|
||||||
|
|
||||||
|
import kotlinx.cinterop.CFunction
|
||||||
|
import kotlinx.cinterop.CPointer
|
||||||
|
import kotlinx.cinterop.CPointerVarOf
|
||||||
|
import kotlinx.cinterop.CValuesRef
|
||||||
|
import kotlinx.cinterop.ExperimentalForeignApi
|
||||||
|
import kotlinx.cinterop.nativeHeap
|
||||||
|
import kotlinx.cinterop.alloc
|
||||||
|
import kotlinx.cinterop.free
|
||||||
|
import kotlinx.cinterop.pointed
|
||||||
|
import kotlinx.cinterop.ptr
|
||||||
|
import kotlinx.cinterop.value
|
||||||
|
import platform.posix.pthread_attr_t
|
||||||
|
import platform.posix.pthread_tVar
|
||||||
|
import platform.posix.pthread_create
|
||||||
|
import platform.posix.pthread_join
|
||||||
|
|
||||||
|
@OptIn(ExperimentalForeignApi::class)
|
||||||
|
internal actual class _PthreadsThreadBindings private constructor(private val _ptr: CPointer<pthread_tVar>) {
|
||||||
|
actual constructor() : this(nativeHeap.alloc<pthread_tVar>().ptr)
|
||||||
|
|
||||||
|
actual fun create(
|
||||||
|
attr: CValuesRef<pthread_attr_t>?,
|
||||||
|
routine: CPointer<CFunction<(CPointer<*>?) -> CPointer<*>?>>?,
|
||||||
|
arg: CValuesRef<*>?
|
||||||
|
): Int = pthread_create(this._ptr, attr, routine, arg)
|
||||||
|
|
||||||
|
actual fun join(
|
||||||
|
routineReturn: CValuesRef<CPointerVarOf<CPointer<*>>>?
|
||||||
|
): Int = pthread_join(this._ptr.pointed.value, routineReturn)
|
||||||
|
|
||||||
|
actual fun free() {
|
||||||
|
nativeHeap.free(this._ptr)
|
||||||
|
}
|
||||||
|
}
|
@ -6,17 +6,8 @@ import kotlinx.atomicfu.update
|
|||||||
import kotlinx.cinterop.CPointer
|
import kotlinx.cinterop.CPointer
|
||||||
import kotlinx.cinterop.ExperimentalForeignApi
|
import kotlinx.cinterop.ExperimentalForeignApi
|
||||||
import kotlinx.cinterop.StableRef
|
import kotlinx.cinterop.StableRef
|
||||||
import kotlinx.cinterop.nativeHeap
|
|
||||||
import kotlinx.cinterop.alloc
|
|
||||||
import kotlinx.cinterop.asStableRef
|
import kotlinx.cinterop.asStableRef
|
||||||
import kotlinx.cinterop.free
|
|
||||||
import kotlinx.cinterop.pointed
|
|
||||||
import kotlinx.cinterop.ptr
|
|
||||||
import kotlinx.cinterop.staticCFunction
|
import kotlinx.cinterop.staticCFunction
|
||||||
import kotlinx.cinterop.value
|
|
||||||
import platform.posix.pthread_create
|
|
||||||
import platform.posix.pthread_join
|
|
||||||
import platform.posix.pthread_tVar
|
|
||||||
import ru.landgrafhomyak.bgtu.networks0.low_level.c_interop_utilities.PosixUtilities
|
import ru.landgrafhomyak.bgtu.networks0.low_level.c_interop_utilities.PosixUtilities
|
||||||
|
|
||||||
@OptIn(ExperimentalForeignApi::class)
|
@OptIn(ExperimentalForeignApi::class)
|
||||||
@ -36,7 +27,7 @@ actual class Thread : AutoCloseable {
|
|||||||
var exitedWithError: Throwable? = null
|
var exitedWithError: Throwable? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private val _threadHandler: CPointer<pthread_tVar>
|
private val _threadBindings: _PthreadsThreadBindings
|
||||||
private val _bootstrapArgRef: StableRef<ThreadBootstrapContext>
|
private val _bootstrapArgRef: StableRef<ThreadBootstrapContext>
|
||||||
private val _state: AtomicRef<State>
|
private val _state: AtomicRef<State>
|
||||||
|
|
||||||
@ -44,10 +35,9 @@ actual class Thread : AutoCloseable {
|
|||||||
this._state = atomic(State.PENDING)
|
this._state = atomic(State.PENDING)
|
||||||
this._bootstrapArgRef = StableRef.create(ThreadBootstrapContext(routine))
|
this._bootstrapArgRef = StableRef.create(ThreadBootstrapContext(routine))
|
||||||
_safeAutoClose2(onAbort = this._bootstrapArgRef::dispose) {
|
_safeAutoClose2(onAbort = this._bootstrapArgRef::dispose) {
|
||||||
this._threadHandler = nativeHeap.alloc<pthread_tVar>().ptr
|
this._threadBindings = _PthreadsThreadBindings()
|
||||||
_safeAutoClose2(onAbort = { nativeHeap.free(this._threadHandler) }) {
|
_safeAutoClose2(onAbort = this._threadBindings::free) {
|
||||||
var err = pthread_create(
|
var err = this._threadBindings.create(
|
||||||
this._threadHandler,
|
|
||||||
null,
|
null,
|
||||||
staticCFunction(Thread::_threadBootstrap),
|
staticCFunction(Thread::_threadBootstrap),
|
||||||
this._bootstrapArgRef.asCPointer()
|
this._bootstrapArgRef.asCPointer()
|
||||||
@ -59,7 +49,6 @@ actual class Thread : AutoCloseable {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
actual fun start() {
|
actual fun start() {
|
||||||
when (this._state.compareAndExchange(State.PENDING, State.STARTING)) {
|
when (this._state.compareAndExchange(State.PENDING, State.STARTING)) {
|
||||||
State.CLOSED -> throw IllegalStateException("Pthreads thread is destroyed")
|
State.CLOSED -> throw IllegalStateException("Pthreads thread is destroyed")
|
||||||
@ -78,7 +67,7 @@ actual class Thread : AutoCloseable {
|
|||||||
State.FINISHED -> return this._bootstrapArgRef.get().exitedWithError
|
State.FINISHED -> return this._bootstrapArgRef.get().exitedWithError
|
||||||
State.STARTING, State.RUNNING, State.PENDING -> {}
|
State.STARTING, State.RUNNING, State.PENDING -> {}
|
||||||
}
|
}
|
||||||
var err = pthread_join(this._threadHandler.pointed.value, null)
|
var err = this._threadBindings.join(null)
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread") }
|
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread") }
|
||||||
return this._bootstrapArgRef.get().exitedWithError
|
return this._bootstrapArgRef.get().exitedWithError
|
||||||
@ -96,23 +85,18 @@ actual class Thread : AutoCloseable {
|
|||||||
|
|
||||||
_safeAutoClose1(
|
_safeAutoClose1(
|
||||||
action = {
|
action = {
|
||||||
var err = pthread_join(this._threadHandler.pointed.value, null)
|
var err = this._threadBindings.join(null)
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread") }
|
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread") }
|
||||||
},
|
},
|
||||||
finally = {
|
finally = {
|
||||||
_safeAutoClose1(
|
_safeAutoClose1(
|
||||||
action = { nativeHeap.free(this._threadHandler) },
|
action = { this._threadBindings.free() },
|
||||||
finally = {
|
|
||||||
_safeAutoClose1(
|
|
||||||
action = { nativeHeap.free(this._threadHandler) },
|
|
||||||
finally = { this._bootstrapArgRef.dispose() }
|
finally = { this._bootstrapArgRef.dispose() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun _threadBootstrap(arg: CPointer<*>?): CPointer<*>? {
|
private fun _threadBootstrap(arg: CPointer<*>?): CPointer<*>? {
|
@ -0,0 +1,25 @@
|
|||||||
|
package ru.landgrafhomyak.bgtu.networks0.low_level.multithreading
|
||||||
|
|
||||||
|
import kotlinx.cinterop.CFunction
|
||||||
|
import kotlinx.cinterop.CPointer
|
||||||
|
import kotlinx.cinterop.CPointerVarOf
|
||||||
|
import kotlinx.cinterop.CValuesRef
|
||||||
|
import kotlinx.cinterop.ExperimentalForeignApi
|
||||||
|
import platform.posix.pthread_attr_t
|
||||||
|
|
||||||
|
@OptIn(ExperimentalForeignApi::class)
|
||||||
|
internal expect class _PthreadsThreadBindings {
|
||||||
|
constructor()
|
||||||
|
|
||||||
|
fun create(
|
||||||
|
attr: CValuesRef<pthread_attr_t>?,
|
||||||
|
routine: CPointer<CFunction<(CPointer<*>?) -> CPointer<*>?>>?,
|
||||||
|
arg: CValuesRef<*>?
|
||||||
|
): Int
|
||||||
|
|
||||||
|
fun join(
|
||||||
|
routineReturn: CValuesRef<CPointerVarOf<CPointer<*>>>?
|
||||||
|
): Int
|
||||||
|
|
||||||
|
fun free()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user