Minor fixes and runnable test program

This commit is contained in:
Andrew Golovashevich 2025-03-19 03:47:07 +03:00
parent 2b5eed2abe
commit 18886705af
8 changed files with 92 additions and 13 deletions

View File

@ -21,6 +21,6 @@ fun KotlinMultiplatformExtension.suppressWarnings(vararg warningNames: String) {
fun KotlinMultiplatformExtension.configureWarnings() {
this.configureAllCompilersOptions a@{ this@a.freeCompilerArgs.addAll("-Wextra", "-Xexpect-actual-classes") }
this.suppressWarnings("JoinDeclarationAndAssignment", "CanBeVal", "ConvertSecondaryConstructorToPrimary", "FunctionName", "PropertyName", "PrivatePropertyName")
this.suppressWarnings()
}

View File

@ -35,6 +35,7 @@ internal class _Refcnt(private val _errMessage: String) {
this.checkNotClosed()
return _safeAutoClose2(onSuccess = this::decref, action = block)
}
fun close(errExistRefs: String) {
val state = this._value.compareAndExchange(0, -1)
when {
@ -47,4 +48,12 @@ internal class _Refcnt(private val _errMessage: String) {
this.incref()
return _safeAutoClose1(finally = this::decref, action = protected)
}
override fun toString(): String {
val refcntCached = this._value.value
if (refcntCached < 0)
return "<ref counter [closed]>"
else
return "<ref counter [${refcntCached}]>"
}
}

View File

@ -9,5 +9,6 @@ inline fun <R> Mutex.withLock(synchronizedBlock: () -> R): R {
contract {
callsInPlace(synchronizedBlock, InvocationKind.EXACTLY_ONCE)
}
this.lock()
return _safeAutoClose1(finally = this::unlock, synchronizedBlock)
}

View File

@ -24,12 +24,12 @@ internal fun <T> AtomicRef<T>.compareAndExchange(expected: T, newValue: T): T {
}
}
@Suppress("WRONG_INVOCATION_KIND")
@PublishedApi
internal inline fun <R> _safeAutoClose1(
finally: () -> Unit,
action: () -> R
): R {
@Suppress("WRONG_INVOCATION_KIND")
contract {
callsInPlace(action, InvocationKind.EXACTLY_ONCE)
callsInPlace(finally, InvocationKind.EXACTLY_ONCE)
@ -37,13 +37,13 @@ internal inline fun <R> _safeAutoClose1(
return _safeAutoClose3(onAbort = finally, onSuccess = finally, onCrossReturn = finally, action = action)
}
@Suppress("WRONG_INVOCATION_KIND")
@PublishedApi
internal inline fun <R> _safeAutoClose2(
onAbort: () -> Unit = {},
onSuccess: () -> Unit = {},
action: () -> R
): R {
@Suppress("WRONG_INVOCATION_KIND")
contract {
callsInPlace(action, InvocationKind.EXACTLY_ONCE)
callsInPlace(onAbort, InvocationKind.AT_MOST_ONCE)
@ -52,13 +52,13 @@ internal inline fun <R> _safeAutoClose2(
return _safeAutoClose3(onAbort = onAbort, onSuccess = onSuccess, onCrossReturn = onSuccess, action = action)
}
@Suppress("WRONG_INVOCATION_KIND")
@PublishedApi
internal inline fun <R> _safeAutoClose2e(
onAbort: (Throwable) -> Unit = {},
onAbort: (Throwable) -> Unit = { _ -> },
onSuccess: () -> Unit = {},
action: () -> R
): R {
@Suppress("WRONG_INVOCATION_KIND")
contract {
callsInPlace(action, InvocationKind.EXACTLY_ONCE)
callsInPlace(onAbort, InvocationKind.AT_MOST_ONCE)
@ -85,7 +85,7 @@ internal inline fun <R> _safeAutoClose3(
@PublishedApi
internal inline fun <R> _safeAutoClose3e(
onAbort: (Throwable) -> Unit = {},
onAbort: (Throwable) -> Unit = { _ -> },
onSuccess: () -> Unit = {},
onCrossReturn: () -> Unit = {},
action: () -> R

View File

@ -39,11 +39,11 @@ actual class Thread : AutoCloseable {
_safeAutoClose2(onAbort = this._threadBindings::free) {
var err = this._threadBindings.create(
null,
staticCFunction(Thread::_threadBootstrap),
staticCFunction({ arg -> return@staticCFunction Thread._threadBootstrap(arg) }),
this._bootstrapArgRef.asCPointer()
)
if (err == 0)
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread") }
if (err != 0)
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread: $d") }
}
}
@ -68,7 +68,7 @@ actual class Thread : AutoCloseable {
State.STARTING, State.RUNNING, State.PENDING -> {}
}
var err = this._threadBindings.join(null)
if (err == 0)
if (err != 0)
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread") }
return this._bootstrapArgRef.get().exitedWithError
}
@ -86,8 +86,8 @@ actual class Thread : AutoCloseable {
_safeAutoClose1(
action = {
var err = this._threadBindings.join(null)
if (err == 0)
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread") }
if (err != 0)
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to destroy pthreads thread: $d") }
},
finally = {
_safeAutoClose1(
@ -115,6 +115,7 @@ actual class Thread : AutoCloseable {
},
onSuccess = { context.threadState.value = State.FINISHED },
action = {
context.startSignal.await()
context.routine.run()
}
)

View File

@ -0,0 +1,25 @@
plugins {
kotlin("multiplatform")
}
repositories {
mavenCentral()
maven("https://maven.landgrafhomyak.ru/")
}
kotlin {
linuxX64 {
this.binaries.executable {
entryPoint("main")
}
}
sourceSets {
linuxX64Main {
dependencies {
implementation(project(":modules:low-level:multithreading"))
}
}
}
}

View File

@ -0,0 +1,42 @@
import platform.posix.sleep
import ru.landgrafhomyak.bgtu.networks0.low_level.multithreading.Thread
class Printer(private val prefix: String) : Thread.Routine {
override fun run() {
for (i in 0..3) {
print("${this.prefix}: ${i}\n")
sleep(1u)
}
}
}
fun main() {
try {
println("entry")
val t1 = Thread(Printer("t1"))
val t2 = Thread(Printer("t2"))
val t3 = Thread(Printer("t3"))
val t4 = Thread(Printer("t4"))
println("created")
sleep(2u)
println("starting...")
t1.start()
t2.start()
t3.start()
t4.start()
print("started\n")
t1.join()?.let(Throwable::printStackTrace)
t2.join()?.let(Throwable::printStackTrace)
t3.join()?.let(Throwable::printStackTrace)
t4.join()?.let(Throwable::printStackTrace)
println("finished")
} catch (e: Throwable) {
e.printStackTrace()
}
}

View File

@ -23,4 +23,5 @@ pluginManagement {
}
include(":modules:low-level:c-interop-utilities")
include(":modules:low-level:multithreading")
include(":modules:low-level:sockets")
include(":modules:low-level:sockets")
include(":programs:test")