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