Split ThreadLocalMethods for multithread platforms and single-thread platforms

This commit is contained in:
Andrew Golovashevich 2025-09-11 00:26:35 +03:00
parent d06f700803
commit e37e39a496
5 changed files with 83 additions and 34 deletions

View File

@ -40,7 +40,11 @@ kotlin {
configureAllCompilersOptionsOnAllTargets {
freeCompilerArgs.addAll("-Xexpect-actual-classes", "-Xrender-internal-diagnostic-names", "-XXLanguage:+ExpectRefinement")
freeCompilerArgs.addAll(
"-Xexpect-actual-classes",
"-Xrender-internal-diagnostic-names", "-Xdont-warn-on-error-suppression",
"-XXLanguage:+ExpectRefinement", /*"-Xreport-output-files"*/
)
}
jvm().compilations.configureEach {

View File

@ -3,7 +3,6 @@ package ru.landgrafhomyak.multitasking_0.threads
import ru.landgrafhomyak.multitasking_0.fibers.Fiber
import ru.landgrafhomyak.multitasking_0.SingleThreadEventLoop
import ru.landgrafhomyak.multitasking_0.WrongCallerThreadException
import ru.landgrafhomyak.multitasking_0.threads.sync.ResumeThreadCallback
public expect sealed interface ThreadLocalMethods {
/**
@ -39,36 +38,4 @@ public expect sealed interface ThreadLocalMethods {
public val runningEventLoop: SingleThreadEventLoop?
public fun setEventLoop(eventLoop: SingleThreadEventLoop): ClearEventLoopCallback
/**
* Hints platform scheduler to switch to another thread. Doesn't guarantee switching.
*/
public fun yield()
/**
* Removes thread from system scheduler until [resumeThread()][ResumeThreadCallback.resumeThread].
* If system allows unauthorized thread resuming, blocks these attempts.
*
* It's a high-level mechanism to implement custom synchronization methods, it isn't faster than existing native synchronization primitives.
*
* @param store callback to obtain and store [ResumeThreadCallback] reference.
* If [resumeThread()][ResumeThreadCallback.resumeThread] called inside - immediately returns.
*/
public fun suspendThread(store: (ResumeThreadCallback) -> Unit)
/**
* Removes thread from system scheduler until [resumeThread()][ResumeThreadCallback.resumeThread] or until timeout expires.
* If system allows unauthorized thread resuming, blocks these attempts.
*
* When timeout expires, [resumeThread()][ResumeThreadCallback.resumeThread] becomes unavailable
* (wrap it with explicit synchronization) and [timeoutHandler] called in thread that was suspended before this function returns.
*
* It's a high-level mechanism to implement custom synchronization methods, it isn't faster than existing native synchronization primitives.
*
* @param timeoutMillis timeout in milliseconds. If equals to `0`, [store] and [timeoutHandler] will be called anyway.
* @param timeoutHandler callback called by resumed thread after timeout expired.
* @param store callback to obtain and store [ResumeThreadCallback] reference.
* If [resumeThread()][ResumeThreadCallback.resumeThread] called inside - immediately returns.
*/
public fun suspendThread(timeoutMillis: UInt, timeoutHandler: ResumeThreadCallback.TimeoutHandler, store: (ResumeThreadCallback) -> Unit)
}

View File

@ -4,6 +4,7 @@ import ru.landgrafhomyak.multitasking_0.fibers.Fiber
import ru.landgrafhomyak.multitasking_0.SingleThreadEventLoop
import ru.landgrafhomyak.multitasking_0.threads.sync.ResumeThreadCallback
@Suppress("AMBIGUOUS_EXPECTS", "ACTUAL_WITHOUT_EXPECT")
public actual sealed interface ThreadLocalMethods {
public actual fun get(): Thread

View File

@ -0,0 +1,77 @@
package ru.landgrafhomyak.multitasking_0.threads
import kotlin.experimental.ExpectRefinement
import ru.landgrafhomyak.multitasking_0.fibers.Fiber
import ru.landgrafhomyak.multitasking_0.SingleThreadEventLoop
import ru.landgrafhomyak.multitasking_0.WrongCallerThreadException
import ru.landgrafhomyak.multitasking_0.threads.sync.ResumeThreadCallback
@OptIn(ExperimentalMultiplatform::class)
@ExpectRefinement
public expect sealed interface ThreadLocalMethods {
/**
* Returns descriptor of current thread.
*
* @throws WrongCallerThreadException if called on thread different that caller of [Thread.current].
*/
public fun get(): Thread
/**
* Returns descriptor of [fiber][Fiber] that is currently [running (or emulates running)][Fiber.resume]
* in this thread.
*
* If set, condition `Thread.current.runningFiber.resumedOnThread === Thread.current.get()` always true
*
* [Fiber][Fiber] implementations must control this property explicitly with [enterFiber()][ThreadLocalMethods.enterFiber]
* and [exitFiber()][ExitFiberCallback.exitFiber]
*
* @throws WrongCallerThreadException if called on thread different that caller of [Thread.current].
*/
public val runningFiber: Fiber?
/**
* Informs thread that execution flow was switched to [fiber][Fiber].
*
* @param fiberToEnter descriptor of fiber that is [going to run][Fiber.resume].
* @return Callback object to rollback value of [Thread.current.runningFiber][ThreadLocalMethods.runningFiber]
* to state before this call.
*
* @throws WrongCallerThreadException if called on thread different that caller of [Thread.current].
*/
public fun enterFiber(fiberToEnter: Fiber): ExitFiberCallback
public val runningEventLoop: SingleThreadEventLoop?
public fun setEventLoop(eventLoop: SingleThreadEventLoop): ClearEventLoopCallback
/**
* Hints platform scheduler to switch to another thread. Doesn't guarantee switching.
*/
public fun yield()
/**
* Removes thread from system scheduler until [resumeThread()][ResumeThreadCallback.resumeThread].
* If system allows unauthorized thread resuming, blocks these attempts.
*
* It's a high-level mechanism to implement custom synchronization methods, it isn't faster than existing native synchronization primitives.
*
* @param store callback to obtain and store [ResumeThreadCallback] reference.
* If [resumeThread()][ResumeThreadCallback.resumeThread] called inside - immediately returns.
*/
public fun suspendThread(store: (ResumeThreadCallback) -> Unit)
/**
* Removes thread from system scheduler until [resumeThread()][ResumeThreadCallback.resumeThread] or until timeout expires.
* If system allows unauthorized thread resuming, blocks these attempts.
*
* When timeout expires, [resumeThread()][ResumeThreadCallback.resumeThread] becomes unavailable
* (wrap it with explicit synchronization) and [timeoutHandler] called in thread that was suspended before this function returns.
*
* It's a high-level mechanism to implement custom synchronization methods, it isn't faster than existing native synchronization primitives.
*
* @param timeoutMillis timeout in milliseconds. If equals to `0`, [store] and [timeoutHandler] will be called anyway.
* @param timeoutHandler callback called by resumed thread after timeout expired.
* @param store callback to obtain and store [ResumeThreadCallback] reference.
* If [resumeThread()][ResumeThreadCallback.resumeThread] called inside - immediately returns.
*/
public fun suspendThread(timeoutMillis: UInt, timeoutHandler: ResumeThreadCallback.TimeoutHandler, store: (ResumeThreadCallback) -> Unit)
}