-
Notifications
You must be signed in to change notification settings - Fork 34
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
Support custom threads #415
base: develop
Are you sure you want to change the base?
Conversation
The only failing CI configuration is "Integration Test with kotlinx.coroutines". |
...vm/test/org/jetbrains/kotlinx/lincheck_test/transformation/KotlinStdlibTransformationTest.kt
Outdated
Show resolved
Hide resolved
0ad50bd
to
25c0c45
Compare
@ndkoval while working on this I discovered a few problems, which are probably should be addressed in separate PRs. One of the problems is related to the local objects tracking --- the current implementation does not work correctly with custom threads (see example below and the comment in class Box(var x: Int)
fun test(): Int {
val box = Box() // <- this object is incorrectly classified as a local object
thread {
box.x = 42 // the local object tracker does not detect here that the `box` object,
// stored in the local variable, escapes into another thread;
// thus it will not insert a switch point before accesses to this object fields
}
return box.x
} I would propose that we can address this problem separately in another PR after we merge this one. Alternatively, we can first perform the necessary refactoring of the local objects tracking algorithm in a separate PR, |
bac6712
to
250236c
Compare
Another small bug fix on which this PR relies on: #426 |
8d548c9
to
9a4fdcd
Compare
…egy` Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
… blocking Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
…ead group Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
* in preparation of implementing ignored sections for custom threads Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
… ignored sections Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
…in `cancelByLincheck` Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
…lass Signed-off-by: Evgeniy Moiseenko <[email protected]>
…lass Signed-off-by: Evgeniy Moiseenko <[email protected]>
This reverts commit 2d52b3a.
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
…in the thread descriptors map Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
…n case of abort Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
…y the output Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
2428b4f
to
469be4f
Compare
…m stack traces) Signed-off-by: Evgeniy Moiseenko <[email protected]>
Signed-off-by: Evgeniy Moiseenko <[email protected]>
@@ -15,7 +15,7 @@ version=2.35-SNAPSHOT | |||
inceptionYear=2019 | |||
lastCopyrightYear=2023 | |||
|
|||
jdkToolchainVersion=17 | |||
jdkToolchainVersion=8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please revert the change
@@ -45,6 +50,101 @@ public class Injections { | |||
@SuppressWarnings({"FieldCanBeLocal", "unused"}) | |||
private static int currentEventId = -1; | |||
|
|||
// Thread local variable storing testing code and ignored section flags. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this line
* - These lists use copy-on-write strategy when a new descriptor is added to avoid race conditions. | ||
* - Thread descriptors store weak references to thread objects, and thus do not prevent their garbage collection. | ||
* | ||
* TODO: although the garbage collection of thread objects is not prevented thanks to weak references, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do the cleanup on each 1000's (feel free choose any number here) access
return ((TestThread) thread).descriptor; | ||
} | ||
int hashCode = System.identityHashCode(thread); | ||
ArrayList<ThreadDescriptor> threadDescriptors = threadDescriptorsMap.get(hashCode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use a weak hash map instead?
| | switch | | ||
| operation() | | | ||
| MONITORENTER at ObstructionFreedomSynchronizedRepresentationTest.operation(ObstructionFreedomRepresentationTest.kt:70) | | | ||
| MONITORENTER at ObstructionFreedomSynchronizedRepresentationTest.operation(ObstructionFreedomRepresentationTest.kt:61) | | | ||
| switch (reason: lock is already acquired) | | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there any switch? It seems the execution ends after this event.
| switch | | | | ||
| | run() | | | ||
| | switch | | | ||
| switch (reason: waiting for thread to join) | | | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's mention which thread the execution is calling join
on
internal fun modelCheckerTest( | ||
testClass: KClass<*>, | ||
testOperation: KFunction<*>, | ||
outcomes: Set<Any?> = setOf(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these the excepted outcomes?
@@ -79,7 +79,8 @@ fun shouldReplayInterleaving(): Boolean { | |||
*/ | |||
@Suppress("UNUSED_PARAMETER") | |||
fun beforeEvent(eventId: Int, type: String) { | |||
val strategy = (Thread.currentThread() as? TestThread)?.eventTracker ?: return | |||
val strategy = Injections.getCurrentThreadDescriptor()?.eventTracker |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you checked how custom threads work with the plugin?
* with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
package org.jetbrains.kotlinx.lincheck.util |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to have to Utils.kt
files?
@@ -204,7 +204,7 @@ internal class LoopDetector( | |||
// Has the thread changed? Reset the counters in this case. | |||
check(lastExecutedThread == iThread) { "reset expected!" } | |||
// Ignore coroutine suspension code locations. | |||
if (codeLocation == COROUTINE_SUSPENSION_CODE_LOCATION) return Decision.Idle |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why UNKNOWN? The documentation here and of the UNKNOWN_CODE_LOCATION
field says it is the coroutine suspension code location.
From what I can see, there is no significant changes in the time of CI builds between this branch and The reason is that in this PR I strive to preserve the old behavior whenever possible, by adding special treatment of
Thus, all the code interacting with |
No description provided.