Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

coroutine finishing early #121

Closed
btwilk opened this issue Oct 17, 2022 · 2 comments
Closed

coroutine finishing early #121

btwilk opened this issue Oct 17, 2022 · 2 comments

Comments

@btwilk
Copy link

btwilk commented Oct 17, 2022

Version: 2.15
I'm model checking some code that uses Mutex. I ran into a case where lincheck incorrectly considers a coroutine that should still be running to have finished. Here is a minimal example:

class CoroutineLinTest {

    private var x = AtomicInteger()
    private val mutex = Mutex()

    @Operation(cancellableOnSuspension = false, allowExtraSuspension = true)
    suspend fun getAndInc(): Int {
        while (true) {
            val snapshot = x.get()
            mutex.withLock {
                if (snapshot == x.get()) {
                    return x.getAndIncrement()
                }
            }
        }
    }

    @Test
    fun test() = ModelCheckingOptions().check(this::class)
}

Here is the assertion error: coroutine-assertion-error.txt

In contrast, the equivalent code with thread synchronization model checks as expected (no counterexamples found):

class ThreadLinTest {

    private var x = AtomicInteger()
    private val mutex = Object()

    @Operation
    fun getAndInc(): Int {
        while (true) {
            val snapshot = x.get()
            synchronized(mutex) {
                if (snapshot == x.get()) {
                    return x.getAndIncrement()
                }
            }
        }
    }

    @Test
    fun test() = ModelCheckingOptions().check(this::class)
}
@ndkoval
Copy link
Collaborator

ndkoval commented Oct 17, 2022

@btwilk Unfortunetely, we do not support multiple suspensions at the moment, but we are considering imrpoving this part later.

@alefedor
Copy link
Contributor

@btwilk
Suprisingly, we did not have applications with multiple suspension points per operation.
Coroutine-based data structures (like queues or channels) mostly have only one natural suspension point.
I opened a more general issue, so I am closing this one

@ndkoval ndkoval closed this as not planned Won't fix, can't repro, duplicate, stale Apr 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants