Bindings to implement posix thread

This commit is contained in:
Andrew Golovashevich 2025-03-19 01:02:05 +03:00
parent c1f96f4915
commit 2b5eed2abe
4 changed files with 104 additions and 24 deletions

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -6,17 +6,8 @@ import kotlinx.atomicfu.update
import kotlinx.cinterop.CPointer
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.StableRef
import kotlinx.cinterop.nativeHeap
import kotlinx.cinterop.alloc
import kotlinx.cinterop.asStableRef
import kotlinx.cinterop.free
import kotlinx.cinterop.pointed
import kotlinx.cinterop.ptr
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
@OptIn(ExperimentalForeignApi::class)
@ -36,7 +27,7 @@ actual class Thread : AutoCloseable {
var exitedWithError: Throwable? = null
}
private val _threadHandler: CPointer<pthread_tVar>
private val _threadBindings: _PthreadsThreadBindings
private val _bootstrapArgRef: StableRef<ThreadBootstrapContext>
private val _state: AtomicRef<State>
@ -44,10 +35,9 @@ actual class Thread : AutoCloseable {
this._state = atomic(State.PENDING)
this._bootstrapArgRef = StableRef.create(ThreadBootstrapContext(routine))
_safeAutoClose2(onAbort = this._bootstrapArgRef::dispose) {
this._threadHandler = nativeHeap.alloc<pthread_tVar>().ptr
_safeAutoClose2(onAbort = { nativeHeap.free(this._threadHandler) }) {
var err = pthread_create(
this._threadHandler,
this._threadBindings = _PthreadsThreadBindings()
_safeAutoClose2(onAbort = this._threadBindings::free) {
var err = this._threadBindings.create(
null,
staticCFunction(Thread::_threadBootstrap),
this._bootstrapArgRef.asCPointer()
@ -59,7 +49,6 @@ actual class Thread : AutoCloseable {
}
actual fun start() {
when (this._state.compareAndExchange(State.PENDING, State.STARTING)) {
State.CLOSED -> throw IllegalStateException("Pthreads thread is destroyed")
@ -78,7 +67,7 @@ actual class Thread : AutoCloseable {
State.FINISHED -> return this._bootstrapArgRef.get().exitedWithError
State.STARTING, State.RUNNING, State.PENDING -> {}
}
var err = pthread_join(this._threadHandler.pointed.value, null)
var err = this._threadBindings.join(null)
if (err == 0)
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread") }
return this._bootstrapArgRef.get().exitedWithError
@ -96,19 +85,14 @@ actual class Thread : AutoCloseable {
_safeAutoClose1(
action = {
var err = pthread_join(this._threadHandler.pointed.value, null)
var err = this._threadBindings.join(null)
if (err == 0)
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread") }
},
finally = {
_safeAutoClose1(
action = { nativeHeap.free(this._threadHandler) },
finally = {
_safeAutoClose1(
action = { nativeHeap.free(this._threadHandler) },
finally = { this._bootstrapArgRef.dispose() }
)
}
action = { this._threadBindings.free() },
finally = { this._bootstrapArgRef.dispose() }
)
}
)

View File

@ -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()
}