diff --git a/bootstrap/src/sun/nio/ch/lincheck/EventTracker.kt b/bootstrap/src/sun/nio/ch/lincheck/EventTracker.kt index 7f3d26717..8930ec812 100644 --- a/bootstrap/src/sun/nio/ch/lincheck/EventTracker.kt +++ b/bootstrap/src/sun/nio/ch/lincheck/EventTracker.kt @@ -40,7 +40,7 @@ interface EventTracker { fun afterWrite() fun beforeMethodCall(owner: Any?, className: String, methodName: String, codeLocation: Int, params: Array) - fun beforeAtomicMethodCall(owner: Any?, methodName: String, codeLocation: Int, params: Array) + fun beforeAtomicMethodCall(owner: Any?, className: String, methodName: String, codeLocation: Int, params: Array) fun onMethodCallFinishedSuccessfully(result: Any?) fun onMethodCallThrewException(t: Throwable) diff --git a/bootstrap/src/sun/nio/ch/lincheck/Injections.java b/bootstrap/src/sun/nio/ch/lincheck/Injections.java index c268955bb..3db979c64 100644 --- a/bootstrap/src/sun/nio/ch/lincheck/Injections.java +++ b/bootstrap/src/sun/nio/ch/lincheck/Injections.java @@ -262,8 +262,8 @@ public static void beforeMethodCall(Object owner, String className, String metho * This is just an optimization of [beforeMethodCall] for trusted * atomic constructs to avoid wrapping the invocations into try-finally blocks. */ - public static void beforeAtomicMethodCall(Object owner, String methodName, int codeLocation, Object[] params) { - getEventTracker().beforeAtomicMethodCall(owner, methodName, codeLocation, params); + public static void beforeAtomicMethodCall(Object owner, String className, String methodName, int codeLocation, Object[] params) { + getEventTracker().beforeAtomicMethodCall(owner, className, methodName, codeLocation, params); } /** diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/ObjectTraverser.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/ObjectTraverser.kt index d26b82a9a..3fad43ea4 100644 --- a/src/jvm/main/org/jetbrains/kotlinx/lincheck/ObjectTraverser.kt +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/ObjectTraverser.kt @@ -20,7 +20,7 @@ package org.jetbrains.kotlinx.lincheck -import org.jetbrains.kotlinx.lincheck.strategy.managed.getObjectNumber +import org.jetbrains.kotlinx.lincheck.strategy.managed.ObjectLabelFactory.getObjectNumber import org.jetbrains.kotlinx.lincheck.util.readFieldViaUnsafe import sun.misc.Unsafe import java.lang.reflect.Field diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/Utils.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/Utils.kt index c913f1d69..c099ec410 100644 --- a/src/jvm/main/org/jetbrains/kotlinx/lincheck/Utils.kt +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/Utils.kt @@ -15,6 +15,7 @@ import sun.nio.ch.lincheck.TestThread import org.jetbrains.kotlinx.lincheck.runner.* import org.jetbrains.kotlinx.lincheck.strategy.managed.* import org.jetbrains.kotlinx.lincheck.transformation.LincheckClassFileTransformer +import org.jetbrains.kotlinx.lincheck.util.UnsafeHolder import org.jetbrains.kotlinx.lincheck.verifier.* import java.io.PrintWriter import java.io.StringWriter @@ -194,6 +195,38 @@ internal val Throwable.text: String get() { return writer.buffer.toString() } +/** + * Returns all found fields in the hierarchy. + * Multiple fields with the same name and the same type may be returned + * if they appear in the subclass and a parent class. + */ +internal val Class<*>.allDeclaredFieldWithSuperclasses get(): List { + val fields: MutableList = ArrayList() + var currentClass: Class<*>? = this + while (currentClass != null) { + val declaredFields: Array = currentClass.declaredFields + fields.addAll(declaredFields) + currentClass = currentClass.superclass + } + return fields +} + +internal fun findFieldNameByOffset(targetType: Class<*>, offset: Long): String? { + // Extract the private offset value and find the matching field. + for (field in targetType.declaredFields) { + try { + if (Modifier.isNative(field.modifiers)) continue + val fieldOffset = if (Modifier.isStatic(field.modifiers)) UnsafeHolder.UNSAFE.staticFieldOffset(field) + else UnsafeHolder.UNSAFE.objectFieldOffset(field) + if (fieldOffset == offset) return field.name + } catch (t: Throwable) { + t.printStackTrace() + } + } + + return null // Field not found +} + /** * Utility exception for test purposes. * When this exception is thrown by an operation, it will halt testing with [UnexpectedExceptionInvocationResult]. diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/runner/ParallelThreadsRunner.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/runner/ParallelThreadsRunner.kt index c56905d2a..c955c239f 100644 --- a/src/jvm/main/org/jetbrains/kotlinx/lincheck/runner/ParallelThreadsRunner.kt +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/runner/ParallelThreadsRunner.kt @@ -183,12 +183,18 @@ internal open class ParallelThreadsRunner( private fun createTestInstance() { testInstance = testClass.newInstance() - // In the model checking mode, we need to ensure - // that all the necessary classes and instrumented - // after creating a test instance. - if (strategy is ModelCheckingStrategy && !ensuredTestInstanceIsTransformed) { - LincheckJavaAgent.ensureObjectIsTransformed(testInstance) - ensuredTestInstanceIsTransformed = true + if (strategy is ModelCheckingStrategy) { + // We pass the test instance to the strategy to initialize the call stack. + // It should be done here as we create the test instance in the `run` method in the runner, after + // `initializeInvocation` method call of ManagedStrategy. + strategy.initializeCallStack(testInstance) + // In the model checking mode, we need to ensure + // that all the necessary classes and instrumented + // after creating a test instance. + if (!ensuredTestInstanceIsTransformed) { + LincheckJavaAgent.ensureObjectIsTransformed(testInstance) + ensuredTestInstanceIsTransformed = true + } } testThreadExecutions.forEach { it.testInstance = testInstance } validationPartExecution?.let { it.testInstance = testInstance } diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/AtomicFieldUpdaterNames.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/AtomicFieldUpdaterNames.kt index d0162cec9..ee17d01b5 100644 --- a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/AtomicFieldUpdaterNames.kt +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/AtomicFieldUpdaterNames.kt @@ -10,8 +10,8 @@ package org.jetbrains.kotlinx.lincheck.strategy.managed +import org.jetbrains.kotlinx.lincheck.findFieldNameByOffset import org.jetbrains.kotlinx.lincheck.util.UnsafeHolder.UNSAFE -import java.lang.reflect.Modifier import java.util.concurrent.atomic.AtomicIntegerFieldUpdater import java.util.concurrent.atomic.AtomicLongFieldUpdater import java.util.concurrent.atomic.AtomicReferenceFieldUpdater @@ -22,7 +22,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater * equality and does not prevent them from being garbage collected. */ internal object AtomicFieldUpdaterNames { - fun getAtomicFieldUpdaterName(updater: Any): String? { + + internal fun getAtomicFieldUpdaterName(updater: Any): String? { if (updater !is AtomicIntegerFieldUpdater<*> && updater !is AtomicLongFieldUpdater<*> && updater !is AtomicReferenceFieldUpdater<*, *>) { throw IllegalArgumentException("Provided object is not a recognized Atomic*FieldUpdater type.") } @@ -35,16 +36,7 @@ internal object AtomicFieldUpdaterNames { val offsetField = updater.javaClass.getDeclaredField("offset") val offset = UNSAFE.getLong(updater, UNSAFE.objectFieldOffset(offsetField)) - for (field in targetType.declaredFields) { - try { - if (Modifier.isNative(field.modifiers)) continue - val fieldOffset = if (Modifier.isStatic(field.modifiers)) UNSAFE.staticFieldOffset(field) - else UNSAFE.objectFieldOffset(field) - if (fieldOffset == offset) return field.name - } catch (t: Throwable) { - t.printStackTrace() - } - } + return findFieldNameByOffset(targetType, offset) } catch (t: Throwable) { t.printStackTrace() } diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/AtomicReferenceNames.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/AtomicReferenceNames.kt new file mode 100644 index 000000000..8ccb0279e --- /dev/null +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/AtomicReferenceNames.kt @@ -0,0 +1,173 @@ +/* + * Lincheck + * + * Copyright (C) 2019 - 2024 JetBrains s.r.o. + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed + * with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.jetbrains.kotlinx.lincheck.strategy.managed + +import kotlinx.atomicfu.AtomicArray +import kotlinx.atomicfu.AtomicBooleanArray +import kotlinx.atomicfu.AtomicIntArray +import org.jetbrains.kotlinx.lincheck.allDeclaredFieldWithSuperclasses +import org.jetbrains.kotlinx.lincheck.strategy.managed.AtomicReferenceMethodType.* +import org.jetbrains.kotlinx.lincheck.strategy.managed.AtomicReferenceNames.AtomicReferenceOwnerWithName.* +import org.jetbrains.kotlinx.lincheck.strategy.managed.AtomicReferenceNames.TraverseResult.* +import java.lang.reflect.Modifier +import java.util.* +import java.util.concurrent.atomic.AtomicIntegerArray +import java.util.concurrent.atomic.AtomicLongArray +import java.util.concurrent.atomic.AtomicReferenceArray + +/** + * Provides method call type to create a more convenient trace point + * with a owner of this AtomicReference field and a name if it can be found. + * Recursively scans the test object, trying to find the provided AtomicReference + * instance as a field. If two or more fields contain this AtomicReference field, then we + * fall back to the default behavior. + */ +internal object AtomicReferenceNames { + + internal fun getMethodCallType( + testObject: Any, + atomicReference: Any, + parameters: Array + ): AtomicReferenceMethodType { + val receiverAndName = getAtomicReferenceReceiverAndName(testObject, atomicReference) + return if (receiverAndName != null) { + if (isAtomicArrayIndexMethodCall(atomicReference, parameters)) { + when (receiverAndName) { + is InstanceOwnerWithName -> InstanceFieldAtomicArrayMethod(receiverAndName.receiver, receiverAndName.fieldName, parameters[0] as Int) + is StaticOwnerWithName -> StaticFieldAtomicArrayMethod(receiverAndName.clazz, receiverAndName.fieldName, parameters[0] as Int) + } + } else { + when (receiverAndName) { + is InstanceOwnerWithName -> AtomicReferenceInstanceMethod(receiverAndName.receiver, receiverAndName.fieldName) + is StaticOwnerWithName -> AtomicReferenceStaticMethod(receiverAndName.clazz, receiverAndName.fieldName) + } + } + } else { + if (isAtomicArrayIndexMethodCall(atomicReference, parameters)) { + AtomicArrayMethod(atomicReference, parameters[0] as Int) + } else { + TreatAsDefaultMethod + } + } + } + + private fun isAtomicArrayIndexMethodCall(atomicReference: Any, parameters: Array): Boolean { + if (parameters.firstOrNull() !is Int) return false + return atomicReference is AtomicReferenceArray<*> || + atomicReference is AtomicLongArray || + atomicReference is AtomicIntegerArray || + atomicReference is AtomicIntArray || + atomicReference is AtomicArray<*> || + atomicReference is AtomicBooleanArray + } + + private fun getAtomicReferenceReceiverAndName(testObject: Any, reference: Any): AtomicReferenceOwnerWithName? = + runCatching { + val visitedObjects: MutableSet = Collections.newSetFromMap(IdentityHashMap()) + return when (val result = findObjectField(testObject, reference, visitedObjects)) { + is FieldName -> result.fieldName + MultipleFieldsMatching, NotFound -> null + } + }.getOrElse { exception -> + exception.printStackTrace() + null + } + + private sealed interface TraverseResult { + data object NotFound : TraverseResult + data class FieldName(val fieldName: AtomicReferenceOwnerWithName) : TraverseResult + data object MultipleFieldsMatching : TraverseResult + } + + private fun findObjectField(testObject: Any?, value: Any, visitedObjects: MutableSet): TraverseResult { + if (testObject == null) return NotFound + var fieldName: AtomicReferenceOwnerWithName? = null + // We take all the fields from the hierarchy. + // If two or more fields match (===) the AtomicReference object, we fall back to the default behavior, + // so there is no problem that we can receive some fields of the same name and the same type. + for (field in testObject::class.java.allDeclaredFieldWithSuperclasses) { + if (field.type.isPrimitive || !field.trySetAccessible()) continue + val fieldValue = field.get(testObject) + + if (fieldValue in visitedObjects) continue + visitedObjects += testObject + + if (fieldValue === value) { + if (fieldName != null) return MultipleFieldsMatching + + fieldName = if (Modifier.isStatic(field.modifiers)) { + StaticOwnerWithName(field.name, testObject::class.java) + } else { + InstanceOwnerWithName(field.name, testObject) + } + continue + } + when (val result = findObjectField(fieldValue, value, visitedObjects)) { + is FieldName -> { + if (fieldName != null) { + return MultipleFieldsMatching + } else { + fieldName = result.fieldName + } + } + + MultipleFieldsMatching -> return result + NotFound -> {} + } + } + return if (fieldName != null) FieldName(fieldName) else NotFound + } + + private sealed class AtomicReferenceOwnerWithName(val fieldName: String) { + class StaticOwnerWithName(fieldName: String, val clazz: Class<*>) : + AtomicReferenceOwnerWithName(fieldName) + + class InstanceOwnerWithName(fieldName: String, val receiver: Any) : + AtomicReferenceOwnerWithName(fieldName) + } +} + +/** + * The type of the AtomicReference method call. + */ +internal sealed interface AtomicReferenceMethodType { + /** + * AtomicArray method call. In this case, we cannot find the owner of this atomic array. + */ + data class AtomicArrayMethod(val atomicArray: Any, val index: Int) : AtomicReferenceMethodType + + /** + * AtomicArray method call. Returned if we found the [owner] and the [field], containing this AtomicArray. + */ + data class InstanceFieldAtomicArrayMethod(val owner: Any, val fieldName: String, val index: Int) : + AtomicReferenceMethodType + + /** + * Static AtomicArray method call. + */ + data class StaticFieldAtomicArrayMethod(val ownerClass: Class<*>, val fieldName: String, val index: Int) : + AtomicReferenceMethodType + + /** + * AtomicReference method call. Returned if we cannot find the owner of this atomic reference. + */ + data object TreatAsDefaultMethod : AtomicReferenceMethodType + + /** + * Instance AtomicReference method call. Returned if we found the [owner] and the [fieldName], containing this AtomicArray + */ + data class AtomicReferenceInstanceMethod(val owner: Any, val fieldName: String) : AtomicReferenceMethodType + + /** + * Static AtomicReference method call. Returned if we found the [ownerClass] and the [fieldName], containing this AtomicArray + */ + data class AtomicReferenceStaticMethod(val ownerClass: Class<*>, val fieldName: String) : AtomicReferenceMethodType +} diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/ManagedStrategy.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/ManagedStrategy.kt index 71c7deaab..abc7b6c54 100644 --- a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/ManagedStrategy.kt +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/ManagedStrategy.kt @@ -20,15 +20,20 @@ import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.* import org.jetbrains.kotlinx.lincheck.transformation.* import org.jetbrains.kotlinx.lincheck.util.* import org.jetbrains.kotlinx.lincheck.verifier.* -import org.jetbrains.kotlinx.lincheck.strategy.managed.AtomicFieldUpdaterNames.getAtomicFieldUpdaterName import sun.nio.ch.lincheck.* -import java.lang.invoke.* -import sun.misc.Unsafe import kotlinx.coroutines.* -import java.util.concurrent.atomic.* +import org.jetbrains.kotlinx.lincheck.strategy.managed.AtomicFieldUpdaterNames.getAtomicFieldUpdaterName +import org.jetbrains.kotlinx.lincheck.strategy.managed.AtomicReferenceMethodType.* +import org.jetbrains.kotlinx.lincheck.strategy.managed.ObjectLabelFactory.adornedStringRepresentation +import org.jetbrains.kotlinx.lincheck.strategy.managed.ObjectLabelFactory.cleanObjectNumeration +import org.jetbrains.kotlinx.lincheck.strategy.managed.UnsafeName.* +import org.jetbrains.kotlinx.lincheck.strategy.managed.VarHandleMethodType.* +import java.lang.invoke.VarHandle import java.lang.reflect.* import java.util.* +import java.util.concurrent.atomic.* import kotlin.collections.set +import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED /** * This is an abstraction for all managed strategies, which encapsulated @@ -121,6 +126,12 @@ abstract class ManagedStrategy( // Utility class for the plugin integration to provide ids for each trace point private var eventIdProvider = EventIdProvider() + /** + * Current method call context (static or instance). + * Initialized and used only in the trace collecting stage. + */ + private lateinit var callStackContextPerThread: Array> + private fun createRunner(): ManagedStrategyRunner = ManagedStrategyRunner( managedStrategy = this, @@ -135,6 +146,8 @@ abstract class ManagedStrategy( runImpl() } finally { runner.close() + // clear the numeration at the end to avoid memory leaks + cleanObjectNumeration() } // == STRATEGY INTERFACE METHODS == @@ -226,6 +239,7 @@ abstract class ManagedStrategy( failingResult is ManagedDeadlockInvocationResult || failingResult is ObstructionFreedomViolationInvocationResult ) + cleanObjectNumeration() runner.close() runner = createRunner() @@ -250,6 +264,12 @@ abstract class ManagedStrategy( return Trace(traceCollector!!.trace) } + fun initializeCallStack(testInstance: Any) { + if (collectTrace) { + callStackContextPerThread = Array(nThreads) { arrayListOf(CallContext.InstanceCallContext(testInstance)) } + } + } + /** * Runs the next invocation with the same [scenario][ExecutionScenario]. */ @@ -276,7 +296,7 @@ abstract class ManagedStrategy( // Forcibly finish the current execution by throwing an exception. throw ForcibleExecutionFinishError } - + private fun failDueToLivelock(lazyMessage: () -> String): Nothing { suddenInvocationResult = ObstructionFreedomViolationInvocationResult(lazyMessage(), runner.collectExecutionResults()) // Forcibly finish the current execution by throwing an exception. @@ -683,6 +703,7 @@ abstract class ManagedStrategy( val iThread = currentThread val tracePoint = if (collectTrace) { ReadTracePoint( + ownerRepresentation = findOwnerName(obj), iThread = iThread, actorId = currentActorId[iThread], callStackTrace = callStackTrace[iThread], @@ -713,6 +734,7 @@ abstract class ManagedStrategy( val iThread = currentThread val tracePoint = if (collectTrace) { ReadTracePoint( + ownerRepresentation = simpleClassName(className), iThread = iThread, actorId = currentActorId[iThread], callStackTrace = callStackTrace[iThread], @@ -734,10 +756,11 @@ abstract class ManagedStrategy( val iThread = currentThread val tracePoint = if (collectTrace) { ReadTracePoint( + ownerRepresentation = null, iThread = iThread, actorId = currentActorId[iThread], callStackTrace = callStackTrace[iThread], - fieldName = "Array[$index]", + fieldName = "${adornedStringRepresentation(array)}[$index]", stackTraceElement = CodeLocations.stackTrace(codeLocation) ) } else { @@ -754,7 +777,7 @@ abstract class ManagedStrategy( if (collectTrace) { runInIgnoredSection { val iThread = currentThread - lastReadTracePoint[iThread]?.initializeReadValue(value) + lastReadTracePoint[iThread]?.initializeReadValue(adornedStringRepresentation(value)) lastReadTracePoint[iThread] = null } } @@ -768,13 +791,14 @@ abstract class ManagedStrategy( val iThread = currentThread val tracePoint = if (collectTrace) { WriteTracePoint( + ownerRepresentation = findOwnerName(obj), iThread = iThread, actorId = currentActorId[iThread], callStackTrace = callStackTrace[iThread], fieldName = fieldName, stackTraceElement = CodeLocations.stackTrace(codeLocation) ).also { - it.initializeWrittenValue(value) + it.initializeWrittenValue(adornedStringRepresentation(value)) } } else { null @@ -789,13 +813,14 @@ abstract class ManagedStrategy( val iThread = currentThread val tracePoint = if (collectTrace) { WriteTracePoint( + ownerRepresentation = simpleClassName(className), iThread = iThread, actorId = currentActorId[iThread], callStackTrace = callStackTrace[iThread], fieldName = fieldName, stackTraceElement = CodeLocations.stackTrace(codeLocation) ).also { - it.initializeWrittenValue(value) + it.initializeWrittenValue(adornedStringRepresentation(value)) } } else { null @@ -811,13 +836,14 @@ abstract class ManagedStrategy( val iThread = currentThread val tracePoint = if (collectTrace) { WriteTracePoint( + ownerRepresentation = null, iThread = iThread, actorId = currentActorId[iThread], callStackTrace = callStackTrace[iThread], - fieldName = "Array[$index]", + fieldName = "${adornedStringRepresentation(array)}[$index]", stackTraceElement = CodeLocations.stackTrace(codeLocation) ).also { - it.initializeWrittenValue(value) + it.initializeWrittenValue(adornedStringRepresentation(value)) } } else { null @@ -901,7 +927,7 @@ abstract class ManagedStrategy( } else { params } - beforeMethodCall(currentThread, codeLocation, null, methodName, params) + beforeMethodCall(owner, currentThread, codeLocation, className, methodName, params) } } // It's important that this method can't be called inside runInIgnoredSection, as the ignored section @@ -913,7 +939,7 @@ abstract class ManagedStrategy( ManagedGuaranteeType.TREAT_AS_ATOMIC -> { runInIgnoredSection { if (collectTrace) { - beforeMethodCall(currentThread, codeLocation, null, methodName, params) + beforeMethodCall(owner, currentThread, codeLocation, className, methodName, params) } newSwitchPointOnAtomicMethodCall(codeLocation) } @@ -936,7 +962,7 @@ abstract class ManagedStrategy( } else { params } - beforeMethodCall(currentThread, codeLocation, null, methodName, params) + beforeMethodCall(owner, currentThread, codeLocation, className, methodName, params) } } } @@ -945,22 +971,13 @@ abstract class ManagedStrategy( override fun beforeAtomicMethodCall( owner: Any?, + className: String, methodName: String, codeLocation: Int, params: Array ) = runInIgnoredSection { if (collectTrace) { - val isAtomicUpdater = owner is AtomicIntegerFieldUpdater<*> || owner is AtomicLongFieldUpdater<*> || owner is AtomicReferenceFieldUpdater<*, *> - val ownerName = if (isAtomicUpdater) owner?.let { getAtomicFieldUpdaterName(it) } else null - // Drop the object instance and offset (in case of Unsafe) from the parameters - // when using Unsafe, VarHandle, or AtomicFieldUpdater. - @Suppress("NAME_SHADOWING") - val params = when { - isAtomicUpdater || owner is VarHandle -> params.drop(1).toTypedArray() - owner is Unsafe || (owner != null && owner::class.java.name == "jdk.internal.misc.Unsafe") -> params.drop(2).toTypedArray() - else -> params - } - beforeMethodCall(currentThread, codeLocation, ownerName, methodName, params) + beforeMethodCall(owner, currentThread, codeLocation, className, methodName, params) } newSwitchPointOnAtomicMethodCall(codeLocation) } @@ -970,7 +987,11 @@ abstract class ManagedStrategy( runInIgnoredSection { val iThread = currentThread val tracePoint = methodCallTracePointStack[iThread].removeLast() - tracePoint.initializeReturnedValue(if (result == Injections.VOID_RESULT) VoidResult else result) + when (result) { + Injections.VOID_RESULT -> tracePoint.initializeVoidReturnedValue() + COROUTINE_SUSPENDED -> tracePoint.initializeCoroutineSuspendedResult() + else -> tracePoint.initializeReturnedValue(adornedStringRepresentation(result)) + } afterMethodCall(iThread, tracePoint) traceCollector!!.addStateRepresentation() } @@ -1080,7 +1101,14 @@ abstract class ManagedStrategy( * @param codeLocation the byte-code location identifier of this invocation * @param iThread number of invoking thread */ - private fun beforeMethodCall(iThread: Int, codeLocation: Int, ownerName: String?, methodName: String, params: Array) { + private fun beforeMethodCall( + owner: Any?, + iThread: Int, + codeLocation: Int, + className: String, + methodName: String, + params: Array, + ) { val callStackTrace = callStackTrace[iThread] val suspendedMethodStack = suspendedFunctionsStack[iThread] val methodId = if (suspendedMethodStack.isNotEmpty()) { @@ -1093,18 +1121,208 @@ abstract class ManagedStrategy( methodCallNumber++ } // Code location of the new method call is currently the last one + val tracePoint = createBeforeMethodCallTracePoint(owner, iThread, className, methodName, params, codeLocation) + methodCallTracePointStack[iThread] += tracePoint + callStackTrace.add(CallStackTraceElement(tracePoint, methodId)) + if (owner == null) { + beforeStaticMethodCall() + } else { + beforeInstanceMethodCall(owner) + } + } + + private fun createBeforeMethodCallTracePoint( + owner: Any?, + iThread: Int, + className: String, + methodName: String, + params: Array, + codeLocation: Int + ): MethodCallTracePoint { + val callStackTrace = callStackTrace[iThread] val tracePoint = MethodCallTracePoint( iThread = iThread, actorId = currentActorId[iThread], callStackTrace = callStackTrace, methodName = methodName, stackTraceElement = CodeLocations.stackTrace(codeLocation) - ).also { - it.initializeParameters(params) - it.initializeOwnerName(ownerName) + ) + if (owner is VarHandle) { + return initializeVarHandleMethodCallTracePoint(tracePoint, owner, params) } - methodCallTracePointStack[iThread] += tracePoint - callStackTrace.add(CallStackTraceElement(tracePoint, methodId)) + if (owner is AtomicIntegerFieldUpdater<*> || owner is AtomicLongFieldUpdater<*> || owner is AtomicReferenceFieldUpdater<*, *>) { + return initializeAtomicUpdaterMethodCallTracePoint(tracePoint, owner, params) + } + if (isAtomicReference(owner)) { + return initializeAtomicReferenceMethodCallTracePoint(tracePoint, owner!!, params) + } + if (isUnsafe(owner)) { + return initializeUnsafeMethodCallTracePoint(tracePoint, owner!!, params) + } + + tracePoint.initializeParameters(params.map { adornedStringRepresentation(it) }) + + val ownerName = if (owner != null) findOwnerName(owner) else simpleClassName(className) + if (ownerName != null) { + tracePoint.initializeOwnerName(ownerName) + } + + return tracePoint + } + + private fun simpleClassName(className: String) = className.takeLastWhile { it != '/' } + + private fun initializeUnsafeMethodCallTracePoint( + tracePoint: MethodCallTracePoint, + receiver: Any, + params: Array + ): MethodCallTracePoint { + when (val unsafeMethodName = UnsafeNames.getMethodCallType(params)) { + is UnsafeArrayMethod -> { + val owner = "${adornedStringRepresentation(unsafeMethodName.array)}[${unsafeMethodName.index}]" + tracePoint.initializeOwnerName(owner) + tracePoint.initializeParameters(unsafeMethodName.parametersToPresent.map { adornedStringRepresentation(it) }) + } + is UnsafeName.TreatAsDefaultMethod -> { + tracePoint.initializeOwnerName(adornedStringRepresentation(receiver)) + tracePoint.initializeParameters(params.map { adornedStringRepresentation(it) }) + } + is UnsafeInstanceMethod -> { + val ownerName = findOwnerName(unsafeMethodName.owner) + val owner = ownerName?.let { "$ownerName.${unsafeMethodName.fieldName}" } ?: unsafeMethodName.fieldName + tracePoint.initializeOwnerName(owner) + tracePoint.initializeParameters(unsafeMethodName.parametersToPresent.map { adornedStringRepresentation(it) }) + } + is UnsafeStaticMethod -> { + tracePoint.initializeOwnerName("${unsafeMethodName.clazz.simpleName}.${unsafeMethodName.fieldName}") + tracePoint.initializeParameters(unsafeMethodName.parametersToPresent.map { adornedStringRepresentation(it) }) + } + } + + return tracePoint + } + + private fun initializeAtomicReferenceMethodCallTracePoint( + tracePoint: MethodCallTracePoint, + receiver: Any, + params: Array + ): MethodCallTracePoint { + when (val atomicReferenceInfo = AtomicReferenceNames.getMethodCallType(runner.testInstance, receiver, params)) { + is AtomicArrayMethod -> { + tracePoint.initializeOwnerName("${adornedStringRepresentation(atomicReferenceInfo.atomicArray)}[${atomicReferenceInfo.atomicArray}]") + tracePoint.initializeParameters(params.drop(1).map { adornedStringRepresentation(it) }) + } + is InstanceFieldAtomicArrayMethod -> { + val receiverName = findOwnerName(atomicReferenceInfo.owner) + tracePoint.initializeOwnerName((receiverName?.let { "$it." } ?: "") + "${atomicReferenceInfo.fieldName}[${atomicReferenceInfo.index}]") + tracePoint.initializeParameters(params.drop(1).map { adornedStringRepresentation(it) }) + } + AtomicReferenceMethodType.TreatAsDefaultMethod -> { + tracePoint.initializeOwnerName(adornedStringRepresentation(receiver)) + tracePoint.initializeParameters(params.map { adornedStringRepresentation(it) }) + } + is AtomicReferenceInstanceMethod -> { + val receiverName = findOwnerName(atomicReferenceInfo.owner) + tracePoint.initializeOwnerName(receiverName?.let { "$it.${atomicReferenceInfo.fieldName}" } ?: atomicReferenceInfo.fieldName) + tracePoint.initializeParameters(params.map { adornedStringRepresentation(it) }) + } + is AtomicReferenceStaticMethod -> { + tracePoint.initializeOwnerName("${atomicReferenceInfo.ownerClass.simpleName}.${atomicReferenceInfo.fieldName}") + tracePoint.initializeParameters(params.map { adornedStringRepresentation(it) }) + } + is StaticFieldAtomicArrayMethod -> { + tracePoint.initializeOwnerName("${atomicReferenceInfo.ownerClass.simpleName}.${atomicReferenceInfo.fieldName}[${atomicReferenceInfo.index}]") + tracePoint.initializeParameters(params.drop(1).map { adornedStringRepresentation(it) }) + } + } + return tracePoint + } + + private fun initializeVarHandleMethodCallTracePoint( + tracePoint: MethodCallTracePoint, + varHandle: VarHandle, + parameters: Array, + ): MethodCallTracePoint { + when (val varHandleMethodType = VarHandleNames.varHandleMethodType(varHandle, parameters)) { + is ArrayVarHandleMethod -> { + tracePoint.initializeOwnerName("${adornedStringRepresentation(varHandleMethodType.array)}[${varHandleMethodType.index}]") + tracePoint.initializeParameters(varHandleMethodType.parameters.map { adornedStringRepresentation(it) }) + } + VarHandleMethodType.TreatAsDefaultMethod -> { + tracePoint.initializeOwnerName(adornedStringRepresentation(varHandle)) + tracePoint.initializeParameters(parameters.map { adornedStringRepresentation(it) }) + } + is InstanceVarHandleMethod -> { + val receiverName = findOwnerName(varHandleMethodType.owner) + tracePoint.initializeOwnerName(receiverName?.let { "$it.${varHandleMethodType.fieldName}" } ?: varHandleMethodType.fieldName) + tracePoint.initializeParameters(varHandleMethodType.parameters.map { adornedStringRepresentation(it) }) + } + is StaticVarHandleMethod -> { + tracePoint.initializeOwnerName("${varHandleMethodType.ownerClass.simpleName}.${varHandleMethodType.fieldName}") + tracePoint.initializeParameters(varHandleMethodType.parameters.map { adornedStringRepresentation(it) }) + } + } + + return tracePoint + } + + private fun initializeAtomicUpdaterMethodCallTracePoint( + tracePoint: MethodCallTracePoint, + atomicUpdater: Any, + parameters: Array, + ): MethodCallTracePoint { + getAtomicFieldUpdaterName(atomicUpdater)?.let { tracePoint.initializeOwnerName(it) } + tracePoint.initializeParameters(parameters.drop(1).map { adornedStringRepresentation(it) }) + return tracePoint + } + + private fun isAtomicReference(receiver: Any?) = receiver is AtomicReference<*> || + receiver is AtomicLong || + receiver is AtomicInteger || + receiver is AtomicBoolean || + receiver is AtomicIntegerArray || + receiver is AtomicReferenceArray<*> || + receiver is AtomicLongArray + + private fun isUnsafe(receiver: Any?): Boolean { + if (receiver == null) return false + val className = receiver::class.java.name + return className == "sun.misc.Unsafe" || className == "jdk.internal.misc.Unsafe" + } + + /** + * Returns beautiful string representation of the [owner]. + * If the [owner] is `this` of the current method, then returns `null`. + */ + private fun findOwnerName(owner: Any): String? { + if (isOwnerCurrentContext(owner)) return null + return adornedStringRepresentation(owner) + } + + /** + * Checks if [owner] is the current `this` in the current method context. + */ + private fun isOwnerCurrentContext(owner: Any): Boolean { + return when (val callContext = callStackContextPerThread[currentThread].last()) { + is CallContext.InstanceCallContext -> callContext.instance === owner + is CallContext.StaticCallContext -> false + } + } + + /* Methods to control the current call context. */ + + private fun beforeStaticMethodCall() { + callStackContextPerThread[currentThread].add(CallContext.StaticCallContext) + } + + private fun beforeInstanceMethodCall(receiver: Any) { + callStackContextPerThread[currentThread].add(CallContext.InstanceCallContext(receiver)) + } + + private fun afterExitMethod() { + val currentContext = callStackContextPerThread[currentThread] + currentContext.removeLast() + check(currentContext.isNotEmpty()) { "Context cannot be empty" } } /** @@ -1114,6 +1332,7 @@ abstract class ManagedStrategy( * @param tracePoint the corresponding trace point for the invocation */ private fun afterMethodCall(iThread: Int, tracePoint: MethodCallTracePoint) { + afterExitMethod() val callStackTrace = callStackTrace[iThread] if (tracePoint.wasSuspended) { // if a method call is suspended, save its identifier to reuse for continuation resuming @@ -1312,6 +1531,20 @@ abstract class ManagedStrategy( } } + /** + * Current method context in a call stack. + */ + sealed interface CallContext { + /** + * Indicates that current method is static. + */ + data object StaticCallContext: CallContext + + /** + * Indicates that method is called on the instance. + */ + data class InstanceCallContext(val instance: Any): CallContext + } } /** diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/ObjectLabelFactory.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/ObjectLabelFactory.kt new file mode 100644 index 000000000..24e0facb5 --- /dev/null +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/ObjectLabelFactory.kt @@ -0,0 +1,113 @@ +/* + * Lincheck + * + * Copyright (C) 2019 - 2024 JetBrains s.r.o. + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed + * with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.jetbrains.kotlinx.lincheck.strategy.managed + +import java.math.BigDecimal +import java.math.BigInteger +import java.util.* +import kotlin.coroutines.Continuation + +/** + * Helps to assign number to an object and to create its beautiful representation to provide to the trace. + */ +object ObjectLabelFactory { + + private val objectNumeration = Collections.synchronizedMap(WeakHashMap, MutableMap>()) + + internal fun adornedStringRepresentation(any: Any?): String { + // Primitive types (and several others) are immutable and + // have trivial `toString` implementation, which is used here. + if (any == null || any.javaClass.isImmutableWithNiceToString) + return any.toString() + // For enum types, we can always display their name. + if (any.javaClass.isEnum) { + return (any as Enum<*>).name + } + // simplified representation for Continuations + // (we usually do not really care about details). + if (any is Continuation<*>) + return "" + // Instead of java.util.HashMap$Node@3e2a56 show Node@1. + // It is better not to use `toString` in general since + // we usually care about references to certain objects, + // not about the content inside them. + return getObjectName(any) + } + + internal fun getObjectNumber(clazz: Class, obj: Any): Int = objectNumeration + .computeIfAbsent(clazz) { IdentityHashMap() } + .computeIfAbsent(obj) { 1 + objectNumeration[clazz]!!.size } + + internal fun cleanObjectNumeration() { + objectNumeration.clear() + } + + private val Class<*>.simpleNameForAnonymous: String + get() { + // Split by the package separator and return the result if this is not an inner class. + val withoutPackage = name.substringAfterLast('.') + if (!withoutPackage.contains("$")) return withoutPackage + // Extract the last named inner class followed by any "$" patterns using regex. + val regex = """(.*\$)?([^\$.\d]+(\$\d+)*)""".toRegex() + val matchResult = regex.matchEntire(withoutPackage) + return matchResult?.groups?.get(2)?.value ?: withoutPackage + } + + private fun getObjectName(obj: Any?): String = + if (obj != null) { + if (obj.javaClass.isAnonymousClass) { + obj.javaClass.simpleNameForAnonymous + } else { + objectName(obj) + "#" + getObjectNumber(obj.javaClass, obj) + } + } else { + "null" + } + + private fun objectName(obj: Any): String { + return when (obj) { + is IntArray -> "IntArray" + is ShortArray -> "ShortArray" + is CharArray -> "CharArray" + is ByteArray -> "ByteArray" + is BooleanArray -> "BooleanArray" + is DoubleArray -> "DoubleArray" + is FloatArray -> "FloatArray" + is LongArray -> "LongArray" + is Array<*> -> "Array<${obj.javaClass.componentType.simpleName}>" + else -> obj.javaClass.simpleName + } + } + + @Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") + private val Class?.isImmutableWithNiceToString + get() = this?.canonicalName in + listOf( + java.lang.Integer::class.java, + java.lang.Long::class.java, + java.lang.Short::class.java, + java.lang.Double::class.java, + java.lang.Float::class.java, + java.lang.Character::class.java, + java.lang.Byte::class.java, + java.lang.Boolean::class.java, + java.lang.String::class.java, + BigInteger::class.java, + BigDecimal::class.java, + kotlinx.coroutines.internal.Symbol::class.java, + ).map { it.canonicalName } + + listOf( + "java.util.Collections.SingletonList", + "java.util.Collections.SingletonMap", + "java.util.Collections.SingletonSet" + ) + +} \ No newline at end of file diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/TracePoint.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/TracePoint.kt index ff9756d5e..7b45fbe6b 100644 --- a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/TracePoint.kt +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/TracePoint.kt @@ -89,43 +89,54 @@ internal class ObstructionFreedomViolationExecutionAbortTracePoint( } internal class ReadTracePoint( + private val ownerRepresentation: String?, iThread: Int, actorId: Int, callStackTrace: CallStackTrace, - private val fieldName: String?, + private val fieldName: String, stackTraceElement: StackTraceElement ) : CodeLocationTracePoint(iThread, actorId, callStackTrace, stackTraceElement) { - private var value: Any? = null + private lateinit var valueRepresentation: String override fun toStringCompact(): String = StringBuilder().apply { - if (fieldName != null) + if (ownerRepresentation != null) { + append("$ownerRepresentation.$fieldName.") + } else { append("$fieldName.") + } append("READ") - append(": ${adornedStringRepresentation(value)}") + append(": $valueRepresentation") }.toString() - fun initializeReadValue(value: Any?) { - this.value = value + fun initializeReadValue(value: String) { + this.valueRepresentation = value + if (value == "StubClass#19") { + Unit + } } } internal class WriteTracePoint( + private val ownerRepresentation: String?, iThread: Int, actorId: Int, callStackTrace: CallStackTrace, - private val fieldName: String?, + private val fieldName: String, stackTraceElement: StackTraceElement ) : CodeLocationTracePoint(iThread, actorId, callStackTrace, stackTraceElement) { - private var value: Any? = null + private lateinit var valueRepresentation: String override fun toStringCompact(): String = StringBuilder().apply { - if (fieldName != null) + if (ownerRepresentation != null) { + append("$ownerRepresentation.$fieldName.") + } else { append("$fieldName.") + } append("WRITE(") - append(adornedStringRepresentation(value)) + append(valueRepresentation) append(")") }.toString() - fun initializeWrittenValue(value: Any?) { - this.value = value + fun initializeWrittenValue(value: String) { + this.valueRepresentation = value } } @@ -135,43 +146,63 @@ internal class MethodCallTracePoint( private val methodName: String, stackTraceElement: StackTraceElement ) : CodeLocationTracePoint(iThread, actorId, callStackTrace, stackTraceElement) { - private var returnedValue: Any? = NO_VALUE + private var returnedValue: ReturnedValueResult = ReturnedValueResult.NoValue private var thrownException: Throwable? = null - private var parameters: Array? = null + private var parameters: List? = null private var ownerName: String? = null - val wasSuspended get() = returnedValue === COROUTINE_SUSPENDED + val wasSuspended get() = returnedValue == ReturnedValueResult.CoroutineSuspended override fun toStringCompact(): String = StringBuilder().apply { if (ownerName != null) append("$ownerName.") append("$methodName(") - if (parameters != null) - append(parameters!!.joinToString(",", transform = ::adornedStringRepresentation)) + val parameters = parameters + if (parameters != null) { + append(parameters.joinToString(",")) + } append(")") - if (returnedValue != NO_VALUE && returnedValue != VoidResult) - append(": ${adornedStringRepresentation(returnedValue)}") - else if (thrownException != null && thrownException != ForcibleExecutionFinishError) + val returnedValue = returnedValue + if (returnedValue is ReturnedValueResult.ValueResult) { + append(": ${returnedValue.valueRepresentation}") + } else if (returnedValue is ReturnedValueResult.CoroutineSuspended) { + append(": COROUTINE_SUSPENDED") + } else if (thrownException != null && thrownException != ForcibleExecutionFinishError) { append(": threw ${thrownException!!.javaClass.simpleName}") + } }.toString() - fun initializeReturnedValue(value: Any?) { - this.returnedValue = value + fun initializeVoidReturnedValue() { + returnedValue = ReturnedValueResult.VoidResult + } + + fun initializeCoroutineSuspendedResult() { + returnedValue = ReturnedValueResult.CoroutineSuspended + } + + fun initializeReturnedValue(valueRepresentation: String) { + returnedValue = ReturnedValueResult.ValueResult(valueRepresentation) } fun initializeThrownException(exception: Throwable) { this.thrownException = exception } - fun initializeParameters(parameters: Array) { + fun initializeParameters(parameters: List) { this.parameters = parameters } - fun initializeOwnerName(ownerName: String?) { + fun initializeOwnerName(ownerName: String) { this.ownerName = ownerName } } -private val NO_VALUE = Any() + +private sealed interface ReturnedValueResult { + data object NoValue: ReturnedValueResult + data object VoidResult: ReturnedValueResult + data object CoroutineSuspended: ReturnedValueResult + data class ValueResult(val valueRepresentation: String): ReturnedValueResult +} internal class MonitorEnterTracePoint( iThread: Int, actorId: Int, @@ -270,26 +301,6 @@ private fun StackTraceElement.shorten(): String { return stackTraceElement } -private fun adornedStringRepresentation(any: Any?): String { - // Primitive types (and several others) are immutable and - // have trivial `toString` implementation, which is used here. - if (any == null || any.javaClass.isImmutableWithNiceToString) - return any.toString() - // For enum types, we can always display their name. - if (any.javaClass.isEnum) { - return (any as Enum<*>).name - } - // simplified representation for Continuations - // (we usually do not really care about details). - if (any is Continuation<*>) - return "" - // Instead of java.util.HashMap$Node@3e2a56 show Node@1. - // It is better not to use `toString` in general since - // we usually care about references to certain objects, - // not about the content inside them. - return getObjectName(any) -} - internal enum class SwitchReason(private val reason: String) { MONITOR_WAIT("wait on monitor"), LOCK_WAIT("lock is already acquired"), @@ -307,25 +318,3 @@ internal enum class SwitchReason(private val reason: String) { * Suspended method calls have the same [identifier] before and after suspension, but different [call] points. */ internal class CallStackTraceElement(val call: MethodCallTracePoint, val identifier: Int) - -@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") -private val Class?.isImmutableWithNiceToString get() = this?.canonicalName in - listOf( - java.lang.Integer::class.java, - java.lang.Long::class.java, - java.lang.Short::class.java, - java.lang.Double::class.java, - java.lang.Float::class.java, - java.lang.Character::class.java, - java.lang.Byte::class.java, - java.lang.Boolean::class.java, - java.lang.String::class.java, - BigInteger::class.java, - BigDecimal::class.java, - kotlinx.coroutines.internal.Symbol::class.java, - ).map { it.canonicalName } + - listOf( - "java.util.Collections.SingletonList", - "java.util.Collections.SingletonMap", - "java.util.Collections.SingletonSet" - ) \ No newline at end of file diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/TraceReporter.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/TraceReporter.kt index 4e1b1a02a..3bd3578b0 100644 --- a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/TraceReporter.kt +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/TraceReporter.kt @@ -27,17 +27,11 @@ internal fun StringBuilder.appendTrace( trace: Trace, exceptionStackTraces: Map ) { - // reset objects numeration - cleanObjectNumeration() - val startTraceGraphNode = constructTraceGraph(failure, results, trace, exceptionStackTraces) appendShortTrace(startTraceGraphNode, failure) appendExceptionsStackTracesBlock(exceptionStackTraces) appendDetailedTrace(startTraceGraphNode, failure) - - // clear the numeration at the end to avoid memory leaks - cleanObjectNumeration() } /** @@ -509,38 +503,6 @@ private fun TraceNode.stateEventRepresentation(iThread: Int, stateRepresentation internal class TraceEventRepresentation(val iThread: Int, val representation: String) -internal fun getObjectName(obj: Any?): String = - if (obj != null) { - if (obj.javaClass.isAnonymousClass) { - obj.javaClass.simpleNameForAnonymous - } else { - obj.javaClass.simpleName + "#" + getObjectNumber(obj.javaClass, obj) - } - } else { - "null" - } - -private val Class<*>.simpleNameForAnonymous: String get() { - // Split by the package separator and return the result if this is not an inner class. - val withoutPackage = name.substringAfterLast('.') - if (!withoutPackage.contains("$")) return withoutPackage - // Extract the last named inner class followed by any "$" patterns using regex. - val regex = """(.*\$)?([^\$.\d]+(\$\d+)*)""".toRegex() - val matchResult = regex.matchEntire(withoutPackage) - return matchResult?.groups?.get(2)?.value ?: withoutPackage -} - -// Should be called only during `appendTrace` invocation -internal fun getObjectNumber(clazz: Class, obj: Any): Int = objectNumeration - .computeIfAbsent(clazz) { IdentityHashMap() } - .computeIfAbsent(obj) { 1 + objectNumeration[clazz]!!.size } - -private val objectNumeration = Collections.synchronizedMap(WeakHashMap, MutableMap>()) - const val TRACE_TITLE = "The following interleaving leads to the error:" const val DETAILED_TRACE_TITLE = "Detailed trace:" private const val ALL_UNFINISHED_THREADS_IN_DEADLOCK_MESSAGE = "All unfinished threads are in deadlock" - -internal fun cleanObjectNumeration() { - objectNumeration.clear() -} diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/UnsafeNames.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/UnsafeNames.kt new file mode 100644 index 000000000..90912729e --- /dev/null +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/UnsafeNames.kt @@ -0,0 +1,98 @@ +/* + * Lincheck + * + * Copyright (C) 2019 - 2024 JetBrains s.r.o. + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed + * with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.jetbrains.kotlinx.lincheck.strategy.managed + +import org.jetbrains.kotlinx.lincheck.findFieldNameByOffset +import org.jetbrains.kotlinx.lincheck.strategy.managed.UnsafeName.* +import org.jetbrains.kotlinx.lincheck.util.UnsafeHolder + +/** + * Helper object to provide the field name and the owner of the Unsafe method call. + * When the Unsafe method is called with a receiver or a class and the offset of the field, + * we extract the field name using it. + */ +internal object UnsafeNames { + + internal fun getMethodCallType(parameters: Array): UnsafeName { + if (parameters.size < 2) return TreatAsDefaultMethod + + val firstParameter = parameters[0] + val secondParameter = parameters[1] + if (secondParameter is Long) { + return if (firstParameter is Class<*>) { + // The First parameter is a Class object in case of static field access. + val fieldName = findFieldNameByOffset(firstParameter, secondParameter) + ?: return TreatAsDefaultMethod + UnsafeStaticMethod(firstParameter, fieldName, parameters.drop(2)) + } else if (firstParameter != null && firstParameter::class.java.isArray) { + // The First parameter is an Array in case of array cell access. + val unsafe = UnsafeHolder.UNSAFE + val arrayBaseOffset = unsafe.arrayBaseOffset(firstParameter::class.java) + val arrayIndexScale = unsafe.arrayIndexScale(firstParameter::class.java) + val index = (secondParameter - arrayBaseOffset) / arrayIndexScale + + UnsafeArrayMethod( + array = firstParameter, + index = index.toInt(), + parametersToPresent = parameters.drop(2) + ) + } else if (firstParameter != null) { + // Then is an instance method call. + val fieldName = findFieldNameByOffset(firstParameter::class.java, secondParameter) + ?: return TreatAsDefaultMethod + UnsafeInstanceMethod( + owner = firstParameter, + fieldName = fieldName, + parametersToPresent = parameters.drop(2) + ) + } else TreatAsDefaultMethod + } + + return TreatAsDefaultMethod + } +} + +/** + * Type of the Unsafe method call. + */ +internal sealed interface UnsafeName { + /** + * Field with name [fieldName] access method call of the [owner] object. + */ + data class UnsafeInstanceMethod( + val owner: Any, + val fieldName: String, + val parametersToPresent: List + ) : UnsafeName + + /** + * Static field with name [fieldName] access method call of the [clazz] class. + */ + data class UnsafeStaticMethod( + val clazz: Class<*>, + val fieldName: String, + val parametersToPresent: List + ) : UnsafeName + + /** + * Array [array] access method call by the index [index]. + */ + data class UnsafeArrayMethod( + val array: Any, + val index: Int, + val parametersToPresent: List + ) : UnsafeName + + /** + * Unrecognized Unsafe method call so we should present it 'as is'. + */ + data object TreatAsDefaultMethod : UnsafeName +} diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/VarHandleNames.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/VarHandleNames.kt new file mode 100644 index 000000000..5604b5498 --- /dev/null +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/VarHandleNames.kt @@ -0,0 +1,203 @@ +/* + * Lincheck + * + * Copyright (C) 2019 - 2024 JetBrains s.r.o. + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed + * with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.jetbrains.kotlinx.lincheck.strategy.managed + +import org.jetbrains.kotlinx.lincheck.findFieldNameByOffset +import org.jetbrains.kotlinx.lincheck.strategy.managed.VarHandleMethodType.* +import org.jetbrains.kotlinx.lincheck.util.readFieldViaUnsafe +import sun.misc.Unsafe +import java.lang.invoke.VarHandle +import java.lang.reflect.Field + +/** + * Helper object to provide the field name and the owner of the VarHandle method call. + */ +@Suppress("SameParameterValue") +internal object VarHandleNames { + + private val nameExtractors: List = listOf( + // Primitive VarHandles + instanceNameExtractor( + "java.lang.invoke.VarHandleInts\$FieldInstanceReadOnly", + "java.lang.invoke.VarHandleDoubles\$FieldInstanceReadOnly", + "java.lang.invoke.VarHandleLongs\$FieldInstanceReadOnly", + "java.lang.invoke.VarHandleFloats\$FieldInstanceReadOnly", + "java.lang.invoke.VarHandleBytes\$FieldInstanceReadOnly", + "java.lang.invoke.VarHandleShorts\$FieldInstanceReadOnly", + "java.lang.invoke.VarHandleChars\$FieldInstanceReadOnly", + "java.lang.invoke.VarHandleBooleans\$FieldInstanceReadOnly" + ), + staticNameExtractor( + "java.lang.invoke.VarHandleInts\$FieldStaticReadOnly", + "java.lang.invoke.VarHandleDoubles\$FieldStaticReadOnly", + "java.lang.invoke.VarHandleLongs\$FieldStaticReadOnly", + "java.lang.invoke.VarHandleFloats\$FieldStaticReadOnly", + "java.lang.invoke.VarHandleBytes\$FieldStaticReadOnly", + "java.lang.invoke.VarHandleShorts\$FieldStaticReadOnly", + "java.lang.invoke.VarHandleChars\$FieldStaticReadOnly", + "java.lang.invoke.VarHandleBooleans\$FieldStaticReadOnly", + ), + arrayNameExtractor( + "java.lang.invoke.VarHandleInts\$Array", + "java.lang.invoke.VarHandleDoubles\$Array", + "java.lang.invoke.VarHandleLongs\$Array", + "java.lang.invoke.VarHandleFloats\$Array", + "java.lang.invoke.VarHandleBytes\$Array", + "java.lang.invoke.VarHandleShorts\$Array", + "java.lang.invoke.VarHandleChars\$Array", + "java.lang.invoke.VarHandleBooleans\$Array", + ), + // Reference type VarHandle. + // Many options are present due to different class names in different JDKs. + listOfNotNull( + referenceExtractor( + "java.lang.invoke.VarHandleReferences\$FieldInstanceReadOnly", + "java.lang.invoke.VarHandleObjects\$FieldInstanceReadOnly", + factory = ::VarHandleInstanceNameExtractor + ), + referenceExtractor( + "java.lang.invoke.VarHandleReferences\$FieldStaticReadOnly", + "java.lang.invoke.VarHandleObjects\$FieldStaticReadOnly", + factory = ::VarHandleStaticNameExtractor + ), + referenceExtractor( + "java.lang.invoke.VarHandleReferences\$Array", + "java.lang.invoke.VarHandleObjects\$Array", + factory = ::VarHandeArrayNameExtractor + ) + ) + ).flatten() + + internal fun varHandleMethodType(varHandle: VarHandle, parameters: Array): VarHandleMethodType = runCatching { + return nameExtractors.firstOrNull { it.canExtract(varHandle) }?.getMethodType(varHandle, parameters) + ?: TreatAsDefaultMethod + }.getOrElse { exception -> + exception.printStackTrace() + TreatAsDefaultMethod + } + + private sealed class VarHandleNameExtractor(protected val varHandleClass: Class<*>) { + fun canExtract(varHandle: VarHandle): Boolean = varHandleClass.isInstance(varHandle) + abstract fun getMethodType(varHandle: VarHandle, parameters: Array): VarHandleMethodType + } + + /** + * [VarHandle] that controls instance field contain field with name + * `fieldOffset` with the offset of the field and `receiverType` with a [Class] of the owner. + * The strategy is to extract them and find the field name in the owner class using offset. + */ + private class VarHandleInstanceNameExtractor(varHandleClass: Class<*>) : VarHandleNameExtractor(varHandleClass) { + private val fieldOffsetField: Field = varHandleClass.getDeclaredField("fieldOffset") + private val receiverTypeField: Field = varHandleClass.getDeclaredField("receiverType") + + override fun getMethodType(varHandle: VarHandle, parameters: Array): VarHandleMethodType { + val ownerType = readFieldViaUnsafe(varHandle, receiverTypeField, Unsafe::getObject) as Class<*> + val fieldOffset = readFieldViaUnsafe(varHandle, fieldOffsetField, Unsafe::getLong) + val fieldName = findFieldNameByOffset(ownerType, fieldOffset) ?: return TreatAsDefaultMethod + val firstParameter = parameters.firstOrNull() ?: return TreatAsDefaultMethod + if (!ownerType.isInstance(firstParameter)) return TreatAsDefaultMethod + + return InstanceVarHandleMethod(firstParameter, fieldName, parameters.drop(1)) + } + } + + /** + * [VarHandle] that controls static field contain the field with name + * `fieldOffset` with the offset of the field and the field `base` with a [Class] of the owner. + * The strategy is to extract them and find the field name in the owner class using offset. + */ + private class VarHandleStaticNameExtractor(varHandleClass: Class<*>) : VarHandleNameExtractor(varHandleClass) { + private val fieldOffsetField: Field = varHandleClass.getDeclaredField("fieldOffset") + + private val receiverTypeField: Field = varHandleClass.getDeclaredField("base") + + override fun getMethodType(varHandle: VarHandle, parameters: Array): VarHandleMethodType { + val ownerType = readFieldViaUnsafe(varHandle, receiverTypeField, Unsafe::getObject) as Class<*> + val fieldOffset = readFieldViaUnsafe(varHandle, fieldOffsetField, Unsafe::getLong) + + val fieldName = findFieldNameByOffset(ownerType, fieldOffset) ?: return TreatAsDefaultMethod + + return StaticVarHandleMethod(ownerType, fieldName, parameters.toList()) + } + } + + /** + * [VarHandle] that controls an array receives the array as a first argument and the index as a second, + * so we just analyze the arguments and return the provided array and the index. + */ + private class VarHandeArrayNameExtractor(varHandleClass: Class<*>) : VarHandleNameExtractor(varHandleClass) { + override fun getMethodType(varHandle: VarHandle, parameters: Array): VarHandleMethodType { + if (parameters.size < 2) return TreatAsDefaultMethod + val firstParameter = parameters[0] ?: return TreatAsDefaultMethod + val index = parameters[1] as? Int ?: return TreatAsDefaultMethod + + return ArrayVarHandleMethod(firstParameter, index, parameters.drop(2)) + } + } + + // RunCatching because VarHandle class can be not found due to a java version. + private fun instanceNameExtractor(vararg varHandleClassNames: String) = + varHandleClassNames.mapNotNull { runCatching { VarHandleInstanceNameExtractor(Class.forName(it)) }.getOrNull() } + + // RunCatching because VarHandle class can be not found due to a java version. + private fun staticNameExtractor(vararg varHandleClassNames: String) = + varHandleClassNames.mapNotNull { runCatching { VarHandleStaticNameExtractor(Class.forName(it)) }.getOrNull() } + + // RunCatching because VarHandle class can be not found due to a java version. + private fun arrayNameExtractor(vararg varHandleClassNames: String) = + varHandleClassNames.mapNotNull { runCatching { VarHandeArrayNameExtractor(Class.forName(it)) }.getOrNull() } + + /** + * Creates [VarHandleNameExtractor] using the first successfully loaded classes from the [varHandleClassNames] list. + * + * For example, in JDK11 VarHandle for objects is located in `java.lang.invoke.VarHandleObjects`, + * while in JDK17 it's in the `java.lang.invoke.VarHandleReferences`. + */ + private inline fun referenceExtractor( + vararg varHandleClassNames: String, + factory: (Class<*>) -> VarHandleNameExtractor + ): VarHandleNameExtractor? { + for (className in varHandleClassNames) { + try { + val varHandleClass = Class.forName(className) + return factory(varHandleClass) + } catch (e: Exception) { continue } + } + return null + } +} + +/** + * Type of the [VarHandle] method call. + */ +internal sealed interface VarHandleMethodType { + /** + * Unrecognized [VarHandle] method call so we should present it 'as is'. + */ + data object TreatAsDefaultMethod : VarHandleMethodType + + /** + * Array cell access method call. + */ + data class ArrayVarHandleMethod(val array: Any, val index: Int, val parameters: List) : VarHandleMethodType + + /** + * Method call affecting field [fieldName] of the [owner]. + */ + data class InstanceVarHandleMethod(val owner: Any, val fieldName: String, val parameters: List) : + VarHandleMethodType + + /** + * Method call affecting static field [fieldName] of the [ownerClass]. + */ + data class StaticVarHandleMethod(val ownerClass: Class<*>, val fieldName: String, val parameters: List) : + VarHandleMethodType +} \ No newline at end of file diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/modelchecking/ModelCheckingStrategy.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/modelchecking/ModelCheckingStrategy.kt index 98b4f89d7..72cd23d17 100644 --- a/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/modelchecking/ModelCheckingStrategy.kt +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/modelchecking/ModelCheckingStrategy.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlinx.lincheck.execution.* import org.jetbrains.kotlinx.lincheck.runner.* import org.jetbrains.kotlinx.lincheck.strategy.* import org.jetbrains.kotlinx.lincheck.strategy.managed.* +import org.jetbrains.kotlinx.lincheck.strategy.managed.ObjectLabelFactory.cleanObjectNumeration import org.jetbrains.kotlinx.lincheck.verifier.* import java.lang.reflect.* import kotlin.random.* diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/transformation/LincheckClassVisitor.kt b/src/jvm/main/org/jetbrains/kotlinx/lincheck/transformation/LincheckClassVisitor.kt index e18188f9a..a3e8cfdc4 100644 --- a/src/jvm/main/org/jetbrains/kotlinx/lincheck/transformation/LincheckClassVisitor.kt +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/transformation/LincheckClassVisitor.kt @@ -952,84 +952,90 @@ internal class LincheckClassVisitor( code = { val argumentTypes = getArgumentTypes(desc) - if (argumentTypes.size == 3) { - // we are in a single value overload - val nextType = argumentTypes.last() - val nextValueLocal = newLocal(OBJECT_TYPE) - - val currentType = argumentTypes[argumentTypes.lastIndex - 1] - val currenValueLocal = newLocal(OBJECT_TYPE) - - val receiverLocal = newLocal(OBJECT_TYPE) - // STACK: nextValue, currentValue, receiver - box(nextType) - // STACK: boxedNextValue, currentValue, receiver - storeLocal(nextValueLocal) - // STACK: currentValue, receiver - box(currentType) - // STACK: boxedCurrentValue, receiver - storeLocal(currenValueLocal) - // STACK: receiver - storeLocal(receiverLocal) - // STACK: - loadLocal(receiverLocal) - // STACK: receiver - loadLocal(currenValueLocal) - // STACK: boxedCurrentValue, receiver - unbox(currentType) - // STACK: currentValue, receiver - loadLocal(nextValueLocal) - // STACK: boxedNextValue, currentValue, receiver - unbox(nextType) - // STACK: nextValue, currentValue, receiver - visitMethodInsn(opcode, owner, name, desc, itf) - loadLocal(receiverLocal) - // STACK: receiver - loadLocal(nextValueLocal) - // STACK: boxedNextValue, receiver - invokeStatic(Injections::onWriteToObjectFieldOrArrayCell) - } else { - // we are in an array version overload (with index) *.compareAndSet(index, currentValue, nextValue) - val nextType = argumentTypes.last() - val nextValueLocal = newLocal(OBJECT_TYPE) - - val currentType = argumentTypes[argumentTypes.lastIndex - 1] - val currenValueLocal = newLocal(OBJECT_TYPE) - - val indexLocal = newLocal(INT_TYPE) - val receiverLocal = newLocal(OBJECT_TYPE) - // STACK: nextValue, currentValue, index, receiver - box(nextType) - // STACK: boxedNextValue, currentValue, index, receiver - storeLocal(nextValueLocal) - // STACK: currentValue, index, receiver - box(currentType) - // STACK: boxedCurrentValue, index, receiver - storeLocal(currenValueLocal) - // STACK: index, receiver - storeLocal(indexLocal) - // STACK: receiver - storeLocal(receiverLocal) - // STACK: - loadLocal(receiverLocal) - // STACK: receiver - loadLocal(indexLocal) - // STACK: index, receiver - loadLocal(currenValueLocal) - // STACK: boxedCurrentValue, index, receiver - unbox(currentType) - // STACK: currentValue, index, receiver - loadLocal(nextValueLocal) - // STACK: boxedNextValue, currentValue, index, receiver - unbox(nextType) - // STACK: nextValue, currentValue, index, receiver - visitMethodInsn(opcode, owner, name, desc, itf) - // STACK: cas-result - loadLocal(receiverLocal) - // STACK: receiver, cas-result - loadLocal(nextValueLocal) - // STACK: boxedNextValue, receiver, cas-result - invokeStatic(Injections::onWriteToObjectFieldOrArrayCell) + when (argumentTypes.size) { + 3 -> { + // we are in a single value overload + val nextType = argumentTypes.last() + val nextValueLocal = newLocal(OBJECT_TYPE) + + val currentType = argumentTypes[argumentTypes.lastIndex - 1] + val currenValueLocal = newLocal(OBJECT_TYPE) + + val receiverLocal = newLocal(OBJECT_TYPE) + // STACK: nextValue, currentValue, receiver + box(nextType) + // STACK: boxedNextValue, currentValue, receiver + storeLocal(nextValueLocal) + // STACK: currentValue, receiver + box(currentType) + // STACK: boxedCurrentValue, receiver + storeLocal(currenValueLocal) + // STACK: receiver + storeLocal(receiverLocal) + // STACK: + loadLocal(receiverLocal) + // STACK: receiver + loadLocal(currenValueLocal) + // STACK: boxedCurrentValue, receiver + unbox(currentType) + // STACK: currentValue, receiver + loadLocal(nextValueLocal) + // STACK: boxedNextValue, currentValue, receiver + unbox(nextType) + // STACK: nextValue, currentValue, receiver + visitMethodInsn(opcode, owner, name, desc, itf) + loadLocal(receiverLocal) + // STACK: receiver + loadLocal(nextValueLocal) + // STACK: boxedNextValue, receiver + invokeStatic(Injections::onWriteToObjectFieldOrArrayCell) + } + 4 -> { + // we are in an array version overload (with index) *.compareAndSet(receiver, index, currentValue, nextValue) + val nextType = argumentTypes.last() + val nextValueLocal = newLocal(OBJECT_TYPE) + + val currentType = argumentTypes[argumentTypes.lastIndex - 1] + val currenValueLocal = newLocal(OBJECT_TYPE) + + val indexLocal = newLocal(INT_TYPE) + val receiverLocal = newLocal(OBJECT_TYPE) + // STACK: nextValue, currentValue, index, receiver + box(nextType) + // STACK: boxedNextValue, currentValue, index, receiver + storeLocal(nextValueLocal) + // STACK: currentValue, index, receiver + box(currentType) + // STACK: boxedCurrentValue, index, receiver + storeLocal(currenValueLocal) + // STACK: index, receiver + storeLocal(indexLocal) + // STACK: receiver + storeLocal(receiverLocal) + // STACK: + loadLocal(receiverLocal) + // STACK: receiver + loadLocal(indexLocal) + // STACK: index, receiver + loadLocal(currenValueLocal) + // STACK: boxedCurrentValue, index, receiver + unbox(currentType) + // STACK: currentValue, index, receiver + loadLocal(nextValueLocal) + // STACK: boxedNextValue, currentValue, index, receiver + unbox(nextType) + // STACK: nextValue, currentValue, index, receiver + visitMethodInsn(opcode, owner, name, desc, itf) + // STACK: cas-result + loadLocal(receiverLocal) + // STACK: receiver, cas-result + loadLocal(nextValueLocal) + // STACK: boxedNextValue, receiver, cas-result + invokeStatic(Injections::onWriteToObjectFieldOrArrayCell) + } + else -> { + visitMethodInsn(opcode, owner, name, desc, itf) + } } } ) @@ -1050,62 +1056,68 @@ internal class LincheckClassVisitor( code = { val argumentTypes = getArgumentTypes(desc) // we are in a single value overload - if (argumentTypes.size == 2) { - // STACK: value, receiver - val argumentType = argumentTypes.last() - val valueLocal = newLocal(OBJECT_TYPE) - val receiverLocal = newLocal(OBJECT_TYPE) - - // STACK: value, receiver - box(argumentType) - storeLocal(valueLocal) - // STACK: boxedValue, receiver - storeLocal(receiverLocal) - // STACK: - loadLocal(receiverLocal) - // STACK: receiver - loadLocal(valueLocal) - // STACK: boxedValue, receiver - unbox(argumentType) - // STACK: value, receiver - visitMethodInsn(opcode, owner, name, desc, itf) - // STACK: - loadLocal(receiverLocal) - // STACK: receiver - loadLocal(valueLocal) - // STACK: boxedValue, receiver - invokeStatic(Injections::onWriteToObjectFieldOrArrayCell) - } else { - // we are in an array version overload (with index) varHandle.set(value, index) - val argumentType = argumentTypes.last() - val valueLocal = newLocal(OBJECT_TYPE) - val indexLocal = newLocal(INT_TYPE) - val receiverLocal = newLocal(OBJECT_TYPE) - - // STACK: value, index, receiver - box(argumentType) - // STACK: boxedValue, index, receiver - storeLocal(valueLocal) - // STACK: index, receiver - storeLocal(indexLocal) - // STACK: receiver - storeLocal(receiverLocal) - // STACK: - loadLocal(receiverLocal) - // STACK: receiver - loadLocal(indexLocal) - // STACK: index, receiver - loadLocal(valueLocal) - // STACK: boxedValue, index, receiver - unbox(argumentType) - // STACK: value, index, receiver - visitMethodInsn(opcode, owner, name, desc, itf) - // STACK: - loadLocal(receiverLocal) - // STACK: receiver - loadLocal(valueLocal) - // STACK: boxedValue, receiver - invokeStatic(Injections::onWriteToObjectFieldOrArrayCell) + when (argumentTypes.size) { + 2 -> { + // STACK: value, receiver + val argumentType = argumentTypes.last() + val valueLocal = newLocal(OBJECT_TYPE) + val receiverLocal = newLocal(OBJECT_TYPE) + + // STACK: value, receiver + box(argumentType) + storeLocal(valueLocal) + // STACK: boxedValue, receiver + storeLocal(receiverLocal) + // STACK: + loadLocal(receiverLocal) + // STACK: receiver + loadLocal(valueLocal) + // STACK: boxedValue, receiver + unbox(argumentType) + // STACK: value, receiver + visitMethodInsn(opcode, owner, name, desc, itf) + // STACK: + loadLocal(receiverLocal) + // STACK: receiver + loadLocal(valueLocal) + // STACK: boxedValue, receiver + invokeStatic(Injections::onWriteToObjectFieldOrArrayCell) + } + 3 -> { + // we are in an array version overload (with index) varHandle.set(receiver, value, index) + val argumentType = argumentTypes.last() + val valueLocal = newLocal(OBJECT_TYPE) + val indexLocal = newLocal(INT_TYPE) + val receiverLocal = newLocal(OBJECT_TYPE) + + // STACK: value, index, receiver + box(argumentType) + // STACK: boxedValue, index, receiver + storeLocal(valueLocal) + // STACK: index, receiver + storeLocal(indexLocal) + // STACK: receiver + storeLocal(receiverLocal) + // STACK: + loadLocal(receiverLocal) + // STACK: receiver + loadLocal(indexLocal) + // STACK: index, receiver + loadLocal(valueLocal) + // STACK: boxedValue, index, receiver + unbox(argumentType) + // STACK: value, index, receiver + visitMethodInsn(opcode, owner, name, desc, itf) + // STACK: + loadLocal(receiverLocal) + // STACK: receiver + loadLocal(valueLocal) + // STACK: boxedValue, receiver + invokeStatic(Injections::onWriteToObjectFieldOrArrayCell) + } + else -> { + visitMethodInsn(opcode, owner, name, desc, itf) + } } } ) @@ -1318,10 +1330,20 @@ internal class LincheckClassVisitor( // the params list before creating a trace point to remove redundant parameters // as receiver and offset. // To determine how we should process it, we provide owner instance. + val isVarHandleOrAtomicReference = (owner == "java/lang/invoke/VarHandle" || + owner == "java/util/concurrent/atomic/AtomicLong" || + owner == "java/util/concurrent/atomic/AtomicInteger" || + owner == "java/util/concurrent/atomic/AtomicBoolean" || + (owner == "java/util/concurrent/atomic/AtomicReference") || + owner == "java/util/concurrent/atomic/AtomicReferenceArray" || + owner == "java/util/concurrent/atomic/AtomicIntegerArray" || + owner == "java/util/concurrent/atomic/AtomicLongArray") && name != "" val provideOwner = opcode != INVOKESTATIC && (owner.endsWith("FieldUpdater") || - owner == "sun/misc/Unsafe" || owner == "jdk/internal/misc/Unsafe" || - owner == "java/lang/invoke/VarHandle") + owner == "sun/misc/Unsafe" || + owner == "jdk/internal/misc/Unsafe" || + isVarHandleOrAtomicReference) + // STACK [INVOKEVIRTUAL]: owner, arguments // STACK [INVOKESTATIC]: arguments val argumentLocals = storeArguments(desc) @@ -1332,18 +1354,18 @@ internal class LincheckClassVisitor( } else { visitInsn(ACONST_NULL) } - // STACK [INVOKEVIRTUAL atomic updater]: owner, owner - // STACK [INVOKESTATIC atomic updater]: , null - - // STACK [INVOKEVIRTUAL atomic]: owner, ownerName - // STACK [INVOKESTATIC atomic]: , ownerName + // STACK [INVOKEVIRTUAL]: owner, owner + // STACK [INVOKESTATIC]: , null + push(owner) + // STACK [INVOKEVIRTUAL]: owner, owner, className + // STACK [INVOKESTATIC]: null, className, push(name) loadNewCodeLocationId() - // STACK [INVOKEVIRTUAL atomic updater]: owner, owner, methodName, codeLocation - // STACK [INVOKESTATIC atomic updater]: null, methodName, codeLocation + // STACK [INVOKEVIRTUAL]: owner, owner, className, methodName, codeLocation + // STACK [INVOKESTATIC]: null, className, methodName, codeLocation - // STACK [INVOKEVIRTUAL atomic]: owner, ownerName, methodName, codeLocation - // STACK [INVOKESTATIC atomic]: ownerName, methodName, codeLocation + // STACK [INVOKEVIRTUAL]: owner, ownerName, className, methodName, codeLocation + // STACK [INVOKESTATIC]: ownerName, className, methodName, codeLocation val argumentTypes = getArgumentTypes(desc) push(argumentLocals.size) // size of the array diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/AtomicReferencesNamesTests.kt b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/AtomicReferencesNamesTests.kt new file mode 100644 index 000000000..2e3a6e682 --- /dev/null +++ b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/AtomicReferencesNamesTests.kt @@ -0,0 +1,105 @@ +/* + * Lincheck + * + * Copyright (C) 2019 - 2024 JetBrains s.r.o. + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed + * with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.jetbrains.kotlinx.lincheck_test.representation + +import java.util.concurrent.atomic.* + +class AtomicReferencesNamesTest : BaseFailingTest("atomic_references_names_trace.txt") { + + private var atomicReference = AtomicReference(Node(1)) + private var atomicInteger = AtomicInteger(0) + private var atomicLong = AtomicLong(0L) + private var atomicBoolean = AtomicBoolean(true) + + private var atomicReferenceArray = AtomicReferenceArray(arrayOf(Node(1))) + private var atomicIntegerArray = AtomicIntegerArray(intArrayOf(0)) + private var atomicLongArray = AtomicLongArray(longArrayOf(0L)) + + private var wrapper = AtomicReferenceWrapper() + + override fun actionsForTrace() { + atomicReference.compareAndSet(atomicReference.get(), Node(2)) + atomicReference.set(Node(3)) + + atomicInteger.compareAndSet(atomicInteger.get(), 2) + atomicInteger.set(3) + + atomicLong.compareAndSet(atomicLong.get(), 2) + atomicLong.set(3) + + atomicBoolean.compareAndSet(atomicBoolean.get(), true) + atomicBoolean.set(false) + + atomicReferenceArray.compareAndSet(0, atomicReferenceArray.get(0), Node(2)) + atomicReferenceArray.set(0, Node(3)) + + atomicIntegerArray.compareAndSet(0, atomicIntegerArray.get(0), 1) + atomicIntegerArray.set(0, 2) + + atomicLongArray.compareAndSet(0, atomicLongArray.get(0), 1) + atomicLongArray.set(0, 2) + + wrapper.reference.set(Node(5)) + wrapper.array.length() + wrapper.array.compareAndSet(0, 1 ,2) + + staticValue.compareAndSet(0, 2) + staticValue.set(0) + + AtomicReferenceWrapper.staticValue.compareAndSet(1, 2) + AtomicReferenceWrapper.staticValue.set(3) + + staticArray.compareAndSet(1, 0, 1) + AtomicReferenceWrapper.staticArray.compareAndSet(1, 0, 1) + } + + private data class Node(val name: Int) + + private class AtomicReferenceWrapper { + val reference = AtomicReference(Node(0)) + val array = AtomicIntegerArray(10) + + companion object { + @JvmStatic + val staticValue = AtomicInteger(1) + @JvmStatic + val staticArray = AtomicIntegerArray(3) + } + } + + companion object { + @JvmStatic + private val staticValue = AtomicInteger(0) + @JvmStatic + val staticArray = AtomicIntegerArray(3) + } +} + +class AtomicReferencesFromMultipleFieldsTest : BaseFailingTest("atomic_references_name_two_fields_trace.txt") { + + private var atomicReference1: AtomicReference + private var atomicReference2: AtomicReference + + init { + val ref = AtomicReference(Node(1)) + atomicReference1 = ref + atomicReference2 = ref + } + + override fun actionsForTrace() { + atomicReference1.compareAndSet(atomicReference2.get(), Node(2)) + } + + private data class Node(val name: Int) + +} + + diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/BaseFailingTest.kt b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/BaseFailingTest.kt new file mode 100644 index 000000000..faab27697 --- /dev/null +++ b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/BaseFailingTest.kt @@ -0,0 +1,50 @@ +/* + * Lincheck + * + * Copyright (C) 2019 - 2024 JetBrains s.r.o. + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed + * with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.jetbrains.kotlinx.lincheck_test.representation + +import org.jetbrains.kotlinx.lincheck.annotations.Operation +import org.jetbrains.kotlinx.lincheck.checkImpl +import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.ModelCheckingOptions +import org.jetbrains.kotlinx.lincheck_test.util.checkLincheckOutput +import org.junit.Test + +/** + * Failing test that checks that output using [outputFileName]. + * The goal is to place the logic to check trace in the [actionsForTrace] method. + */ +abstract class BaseFailingTest(private val outputFileName: String) { + + @Volatile + private var counter: Int = 0 + + @Operation + fun increment(): Int { + val result = counter++ + actionsForTrace() + return result + } + + /** + * Implement me and place the logic to check its trace. + */ + abstract fun actionsForTrace() + + @Test + fun test() = ModelCheckingOptions() + .addCustomScenario { + parallel { + thread { actor(::increment) } + } + } + .checkImpl(this::class.java) + .checkLincheckOutput(outputFileName) + +} \ No newline at end of file diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/OwnerNameInTraceRepresentationTests.kt b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/OwnerNameInTraceRepresentationTests.kt new file mode 100644 index 000000000..00467a257 --- /dev/null +++ b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/OwnerNameInTraceRepresentationTests.kt @@ -0,0 +1,97 @@ +/* + * Lincheck + * + * Copyright (C) 2019 - 2024 JetBrains s.r.o. + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed + * with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.jetbrains.kotlinx.lincheck_test.representation + +class OwnerNameInTraceRepresentationTest : BaseFailingTest("owner_name_in_trace.txt") { + + @Volatile + private var value: Int = 1 + + @Volatile + private var stub = StubClass() + private val array: Array = arrayOf(0) + + + override fun actionsForTrace() { + readWriteTestMethod() + val result = stub + result.readWriteTestMethod() + doReadWriteWithOtherObject() + } + + private fun readWriteTestMethod(): Int { + value = 2 + array[0] = 4 + return value + array[0] + } + + private fun doReadWriteWithOtherObject(): Int { + stub.value = 2 + stub.array[0] = 4 + return stub.value + stub.array[0] + } + + class StubClass { + @Volatile + @JvmField + var value: Int = 1 + val array: Array = arrayOf(1) + + fun readWriteTestMethod(): Int { + value = 3 + array[0] = 4 + return value + array[0] + } + } +} + +class ArrayNameInTraceRepresentationTest : BaseFailingTest("array_name_in_trace.txt") { + + private var intArray: IntArray = intArrayOf(1) + private var shortArray: ShortArray = shortArrayOf(1) + private var charArray: CharArray = charArrayOf('1') + private var byteArray: ByteArray = byteArrayOf(1) + private var booleanArray: BooleanArray = booleanArrayOf(true) + + private val floatArray: FloatArray = floatArrayOf(1.0f) + private val doubleArray: DoubleArray = doubleArrayOf(1.0) + private val longArray: LongArray = longArrayOf(1L) + + override fun actionsForTrace() { + readActions() + writeActions() + } + + private fun readActions() { + intArray[0] + shortArray[0] + charArray[0] + byteArray[0] + booleanArray[0] + + floatArray[0] + doubleArray[0] + longArray[0] + } + + private fun writeActions() { + intArray[0] = 0 + shortArray[0] = 0 + charArray[0] = '0' + byteArray[0] = 0 + booleanArray[0] = false + + floatArray[0] = 0f + doubleArray[0] = 0.0 + longArray[0] = 0L + } + +} \ No newline at end of file diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/UnsafeTraceRepresentationTest.kt b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/UnsafeTraceRepresentationTest.kt new file mode 100644 index 000000000..929509bab --- /dev/null +++ b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/UnsafeTraceRepresentationTest.kt @@ -0,0 +1,54 @@ +/* + * Lincheck + * + * Copyright (C) 2019 - 2024 JetBrains s.r.o. + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed + * with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.jetbrains.kotlinx.lincheck_test.representation + +import org.jetbrains.kotlinx.lincheck.util.UnsafeHolder + + +class UnsafeTraceRepresentationTest : BaseFailingTest("unsafe_representation_trace.txt") { + + private val array = Array(3) { IntWrapper(it) } + private var value: Int = 2 + private val node = IntWrapper(3) + + override fun actionsForTrace() { + unsafe.getObject(array, baseOffset + indexScale * 2L) + unsafe.compareAndSwapObject(this, nodeFieldOffset, node, IntWrapper(4)) + unsafe.compareAndSwapInt(this, valueFieldOffset, value, 3) + + unsafe.compareAndSwapObject(staticNodeFieldBase, staticNodeFieldOffset, staticNode, IntWrapper(6)) + unsafe.compareAndSwapInt(node, nodeValueOffset, node.value, 6) + } + + private data class IntWrapper(val value: Int) + + companion object { + val unsafe = UnsafeHolder.UNSAFE + + private val nodeField = UnsafeTraceRepresentationTest::class.java.getDeclaredField("node") + private val staticNodeField = UnsafeTraceRepresentationTest::class.java.getDeclaredField("staticNode") + private val valueField = UnsafeTraceRepresentationTest::class.java.getDeclaredField("value") + private val nodeValueField = IntWrapper::class.java.getDeclaredField("value") + + private val baseOffset: Int = unsafe.arrayBaseOffset(Array::class.java) + private val indexScale: Int = unsafe.arrayIndexScale(Array::class.java) + + private val nodeFieldOffset = unsafe.objectFieldOffset(nodeField) + private val staticNodeFieldOffset = unsafe.staticFieldOffset(staticNodeField) + private val staticNodeFieldBase = unsafe.staticFieldBase(staticNodeField) + private val valueFieldOffset = unsafe.objectFieldOffset(valueField) + private val nodeValueOffset = unsafe.objectFieldOffset(nodeValueField) + + @JvmStatic + private val staticNode = IntWrapper(5) + } + +} \ No newline at end of file diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/UnsafeUpdaterVarHandleTraceRepresentationTests.kt b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/UnsafeUpdaterVarHandleTraceRepresentationTests.kt index 8b008b8f0..d08183ab3 100644 --- a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/UnsafeUpdaterVarHandleTraceRepresentationTests.kt +++ b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/UnsafeUpdaterVarHandleTraceRepresentationTests.kt @@ -16,8 +16,6 @@ import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.ModelChecki import org.jetbrains.kotlinx.lincheck_test.util.checkLincheckOutput import org.junit.Test import sun.misc.Unsafe -import java.lang.invoke.MethodHandles -import java.lang.invoke.VarHandle import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicReferenceFieldUpdater @@ -27,7 +25,7 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater class SunUnsafeTraceRepresentationTest { @Volatile - private var node: Node = Node(1) + private var node: IntWrapper = IntWrapper(1) @Volatile private var counter: Int = 0 @@ -50,8 +48,8 @@ class SunUnsafeTraceRepresentationTest { .checkLincheckOutput("sun_unsafe_trace.txt") private fun actionsJustForTrace() { - unsafe.compareAndSwapObject(this, offset, node, Node(2)) - unsafe.getAndSetObject(this, offset, Node(3)) + unsafe.compareAndSwapObject(this, offset, node, IntWrapper(2)) + unsafe.getAndSetObject(this, offset, IntWrapper(3)) } companion object { @@ -72,9 +70,6 @@ class SunUnsafeTraceRepresentationTest { */ class JdkUnsafeTraceRepresentationTest { - @Volatile - private var node: Node = Node(1) - @Volatile private var counter: Int = 0 // We use it just to interact with jdk.internal.misc.Unsafe, which we cannot access directly. @@ -101,18 +96,6 @@ class JdkUnsafeTraceRepresentationTest { // Here under the hood we interact with the Unsafe instance. hashMap[1] = 2 } - - companion object { - val unsafe: Unsafe = try { - val unsafeField = Unsafe::class.java.getDeclaredField("theUnsafe") - unsafeField.isAccessible = true - unsafeField.get(null) as Unsafe - } catch (ex: Exception) { - throw RuntimeException(ex) - } - val offset = - unsafe.objectFieldOffset(SunUnsafeTraceRepresentationTest::class.java.getDeclaredField("node")) - } } /** @@ -122,7 +105,7 @@ class JdkUnsafeTraceRepresentationTest { class AtomicUpdaterTraceRepresentationTest { @Volatile - private var node: Node = Node(1) + private var node: IntWrapper = IntWrapper(1) @Volatile private var counter: Int = 0 @@ -145,59 +128,18 @@ class AtomicUpdaterTraceRepresentationTest { .checkLincheckOutput("atomic_updater_trace.txt") private fun actionsJustForTrace() { - nodeUpdater.compareAndSet(this, node, Node(4)) - nodeUpdater.set(this, Node(5)) + nodeUpdater.compareAndSet(this, node, IntWrapper(4)) + nodeUpdater.set(this, IntWrapper(5)) } companion object { - val nodeUpdater: AtomicReferenceFieldUpdater = + val nodeUpdater: AtomicReferenceFieldUpdater = AtomicReferenceFieldUpdater.newUpdater( AtomicUpdaterTraceRepresentationTest::class.java, - Node::class.java, + IntWrapper::class.java, "node" ) } } -/** - * Test checks that in case of a field update using VarHandle we remove receiver argument from the trace. - */ -class VarHandleTraceRepresentationTest { - - @Volatile - private var node: Node = Node(1) - - @Volatile - private var counter: Int = 0 - - @Operation - fun increment(): Int { - val result = counter++ - actionsJustForTrace() - return result - } - - @Test - fun test() = ModelCheckingOptions() - .addCustomScenario { - parallel { - thread { actor(::increment) } - } - } - .checkImpl(this::class.java) - .checkLincheckOutput("varhandle_trace.txt") - - private fun actionsJustForTrace() { - nodeHandle.compareAndSet(this, node, Node(6)) - nodeHandle.set(this, Node(7)) - } - - companion object { - val nodeHandle: VarHandle = MethodHandles.lookup() - .`in`(VarHandleTraceRepresentationTest::class.java) - .findVarHandle(VarHandleTraceRepresentationTest::class.java, "node", Node::class.java) - - } -} - -data class Node(val value: Int) \ No newline at end of file +data class IntWrapper(val value: Int) \ No newline at end of file diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/VarHandleRepresentationTests.kt b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/VarHandleRepresentationTests.kt new file mode 100644 index 000000000..741d57b84 --- /dev/null +++ b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/VarHandleRepresentationTests.kt @@ -0,0 +1,353 @@ +/* + * Lincheck + * + * Copyright (C) 2019 - 2024 JetBrains s.r.o. + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed + * with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.jetbrains.kotlinx.lincheck_test.representation + +import java.lang.invoke.MethodHandles +import java.lang.invoke.VarHandle + +class VarHandleReferenceRepresentationTest : BaseFailingTest("var_handle/varhandle_reference_representation.txt") { + + @Volatile + private var wrapper = IntWrapper(1) + private var array = Array(10) { IntWrapper(it) } + private val valueWrapper = Wrapper() + + override fun actionsForTrace() { + // Instance object field operation. + nodeHandle.compareAndSet(this, wrapper, IntWrapper(2)) + nodeHandle.set(this, IntWrapper(3)) + // Static object field operation. + staticNodeHandle.compareAndSet(wrapper, IntWrapper(2)) + staticNodeHandle.set(IntWrapper(3)) + // Array object field operation. + nodeArrayHandle.compareAndSet(array, 1, IntWrapper(1), IntWrapper(2)) + nodeArrayHandle.set(array, 1, IntWrapper(1)) + // Another object field operation. + wrapperValueHandle.compareAndSet(valueWrapper, 1, 2) + wrapperValueHandle.set(valueWrapper, 3) + } + + class Wrapper { + @Volatile + @JvmField + var value: Int = 1 + } + + companion object { + @Suppress("unused") + @Volatile + @JvmStatic + private var staticWrapper = IntWrapper(1) + + val nodeHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleReferenceRepresentationTest::class.java) + .findVarHandle(VarHandleReferenceRepresentationTest::class.java, "wrapper", IntWrapper::class.java) + val staticNodeHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleReferenceRepresentationTest::class.java) + .findStaticVarHandle(VarHandleReferenceRepresentationTest::class.java, "staticWrapper", IntWrapper::class.java) + val nodeArrayHandle: VarHandle = MethodHandles.arrayElementVarHandle(Array::class.java) + val wrapperValueHandle: VarHandle = MethodHandles.lookup() + .`in`(Wrapper::class.java) + .findVarHandle(Wrapper::class.java, "value", Int::class.java) + } +} + +class VarHandleIntRepresentationTest : BaseFailingTest("var_handle/varhandle_int_representation.txt") { + + @Volatile + private var number: Int = 1 + private var array = IntArray(10) { it } + + override fun actionsForTrace() { + numberHandle.compareAndSet(this, number, 2) + numberHandle.set(this, 3) + + staticNumberHandle.compareAndSet(staticNumber, 2) + staticNumberHandle.set(3) + + arrayHandle.compareAndSet(array, 1, 1, 1) + arrayHandle.set(array, 1, 1) + } + + companion object { + + @Volatile + @JvmStatic + private var staticNumber: Int = 1 + + val numberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleIntRepresentationTest::class.java) + .findVarHandle(VarHandleIntRepresentationTest::class.java, "number", Int::class.java) + + val staticNumberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleIntRepresentationTest::class.java) + .findStaticVarHandle(VarHandleIntRepresentationTest::class.java, "staticNumber", Int::class.java) + + val arrayHandle: VarHandle = MethodHandles.arrayElementVarHandle(IntArray::class.java) + } +} + +class VarHandleShortRepresentationTest : BaseFailingTest("var_handle/varhandle_short_representation.txt") { + + @Volatile + private var number: Short = (1).toShort() + private var array = ShortArray(10) { it.toShort() } + + override fun actionsForTrace() { + numberHandle.compareAndSet(this, number, (1).toShort()) + numberHandle.set(this, (2).toShort()) + + staticNumberHandle.compareAndSet(staticNumber, (1).toShort()) + staticNumberHandle.set((3).toShort()) + + arrayHandle.compareAndSet(array, 1, (3).toShort(), (1).toShort()) + arrayHandle.set(array, 1, (2).toShort()) + } + + companion object { + + @Volatile + @JvmStatic + private var staticNumber: Short = (2).toShort() + + val numberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleShortRepresentationTest::class.java) + .findVarHandle(VarHandleShortRepresentationTest::class.java, "number", Short::class.java) + + val staticNumberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleShortRepresentationTest::class.java) + .findStaticVarHandle(VarHandleShortRepresentationTest::class.java, "staticNumber", Short::class.java) + + val arrayHandle: VarHandle = MethodHandles.arrayElementVarHandle(ShortArray::class.java) + } +} + + + +class VarHandleByteRepresentationTest : BaseFailingTest("var_handle/varhandle_byte_representation.txt") { + + @Volatile + private var number: Byte = (1).toByte() + private var array = ByteArray(10) { it.toByte() } + + override fun actionsForTrace() { + numberHandle.compareAndSet(this, number, (1).toByte()) + numberHandle.set(this, (2).toByte()) + + staticNumberHandle.compareAndSet(staticNumber, (1).toByte()) + staticNumberHandle.set((3).toByte()) + + arrayHandle.compareAndSet(array, 1, (3).toByte(), (1).toByte()) + arrayHandle.set(array, 1, (2).toByte()) + } + + companion object { + + @Volatile + @JvmStatic + private var staticNumber: Byte = (2).toByte() + + val numberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleByteRepresentationTest::class.java) + .findVarHandle(VarHandleByteRepresentationTest::class.java, "number", Byte::class.java) + + val staticNumberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleByteRepresentationTest::class.java) + .findStaticVarHandle(VarHandleByteRepresentationTest::class.java, "staticNumber", Byte::class.java) + + val arrayHandle: VarHandle = MethodHandles.arrayElementVarHandle(ByteArray::class.java) + } +} + + + +class VarHandleCharRepresentationTest : BaseFailingTest("var_handle/varhandle_char_representation.txt") { + + @Volatile + private var number: Char = '1' + private var array = CharArray(10) { it.toChar() } + + override fun actionsForTrace() { + numberHandle.compareAndSet(this, number, '1') + numberHandle.set(this, '2') + + staticNumberHandle.compareAndSet(staticNumber, '1') + staticNumberHandle.set('3') + + arrayHandle.compareAndSet(array, 1, '3', '1') + arrayHandle.set(array, 1, '2') + } + + companion object { + + @Volatile + @JvmStatic + private var staticNumber: Char = '2' + + val numberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleCharRepresentationTest::class.java) + .findVarHandle(VarHandleCharRepresentationTest::class.java, "number", Char::class.java) + + val staticNumberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleCharRepresentationTest::class.java) + .findStaticVarHandle(VarHandleCharRepresentationTest::class.java, "staticNumber", Char::class.java) + + val arrayHandle: VarHandle = MethodHandles.arrayElementVarHandle(CharArray::class.java) + } +} + + + +class VarHandleBooleanRepresentationTest : BaseFailingTest("var_handle/varhandle_boolean_representation.txt") { + + @Volatile + private var number: Boolean = false + private var array = BooleanArray(10) { false } + + override fun actionsForTrace() { + numberHandle.compareAndSet(this, number, false) + numberHandle.set(this, true) + + staticNumberHandle.compareAndSet(staticNumber, false) + staticNumberHandle.set(false) + + arrayHandle.compareAndSet(array, 1, false, false) + arrayHandle.set(array, 1, true) + } + + companion object { + + @Volatile + @JvmStatic + private var staticNumber: Boolean = true + + val numberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleBooleanRepresentationTest::class.java) + .findVarHandle(VarHandleBooleanRepresentationTest::class.java, "number", Boolean::class.java) + + val staticNumberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleBooleanRepresentationTest::class.java) + .findStaticVarHandle(VarHandleBooleanRepresentationTest::class.java, "staticNumber", Boolean::class.java) + + val arrayHandle: VarHandle = MethodHandles.arrayElementVarHandle(BooleanArray::class.java) + } +} + + + +class VarHandleLongRepresentationTest : BaseFailingTest("var_handle/varhandle_long_representation.txt") { + + @Volatile + private var number: Long = 1L + private var array = LongArray(10) { it.toLong() } + + override fun actionsForTrace() { + numberHandle.compareAndSet(this, number, 1L) + numberHandle.set(this, 2L) + + staticNumberHandle.compareAndSet(staticNumber, 1L) + staticNumberHandle.set(3L) + + arrayHandle.compareAndSet(array, 1, 3L, 1L) + arrayHandle.set(array, 1, 2L) + } + + companion object { + + @Volatile + @JvmStatic + private var staticNumber: Long = 2L + + val numberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleLongRepresentationTest::class.java) + .findVarHandle(VarHandleLongRepresentationTest::class.java, "number", Long::class.java) + + val staticNumberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleLongRepresentationTest::class.java) + .findStaticVarHandle(VarHandleLongRepresentationTest::class.java, "staticNumber", Long::class.java) + + val arrayHandle: VarHandle = MethodHandles.arrayElementVarHandle(LongArray::class.java) + } +} + + + +class VarHandleFloatRepresentationTest : BaseFailingTest("var_handle/varhandle_float_representation.txt") { + + @Volatile + private var number: Float = 1f + private var array = FloatArray(10) { it.toFloat() } + + override fun actionsForTrace() { + numberHandle.compareAndSet(this, number, 1f) + numberHandle.set(this, 2f) + + staticNumberHandle.compareAndSet(staticNumber, 1f) + staticNumberHandle.set(3f) + + arrayHandle.compareAndSet(array, 1, 3f, 1f) + arrayHandle.set(array, 1, 2f) + } + + companion object { + + @Volatile + @JvmStatic + private var staticNumber: Float = 2f + + val numberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleFloatRepresentationTest::class.java) + .findVarHandle(VarHandleFloatRepresentationTest::class.java, "number", Float::class.java) + + val staticNumberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleFloatRepresentationTest::class.java) + .findStaticVarHandle(VarHandleFloatRepresentationTest::class.java, "staticNumber", Float::class.java) + + val arrayHandle: VarHandle = MethodHandles.arrayElementVarHandle(FloatArray::class.java) + } +} + + + +class VarHandleDoubleRepresentationTest : BaseFailingTest("var_handle/varhandle_double_representation.txt") { + + @Volatile + private var number: Double = 1.0 + private var array = DoubleArray(10) { it.toDouble() } + + override fun actionsForTrace() { + numberHandle.compareAndSet(this, number, 1.0) + numberHandle.set(this, 2.0) + + staticNumberHandle.compareAndSet(staticNumber, 1.0) + staticNumberHandle.set(3.0) + + arrayHandle.compareAndSet(array, 1, 3.0, 1.0) + arrayHandle.set(array, 1, 2.0) + } + + companion object { + + @Volatile + @JvmStatic + private var staticNumber: Double = 2.0 + + val numberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleDoubleRepresentationTest::class.java) + .findVarHandle(VarHandleDoubleRepresentationTest::class.java, "number", Double::class.java) + + val staticNumberHandle: VarHandle = MethodHandles.lookup() + .`in`(VarHandleDoubleRepresentationTest::class.java) + .findStaticVarHandle(VarHandleDoubleRepresentationTest::class.java, "staticNumber", Double::class.java) + + val arrayHandle: VarHandle = MethodHandles.arrayElementVarHandle(DoubleArray::class.java) + } +} \ No newline at end of file diff --git a/src/jvm/test/resources/expected_logs/array_name_in_trace.txt b/src/jvm/test/resources/expected_logs/array_name_in_trace.txt new file mode 100644 index 000000000..8c3e890f6 --- /dev/null +++ b/src/jvm/test/resources/expected_logs/array_name_in_trace.txt @@ -0,0 +1,92 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| readActions() at ArrayNameInTraceRepresentationTest.actionsForTrace(OwnerNameInTraceRepresentationTests.kt:69) | | +| intArray.READ: IntArray#1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:74) | | +| IntArray#1[0].READ: 1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:74) | | +| shortArray.READ: ShortArray#1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:75) | | +| ShortArray#1[0].READ: 1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:75) | | +| charArray.READ: CharArray#1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:76) | | +| CharArray#1[0].READ: 1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:76) | | +| byteArray.READ: ByteArray#1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:77) | | +| ByteArray#1[0].READ: true at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:77) | | +| booleanArray.READ: BooleanArray#1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:78) | | +| BooleanArray#1[0].READ: true at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:78) | | +| FloatArray#1[0].READ: 1.0 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:80) | | +| DoubleArray#1[0].READ: 1.0 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:81) | | +| LongArray#1[0].READ: 1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:82) | | +| writeActions() at ArrayNameInTraceRepresentationTest.actionsForTrace(OwnerNameInTraceRepresentationTests.kt:70) | | +| intArray.READ: IntArray#1 at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:86) | | +| IntArray#1[0].WRITE(0) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:86) | | +| shortArray.READ: ShortArray#1 at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:87) | | +| ShortArray#1[0].WRITE(0) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:87) | | +| charArray.READ: CharArray#1 at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:88) | | +| CharArray#1[0].WRITE(0) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:88) | | +| byteArray.READ: ByteArray#1 at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:89) | | +| ByteArray#1[0].WRITE(false) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:89) | | +| booleanArray.READ: BooleanArray#1 at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:90) | | +| BooleanArray#1[0].WRITE(false) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:90) | | +| FloatArray#1[0].WRITE(0.0) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:92) | | +| DoubleArray#1[0].WRITE(0.0) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:93) | | +| LongArray#1[0].WRITE(0) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:94) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | readActions() at ArrayNameInTraceRepresentationTest.actionsForTrace(OwnerNameInTraceRepresentationTests.kt:69) | +| | intArray.READ: IntArray#1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:74) | +| | IntArray#1[0].READ: 0 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:74) | +| | shortArray.READ: ShortArray#1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:75) | +| | ShortArray#1[0].READ: 0 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:75) | +| | charArray.READ: CharArray#1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:76) | +| | CharArray#1[0].READ: 0 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:76) | +| | byteArray.READ: ByteArray#1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:77) | +| | ByteArray#1[0].READ: false at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:77) | +| | booleanArray.READ: BooleanArray#1 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:78) | +| | BooleanArray#1[0].READ: false at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:78) | +| | FloatArray#1[0].READ: 0.0 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:80) | +| | DoubleArray#1[0].READ: 0.0 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:81) | +| | LongArray#1[0].READ: 0 at ArrayNameInTraceRepresentationTest.readActions(OwnerNameInTraceRepresentationTests.kt:82) | +| | writeActions() at ArrayNameInTraceRepresentationTest.actionsForTrace(OwnerNameInTraceRepresentationTests.kt:70) | +| | intArray.READ: IntArray#1 at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:86) | +| | IntArray#1[0].WRITE(0) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:86) | +| | shortArray.READ: ShortArray#1 at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:87) | +| | ShortArray#1[0].WRITE(0) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:87) | +| | charArray.READ: CharArray#1 at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:88) | +| | CharArray#1[0].WRITE(0) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:88) | +| | byteArray.READ: ByteArray#1 at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:89) | +| | ByteArray#1[0].WRITE(false) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:89) | +| | booleanArray.READ: BooleanArray#1 at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:90) | +| | BooleanArray#1[0].WRITE(false) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:90) | +| | FloatArray#1[0].WRITE(0.0) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:92) | +| | DoubleArray#1[0].WRITE(0.0) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:93) | +| | LongArray#1[0].WRITE(0) at ArrayNameInTraceRepresentationTest.writeActions(OwnerNameInTraceRepresentationTests.kt:94) | +| | result: 0 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/array_read_write.txt b/src/jvm/test/resources/expected_logs/array_read_write.txt index 47ba6f006..ce74a40a5 100644 --- a/src/jvm/test/resources/expected_logs/array_read_write.txt +++ b/src/jvm/test/resources/expected_logs/array_read_write.txt @@ -6,37 +6,37 @@ | ------------------------------- | The following interleaving leads to the error: -| -------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| -------------------------------------------------------------------------------------------------------------------------- | -| | increment(): 0 | -| | Array[0].READ: 0 at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:26) | -| | Array[0].WRITE(1) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:27) | -| | counter.READ: 0 at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:28) | -| | switch | -| increment(): 0 | | -| | counter.WRITE(1) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:28) | -| | Array[1].WRITE(0) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:29) | -| | result: 0 | -| -------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | IntArray#1[0].READ: 0 at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:30) | +| | IntArray#1[0].WRITE(1) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:31) | +| | counter.READ: 0 at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:32) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:32) | +| | IntArray#1[1].WRITE(0) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:33) | +| | result: 0 | +| ------------------------------------------------------------------------------------------------------------------------------- | Detailed trace: -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | increment(): 0 | -| | Array[0].READ: 0 at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:26) | -| | Array[0].WRITE(1) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:27) | -| | counter.READ: 0 at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:28) | -| | switch | -| increment(): 0 | | -| Array[0].READ: 1 at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:26) | | -| Array[0].WRITE(2) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:27) | | -| counter.READ: 0 at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:28) | | -| counter.WRITE(1) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:28) | | -| Array[1].WRITE(0) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:29) | | -| result: 0 | | -| | counter.WRITE(1) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:28) | -| | Array[1].WRITE(0) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:29) | -| | result: 0 | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | IntArray#1[0].READ: 0 at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:30) | +| | IntArray#1[0].WRITE(1) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:31) | +| | counter.READ: 0 at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:32) | +| | switch | +| increment(): 0 | | +| IntArray#1[0].READ: 1 at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:30) | | +| IntArray#1[0].WRITE(2) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:31) | | +| counter.READ: 0 at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:32) | | +| counter.WRITE(1) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:32) | | +| IntArray#1[1].WRITE(0) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:33) | | +| result: 0 | | +| | counter.WRITE(1) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:32) | +| | IntArray#1[1].WRITE(0) at ArrayReadWriteRepresentationTest.increment(ArrayReadWriteRepresentationTest.kt:33) | +| | result: 0 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/atomic_references_name_two_fields_trace.txt b/src/jvm/test/resources/expected_logs/atomic_references_name_two_fields_trace.txt new file mode 100644 index 000000000..7e7bfd0ae --- /dev/null +++ b/src/jvm/test/resources/expected_logs/atomic_references_name_two_fields_trace.txt @@ -0,0 +1,44 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| atomicReference1.READ: AtomicReference#1 at AtomicReferencesFromMultipleFieldsTest.actionsForTrace(AtomicReferencesNamesTests.kt:98) | | +| atomicReference2.READ: AtomicReference#1 at AtomicReferencesFromMultipleFieldsTest.actionsForTrace(AtomicReferencesNamesTests.kt:98) | | +| AtomicReference#1.get(): Node#1 at AtomicReferencesFromMultipleFieldsTest.actionsForTrace(AtomicReferencesNamesTests.kt:98) | | +| AtomicReference#1.compareAndSet(Node#1,Node#2): true at AtomicReferencesFromMultipleFieldsTest.actionsForTrace(AtomicReferencesNamesTests.kt:98) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | atomicReference1.READ: AtomicReference#1 at AtomicReferencesFromMultipleFieldsTest.actionsForTrace(AtomicReferencesNamesTests.kt:98) | +| | atomicReference2.READ: AtomicReference#1 at AtomicReferencesFromMultipleFieldsTest.actionsForTrace(AtomicReferencesNamesTests.kt:98) | +| | AtomicReference#1.get(): Node#2 at AtomicReferencesFromMultipleFieldsTest.actionsForTrace(AtomicReferencesNamesTests.kt:98) | +| | AtomicReference#1.compareAndSet(Node#2,Node#3): true at AtomicReferencesFromMultipleFieldsTest.actionsForTrace(AtomicReferencesNamesTests.kt:98) | +| | result: 0 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/atomic_references_names_trace.txt b/src/jvm/test/resources/expected_logs/atomic_references_names_trace.txt new file mode 100644 index 000000000..35d773f8e --- /dev/null +++ b/src/jvm/test/resources/expected_logs/atomic_references_names_trace.txt @@ -0,0 +1,144 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| atomicReference.READ: AtomicReference#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:29) | | +| atomicReference.READ: AtomicReference#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:29) | | +| atomicReference.get(): Node#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:29) | | +| atomicReference.compareAndSet(Node#1,Node#2): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:29) | | +| atomicReference.READ: AtomicReference#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:30) | | +| atomicReference.set(Node#3) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:30) | | +| atomicInteger.READ: AtomicInteger#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:32) | | +| atomicInteger.READ: AtomicInteger#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:32) | | +| atomicInteger.get(): 0 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:32) | | +| atomicInteger.compareAndSet(0,2): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:32) | | +| atomicInteger.READ: AtomicInteger#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:33) | | +| atomicInteger.set(3) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:33) | | +| atomicLong.READ: AtomicLong#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:35) | | +| atomicLong.READ: AtomicLong#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:35) | | +| atomicLong.get(): 0 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:35) | | +| atomicLong.compareAndSet(0,2): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:35) | | +| atomicLong.READ: AtomicLong#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:36) | | +| atomicLong.set(3) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:36) | | +| atomicBoolean.READ: AtomicBoolean#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:38) | | +| atomicBoolean.READ: AtomicBoolean#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:38) | | +| atomicBoolean.get(): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:38) | | +| atomicBoolean.compareAndSet(true,true): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:38) | | +| atomicBoolean.READ: AtomicBoolean#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:39) | | +| atomicBoolean.set(false) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:39) | | +| atomicReferenceArray.READ: AtomicReferenceArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:41) | | +| atomicReferenceArray.READ: AtomicReferenceArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:41) | | +| atomicReferenceArray[0].get(): Node#4 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:41) | | +| atomicReferenceArray[0].compareAndSet(Node#4,Node#5): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:41) | | +| atomicReferenceArray.READ: AtomicReferenceArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:42) | | +| atomicReferenceArray[0].set(Node#6) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:42) | | +| atomicIntegerArray.READ: AtomicIntegerArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:44) | | +| atomicIntegerArray.READ: AtomicIntegerArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:44) | | +| atomicIntegerArray[0].get(): 0 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:44) | | +| atomicIntegerArray[0].compareAndSet(0,1): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:44) | | +| atomicIntegerArray.READ: AtomicIntegerArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:45) | | +| atomicIntegerArray[0].set(2) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:45) | | +| atomicLongArray.READ: AtomicLongArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:47) | | +| atomicLongArray.READ: AtomicLongArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:47) | | +| atomicLongArray[0].get(): 0 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:47) | | +| atomicLongArray[0].compareAndSet(0,1): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:47) | | +| atomicLongArray.READ: AtomicLongArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:48) | | +| atomicLongArray[0].set(2) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:48) | | +| wrapper.READ: AtomicReferenceWrapper#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:50) | | +| AtomicReferenceWrapper#1.reference.set(Node#7) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:50) | | +| wrapper.READ: AtomicReferenceWrapper#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:51) | | +| AtomicReferenceWrapper#1.array.length(): 10 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:51) | | +| wrapper.READ: AtomicReferenceWrapper#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:52) | | +| AtomicReferenceWrapper#1.array[0].compareAndSet(1,2): false at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:52) | | +| AtomicReferencesNamesTest.staticValue.compareAndSet(0,2): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:54) | | +| AtomicReferencesNamesTest.staticValue.set(0) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:55) | | +| AtomicReferenceWrapper.staticValue.compareAndSet(1,2): false at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:57) | | +| AtomicReferenceWrapper.staticValue.set(3) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:58) | | +| AtomicReferencesNamesTest.staticArray[1].compareAndSet(0,1): false at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:60) | | +| AtomicReferenceWrapper.staticArray[1].compareAndSet(0,1): false at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:61) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | atomicReference.READ: AtomicReference#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:29) | +| | atomicReference.READ: AtomicReference#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:29) | +| | atomicReference.get(): Node#3 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:29) | +| | atomicReference.compareAndSet(Node#3,Node#8): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:29) | +| | atomicReference.READ: AtomicReference#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:30) | +| | atomicReference.set(Node#9) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:30) | +| | atomicInteger.READ: AtomicInteger#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:32) | +| | atomicInteger.READ: AtomicInteger#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:32) | +| | atomicInteger.get(): 3 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:32) | +| | atomicInteger.compareAndSet(3,2): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:32) | +| | atomicInteger.READ: AtomicInteger#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:33) | +| | atomicInteger.set(3) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:33) | +| | atomicLong.READ: AtomicLong#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:35) | +| | atomicLong.READ: AtomicLong#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:35) | +| | atomicLong.get(): 3 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:35) | +| | atomicLong.compareAndSet(3,2): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:35) | +| | atomicLong.READ: AtomicLong#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:36) | +| | atomicLong.set(3) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:36) | +| | atomicBoolean.READ: AtomicBoolean#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:38) | +| | atomicBoolean.READ: AtomicBoolean#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:38) | +| | atomicBoolean.get(): false at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:38) | +| | atomicBoolean.compareAndSet(false,true): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:38) | +| | atomicBoolean.READ: AtomicBoolean#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:39) | +| | atomicBoolean.set(false) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:39) | +| | atomicReferenceArray.READ: AtomicReferenceArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:41) | +| | atomicReferenceArray.READ: AtomicReferenceArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:41) | +| | atomicReferenceArray[0].get(): Node#6 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:41) | +| | atomicReferenceArray[0].compareAndSet(Node#6,Node#10): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:41) | +| | atomicReferenceArray.READ: AtomicReferenceArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:42) | +| | atomicReferenceArray[0].set(Node#11) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:42) | +| | atomicIntegerArray.READ: AtomicIntegerArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:44) | +| | atomicIntegerArray.READ: AtomicIntegerArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:44) | +| | atomicIntegerArray[0].get(): 2 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:44) | +| | atomicIntegerArray[0].compareAndSet(2,1): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:44) | +| | atomicIntegerArray.READ: AtomicIntegerArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:45) | +| | atomicIntegerArray[0].set(2) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:45) | +| | atomicLongArray.READ: AtomicLongArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:47) | +| | atomicLongArray.READ: AtomicLongArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:47) | +| | atomicLongArray[0].get(): 2 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:47) | +| | atomicLongArray[0].compareAndSet(2,1): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:47) | +| | atomicLongArray.READ: AtomicLongArray#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:48) | +| | atomicLongArray[0].set(2) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:48) | +| | wrapper.READ: AtomicReferenceWrapper#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:50) | +| | AtomicReferenceWrapper#1.reference.set(Node#12) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:50) | +| | wrapper.READ: AtomicReferenceWrapper#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:51) | +| | AtomicReferenceWrapper#1.array.length(): 10 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:51) | +| | wrapper.READ: AtomicReferenceWrapper#1 at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:52) | +| | AtomicReferenceWrapper#1.array[0].compareAndSet(1,2): false at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:52) | +| | AtomicReferencesNamesTest.staticValue.compareAndSet(0,2): true at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:54) | +| | AtomicReferencesNamesTest.staticValue.set(0) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:55) | +| | AtomicReferenceWrapper.staticValue.compareAndSet(1,2): false at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:57) | +| | AtomicReferenceWrapper.staticValue.set(3) at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:58) | +| | AtomicReferencesNamesTest.staticArray[1].compareAndSet(0,1): false at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:60) | +| | AtomicReferenceWrapper.staticArray[1].compareAndSet(0,1): false at AtomicReferencesNamesTest.actionsForTrace(AtomicReferencesNamesTests.kt:61) | +| | result: 0 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/atomic_updater_trace.txt b/src/jvm/test/resources/expected_logs/atomic_updater_trace.txt index a80b67218..4be5faff7 100644 --- a/src/jvm/test/resources/expected_logs/atomic_updater_trace.txt +++ b/src/jvm/test/resources/expected_logs/atomic_updater_trace.txt @@ -10,33 +10,33 @@ The following interleaving leads to the error: | Thread 1 | Thread 2 | | ------------------------------------------------------------------------------------------------------------------------------------------------- | | | increment(): 0 | -| | counter.READ: 0 at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:132) | +| | counter.READ: 0 at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:115) | | | switch | | increment(): 0 | | -| | counter.WRITE(1) at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:132) | -| | actionsJustForTrace() at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:133) | +| | counter.WRITE(1) at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:115) | +| | actionsJustForTrace() at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:116) | | | result: 0 | | ------------------------------------------------------------------------------------------------------------------------------------------------- | Detailed trace: -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | increment(): 0 | -| | counter.READ: 0 at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:132) | -| | switch | -| increment(): 0 | | -| counter.READ: 0 at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:132) | | -| counter.WRITE(1) at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:132) | | -| actionsJustForTrace() at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:133) | | -| node.READ: Node#1 at AtomicUpdaterTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:148) | | -| node.compareAndSet(Node#1,Node#2): true at AtomicUpdaterTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:148) | | -| node.set(Node#3) at AtomicUpdaterTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:149) | | -| result: 0 | | -| | counter.WRITE(1) at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:132) | -| | actionsJustForTrace() at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:133) | -| | node.READ: Node#3 at AtomicUpdaterTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:148) | -| | node.compareAndSet(Node#3,Node#4): true at AtomicUpdaterTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:148) | -| | node.set(Node#5) at AtomicUpdaterTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:149) | -| | result: 0 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:115) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:115) | | +| counter.WRITE(1) at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:115) | | +| actionsJustForTrace() at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:116) | | +| node.READ: IntWrapper#1 at AtomicUpdaterTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:131) | | +| node.compareAndSet(IntWrapper#1,IntWrapper#2): true at AtomicUpdaterTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:131) | | +| node.set(IntWrapper#3) at AtomicUpdaterTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:132) | | +| result: 0 | | +| | counter.WRITE(1) at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:115) | +| | actionsJustForTrace() at AtomicUpdaterTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:116) | +| | node.READ: IntWrapper#3 at AtomicUpdaterTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:131) | +| | node.compareAndSet(IntWrapper#3,IntWrapper#4): true at AtomicUpdaterTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:131) | +| | node.set(IntWrapper#5) at AtomicUpdaterTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:132) | +| | result: 0 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/captured_value.txt b/src/jvm/test/resources/expected_logs/captured_value.txt index 1d45d2b38..11fe64718 100644 --- a/src/jvm/test/resources/expected_logs/captured_value.txt +++ b/src/jvm/test/resources/expected_logs/captured_value.txt @@ -15,8 +15,8 @@ The following interleaving leads to the error: | | innerClass.READ: InnerClass#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:39) | | | innerClass.READ: InnerClass#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:40) | | | otherInnerClass.READ: InnerClass#2 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:41) | -| | primitiveArray.READ: int[]#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:42) | -| | objectArray.READ: String[]#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:43) | +| | primitiveArray.READ: IntArray#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:42) | +| | objectArray.READ: Array#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:43) | | | counter.READ: 0 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:44) | | | switch | | operation(): 0 | | @@ -34,8 +34,8 @@ Detailed trace: | | innerClass.READ: InnerClass#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:39) | | | innerClass.READ: InnerClass#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:40) | | | otherInnerClass.READ: InnerClass#2 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:41) | -| | primitiveArray.READ: int[]#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:42) | -| | objectArray.READ: String[]#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:43) | +| | primitiveArray.READ: IntArray#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:42) | +| | objectArray.READ: Array#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:43) | | | counter.READ: 0 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:44) | | | switch | | operation(): 0 | | @@ -44,8 +44,8 @@ Detailed trace: | innerClass.READ: InnerClass#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:39) | | | innerClass.READ: InnerClass#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:40) | | | otherInnerClass.READ: InnerClass#2 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:41) | | -| primitiveArray.READ: int[]#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:42) | | -| objectArray.READ: String[]#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:43) | | +| primitiveArray.READ: IntArray#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:42) | | +| objectArray.READ: Array#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:43) | | | counter.READ: 0 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:44) | | | counter.WRITE(1) at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:44) | | | result: 0 | | diff --git a/src/jvm/test/resources/expected_logs/captured_value_plugin.txt b/src/jvm/test/resources/expected_logs/captured_value_plugin.txt index 1d45d2b38..11fe64718 100644 --- a/src/jvm/test/resources/expected_logs/captured_value_plugin.txt +++ b/src/jvm/test/resources/expected_logs/captured_value_plugin.txt @@ -15,8 +15,8 @@ The following interleaving leads to the error: | | innerClass.READ: InnerClass#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:39) | | | innerClass.READ: InnerClass#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:40) | | | otherInnerClass.READ: InnerClass#2 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:41) | -| | primitiveArray.READ: int[]#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:42) | -| | objectArray.READ: String[]#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:43) | +| | primitiveArray.READ: IntArray#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:42) | +| | objectArray.READ: Array#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:43) | | | counter.READ: 0 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:44) | | | switch | | operation(): 0 | | @@ -34,8 +34,8 @@ Detailed trace: | | innerClass.READ: InnerClass#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:39) | | | innerClass.READ: InnerClass#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:40) | | | otherInnerClass.READ: InnerClass#2 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:41) | -| | primitiveArray.READ: int[]#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:42) | -| | objectArray.READ: String[]#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:43) | +| | primitiveArray.READ: IntArray#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:42) | +| | objectArray.READ: Array#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:43) | | | counter.READ: 0 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:44) | | | switch | | operation(): 0 | | @@ -44,8 +44,8 @@ Detailed trace: | innerClass.READ: InnerClass#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:39) | | | innerClass.READ: InnerClass#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:40) | | | otherInnerClass.READ: InnerClass#2 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:41) | | -| primitiveArray.READ: int[]#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:42) | | -| objectArray.READ: String[]#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:43) | | +| primitiveArray.READ: IntArray#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:42) | | +| objectArray.READ: Array#1 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:43) | | | counter.READ: 0 at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:44) | | | counter.WRITE(1) at CapturedValueRepresentationTest.operation(CapturedValueRepresentationTest.kt:44) | | | result: 0 | | diff --git a/src/jvm/test/resources/expected_logs/coroutine_cancellation.txt b/src/jvm/test/resources/expected_logs/coroutine_cancellation.txt index 64548c3bf..187ba0fc2 100644 --- a/src/jvm/test/resources/expected_logs/coroutine_cancellation.txt +++ b/src/jvm/test/resources/expected_logs/coroutine_cancellation.txt @@ -6,76 +6,76 @@ | ---------------------------------------------------------------- | The following interleaving leads to the error: -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | isAbsurd(): true | -| | correct.READ: true at CoroutineCancellationTraceReportingTest.isAbsurd(CoroutineCancellationTraceReportingTest.kt:36) | -| | switch | -| cancelledOp() + cancel: SUSPENDED + CANCELLED | | -| initCancellability() at CoroutineCancellationTraceReportingTest.cancelledOp(CoroutineCancellationTraceReportingTest.kt:57) | | -| invokeOnCancellation(cancelledOp$2$1) at CoroutineCancellationTraceReportingTest.cancelledOp(CoroutineCancellationTraceReportingTest.kt:29) | | -| getResult(): COROUTINE_SUSPENDED at CoroutineCancellationTraceReportingTest.cancelledOp(CoroutineCancellationTraceReportingTest.kt:59) | | -| trySuspend(): true at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:300) | | -| getParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:310) | | -| CANCELLED BEFORE RESUMPTION | | -| _state.get(): InvokeOnCancel#1 at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:0) | | -| _state.compareAndSet(InvokeOnCancel#1,CancelledContinuation#1): true at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:209) | | -| callCancelHandler(InvokeOnCancel#1,Exception#1) at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:212) | | -| detachChildIfNonResuable() at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:216) | | -| dispatchResume(1) at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:217) | | -| result: SUSPENDED + CANCELLED | | -| | correct.READ: false at CoroutineCancellationTraceReportingTest.isAbsurd(CoroutineCancellationTraceReportingTest.kt:36) | -| | result: true | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | isAbsurd(): true | +| | correct.READ: true at CoroutineCancellationTraceReportingTest.isAbsurd(CoroutineCancellationTraceReportingTest.kt:36) | +| | switch | +| cancelledOp() + cancel: SUSPENDED + CANCELLED | | +| .initCancellability() at CoroutineCancellationTraceReportingTest.cancelledOp(CoroutineCancellationTraceReportingTest.kt:57) | | +| .invokeOnCancellation(cancelledOp$2$1) at CoroutineCancellationTraceReportingTest.cancelledOp(CoroutineCancellationTraceReportingTest.kt:29) | | +| .getResult(): COROUTINE_SUSPENDED at CoroutineCancellationTraceReportingTest.cancelledOp(CoroutineCancellationTraceReportingTest.kt:59) | | +| trySuspend(): true at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:300) | | +| getParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:310) | | +| CANCELLED BEFORE RESUMPTION | | +| _state.get(): InvokeOnCancel#1 at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:0) | | +| _state.compareAndSet(InvokeOnCancel#1,CancelledContinuation#1): true at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:209) | | +| .callCancelHandler(InvokeOnCancel#1,Exception#1) at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:212) | | +| .detachChildIfNonResuable() at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:216) | | +| .dispatchResume(1) at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:217) | | +| result: SUSPENDED + CANCELLED | | +| | correct.READ: false at CoroutineCancellationTraceReportingTest.isAbsurd(CoroutineCancellationTraceReportingTest.kt:36) | +| | result: true | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | Detailed trace: -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | isAbsurd(): true | -| | correct.READ: true at CoroutineCancellationTraceReportingTest.isAbsurd(CoroutineCancellationTraceReportingTest.kt:36) | -| | switch | -| cancelledOp() + cancel: SUSPENDED + CANCELLED | | -| initCancellability() at CoroutineCancellationTraceReportingTest.cancelledOp(CoroutineCancellationTraceReportingTest.kt:57) | | -| installParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.initCancellability(CancellableContinuationImpl.kt:129) | | -| _parentHandle.compareAndSet(null,ChildContinuation#1): true at CancellableContinuationImpl.installParentHandle(CancellableContinuationImpl.kt:352) | | -| isCompleted(): false at CancellableContinuationImpl.initCancellability(CancellableContinuationImpl.kt:134) | | -| getState$kotlinx_coroutines_core(): Active#1 at CancellableContinuationImpl.isCompleted(CancellableContinuationImpl.kt:112) | | -| _state.get(): Active#1 at CancellableContinuationImpl.getState$kotlinx_coroutines_core(CancellableContinuationImpl.kt:108) | | -| invokeOnCancellation(cancelledOp$2$1) at CoroutineCancellationTraceReportingTest.cancelledOp(CoroutineCancellationTraceReportingTest.kt:29) | | -| invokeOnCancellationImpl(InvokeOnCancel#1) at CancellableContinuationImpl.invokeOnCancellation(CancellableContinuationImpl.kt:399) | | -| _state.get(): Active#1 at CancellableContinuationImpl.invokeOnCancellationImpl(CancellableContinuationImpl.kt:403) | | -| _state.compareAndSet(Active#1,InvokeOnCancel#1): true at CancellableContinuationImpl.invokeOnCancellationImpl(CancellableContinuationImpl.kt:407) | | -| getResult(): COROUTINE_SUSPENDED at CoroutineCancellationTraceReportingTest.cancelledOp(CoroutineCancellationTraceReportingTest.kt:59) | | -| trySuspend(): true at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:300) | | -| _decisionAndIndex.get(): 536870911 at CancellableContinuationImpl.trySuspend(CancellableContinuationImpl.kt:0) | | -| _decisionAndIndex.compareAndSet(536870911,1073741823): true at CancellableContinuationImpl.trySuspend(CancellableContinuationImpl.kt:278) | | -| getParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:310) | | -| _parentHandle.get(): ChildContinuation#1 at CancellableContinuationImpl.getParentHandle(CancellableContinuationImpl.kt:106) | | -| CANCELLED BEFORE RESUMPTION | | -| _state.get(): InvokeOnCancel#1 at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:0) | | -| _state.compareAndSet(InvokeOnCancel#1,CancelledContinuation#1): true at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:209) | | -| callCancelHandler(InvokeOnCancel#1,Exception#1) at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:212) | | -| invoke(Exception#1) at CancellableContinuationImpl.callCancelHandler(CancellableContinuationImpl.kt:249) | | -| invoke(Exception#1): Unit#1 at InvokeOnCancel.invoke(CancellableContinuationImpl.kt:642) | | -| invoke(Exception#1) at CoroutineCancellationTraceReportingTest$cancelledOp$2$1.invoke(CoroutineCancellationTraceReportingTest.kt:29) | | -| setCorrect(false) at CoroutineCancellationTraceReportingTest$cancelledOp$2$1.invoke(CoroutineCancellationTraceReportingTest.kt:30) | | -| correct.WRITE(false) at CoroutineCancellationTraceReportingTest.setCorrect(CoroutineCancellationTraceReportingTest.kt:23) | | -| detachChildIfNonResuable() at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:216) | | -| detachChild$kotlinx_coroutines_core() at CancellableContinuationImpl.detachChildIfNonResuable(CancellableContinuationImpl.kt:565) | | -| getParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.detachChild$kotlinx_coroutines_core(CancellableContinuationImpl.kt:572) | | -| _parentHandle.get(): ChildContinuation#1 at CancellableContinuationImpl.getParentHandle(CancellableContinuationImpl.kt:106) | | -| _parentHandle.set(NonDisposableHandle#1) at CancellableContinuationImpl.detachChild$kotlinx_coroutines_core(CancellableContinuationImpl.kt:574) | | -| dispatchResume(1) at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:217) | | -| tryResume(): false at CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:472) | | -| _decisionAndIndex.get(): 1073741823 at CancellableContinuationImpl.tryResume(CancellableContinuationImpl.kt:0) | | -| dispatch(,1) at CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:474) | | -| resume(,,false) at DispatchedTaskKt.dispatch(DispatchedTask.kt:168) | | -| takeState$kotlinx_coroutines_core(): CancelledContinuation#1 at DispatchedTaskKt.resume(DispatchedTask.kt:174) | | -| getState$kotlinx_coroutines_core(): CancelledContinuation#1 at CancellableContinuationImpl.takeState$kotlinx_coroutines_core(CancellableContinuationImpl.kt:168) | | -| _state.get(): CancelledContinuation#1 at CancellableContinuationImpl.getState$kotlinx_coroutines_core(CancellableContinuationImpl.kt:108) | | -| result: SUSPENDED + CANCELLED | | -| | correct.READ: false at CoroutineCancellationTraceReportingTest.isAbsurd(CoroutineCancellationTraceReportingTest.kt:36) | -| | result: true | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | isAbsurd(): true | +| | correct.READ: true at CoroutineCancellationTraceReportingTest.isAbsurd(CoroutineCancellationTraceReportingTest.kt:36) | +| | switch | +| cancelledOp() + cancel: SUSPENDED + CANCELLED | | +| .initCancellability() at CoroutineCancellationTraceReportingTest.cancelledOp(CoroutineCancellationTraceReportingTest.kt:57) | | +| installParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.initCancellability(CancellableContinuationImpl.kt:129) | | +| _parentHandle.compareAndSet(null,ChildContinuation#1): true at CancellableContinuationImpl.installParentHandle(CancellableContinuationImpl.kt:352) | | +| isCompleted(): false at CancellableContinuationImpl.initCancellability(CancellableContinuationImpl.kt:134) | | +| getState$kotlinx_coroutines_core(): Active#1 at CancellableContinuationImpl.isCompleted(CancellableContinuationImpl.kt:112) | | +| _state.get(): Active#1 at CancellableContinuationImpl.getState$kotlinx_coroutines_core(CancellableContinuationImpl.kt:108) | | +| .invokeOnCancellation(cancelledOp$2$1) at CoroutineCancellationTraceReportingTest.cancelledOp(CoroutineCancellationTraceReportingTest.kt:29) | | +| invokeOnCancellationImpl(InvokeOnCancel#1) at CancellableContinuationImpl.invokeOnCancellation(CancellableContinuationImpl.kt:399) | | +| _state.get(): Active#1 at CancellableContinuationImpl.invokeOnCancellationImpl(CancellableContinuationImpl.kt:403) | | +| _state.compareAndSet(Active#1,InvokeOnCancel#1): true at CancellableContinuationImpl.invokeOnCancellationImpl(CancellableContinuationImpl.kt:407) | | +| .getResult(): COROUTINE_SUSPENDED at CoroutineCancellationTraceReportingTest.cancelledOp(CoroutineCancellationTraceReportingTest.kt:59) | | +| trySuspend(): true at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:300) | | +| _decisionAndIndex.get(): 536870911 at CancellableContinuationImpl.trySuspend(CancellableContinuationImpl.kt:0) | | +| _decisionAndIndex.compareAndSet(536870911,1073741823): true at CancellableContinuationImpl.trySuspend(CancellableContinuationImpl.kt:278) | | +| getParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:310) | | +| _parentHandle.get(): ChildContinuation#1 at CancellableContinuationImpl.getParentHandle(CancellableContinuationImpl.kt:106) | | +| CANCELLED BEFORE RESUMPTION | | +| _state.get(): InvokeOnCancel#1 at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:0) | | +| _state.compareAndSet(InvokeOnCancel#1,CancelledContinuation#1): true at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:209) | | +| .callCancelHandler(InvokeOnCancel#1,Exception#1) at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:212) | | +| InvokeOnCancel#1.invoke(Exception#1) at CancellableContinuationImpl.callCancelHandler(CancellableContinuationImpl.kt:249) | | +| cancelledOp$2$1.invoke(Exception#1): Unit#1 at InvokeOnCancel.invoke(CancellableContinuationImpl.kt:642) | | +| invoke(Exception#1) at CoroutineCancellationTraceReportingTest$cancelledOp$2$1.invoke(CoroutineCancellationTraceReportingTest.kt:29) | | +| CoroutineCancellationTraceReportingTest#1.setCorrect(false) at CoroutineCancellationTraceReportingTest$cancelledOp$2$1.invoke(CoroutineCancellationTraceReportingTest.kt:30) | | +| correct.WRITE(false) at CoroutineCancellationTraceReportingTest.setCorrect(CoroutineCancellationTraceReportingTest.kt:23) | | +| .detachChildIfNonResuable() at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:216) | | +| detachChild$kotlinx_coroutines_core() at CancellableContinuationImpl.detachChildIfNonResuable(CancellableContinuationImpl.kt:565) | | +| getParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.detachChild$kotlinx_coroutines_core(CancellableContinuationImpl.kt:572) | | +| _parentHandle.get(): ChildContinuation#1 at CancellableContinuationImpl.getParentHandle(CancellableContinuationImpl.kt:106) | | +| _parentHandle.set(NonDisposableHandle#1) at CancellableContinuationImpl.detachChild$kotlinx_coroutines_core(CancellableContinuationImpl.kt:574) | | +| .dispatchResume(1) at CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:217) | | +| tryResume(): false at CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:472) | | +| _decisionAndIndex.get(): 1073741823 at CancellableContinuationImpl.tryResume(CancellableContinuationImpl.kt:0) | | +| DispatchedTaskKt.dispatch(,1) at CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:474) | | +| DispatchedTaskKt.resume(,,false) at DispatchedTaskKt.dispatch(DispatchedTask.kt:168) | | +| .takeState$kotlinx_coroutines_core(): CancelledContinuation#1 at DispatchedTaskKt.resume(DispatchedTask.kt:174) | | +| getState$kotlinx_coroutines_core(): CancelledContinuation#1 at CancellableContinuationImpl.takeState$kotlinx_coroutines_core(CancellableContinuationImpl.kt:168) | | +| _state.get(): CancelledContinuation#1 at CancellableContinuationImpl.getState$kotlinx_coroutines_core(CancellableContinuationImpl.kt:108) | | +| result: SUSPENDED + CANCELLED | | +| | correct.READ: false at CoroutineCancellationTraceReportingTest.isAbsurd(CoroutineCancellationTraceReportingTest.kt:36) | +| | result: true | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/infinite_spin_loop_events_cut.txt b/src/jvm/test/resources/expected_logs/infinite_spin_loop_events_cut.txt index 3b63c77d8..0df0013f5 100644 --- a/src/jvm/test/resources/expected_logs/infinite_spin_loop_events_cut.txt +++ b/src/jvm/test/resources/expected_logs/infinite_spin_loop_events_cut.txt @@ -21,116 +21,116 @@ All operations above the horizontal line | ----- | happen before those below the The following interleaving leads to the error: -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| one(): 1 | | -| one(): 1 | | -| one(): 1 | | -| one(): 1 | | -| two(): 2 | | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | two(): 2 | -| | two(): 2 | -| | two(): 2 | -| | one(): 1 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | switch | -| two(): | | -| compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:151) | | -| /* The following events repeat infinitely: */ | | -| get(): false at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:88) | | -| set(true) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:89) | | -| switch (reason: active lock detected) | | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | -| | result: 1 | -| | one(): 1 | -| /* The following events repeat infinitely: */ | | -| get(): true at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:88) | | -| set(false) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:89) | | -| switch (reason: active lock detected) | | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| one(): 1 | | +| one(): 1 | | +| one(): 1 | | +| one(): 1 | | +| two(): 2 | | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | two(): 2 | +| | two(): 2 | +| | two(): 2 | +| | one(): 1 | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | switch | +| two(): | | +| sharedState2.compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:151) | | +| /* The following events repeat infinitely: */ | | +| sharedStateAny.get(): false at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:88) | | +| sharedStateAny.set(true) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:89) | | +| switch (reason: active lock detected) | | +| | sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | +| | result: 1 | +| | one(): 1 | +| /* The following events repeat infinitely: */ | | +| sharedStateAny.get(): true at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:88) | | +| sharedStateAny.set(false) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:89) | | +| switch (reason: active lock detected) | | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | All unfinished threads are in deadlock Detailed trace: -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| two(): 2 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | | -| set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | | -| result: 2 | | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | one(): 1 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | switch | -| two(): | | -| compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:151) | | -| /* The following events repeat infinitely: */ | | -| get(): false at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:88) | | -| set(true) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:89) | | -| switch (reason: active lock detected) | | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | -| | result: 1 | -| | one(): 1 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | -| | result: 1 | -| /* The following events repeat infinitely: */ | | -| get(): true at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:88) | | -| set(false) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:89) | | -| switch (reason: active lock detected) | | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| two(): 2 | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | | +| result: 2 | | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | one(): 1 | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | switch | +| two(): | | +| sharedState2.compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:151) | | +| /* The following events repeat infinitely: */ | | +| sharedStateAny.get(): false at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:88) | | +| sharedStateAny.set(true) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:89) | | +| switch (reason: active lock detected) | | +| | sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | +| | result: 1 | +| | one(): 1 | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | +| | result: 1 | +| /* The following events repeat infinitely: */ | | +| sharedStateAny.get(): true at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:88) | | +| sharedStateAny.set(false) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:89) | | +| switch (reason: active lock detected) | | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | All unfinished threads are in deadlock diff --git a/src/jvm/test/resources/expected_logs/jdk_unsafe_trace.txt b/src/jvm/test/resources/expected_logs/jdk_unsafe_trace.txt index 18c9cb357..b6b88890e 100644 --- a/src/jvm/test/resources/expected_logs/jdk_unsafe_trace.txt +++ b/src/jvm/test/resources/expected_logs/jdk_unsafe_trace.txt @@ -10,55 +10,55 @@ The following interleaving leads to the error: | Thread 1 | Thread 2 | | -------------------------------------------------------------------------------------------------------------------------------------------- | | | increment(): 0 | -| | counter.READ: 0 at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:85) | +| | counter.READ: 0 at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:82) | | | switch | | increment(): 0 | | -| | counter.WRITE(1) at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:85) | -| | actionsJustForTrace() at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:86) | +| | counter.WRITE(1) at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:82) | +| | actionsJustForTrace() at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:83) | | | result: 0 | | -------------------------------------------------------------------------------------------------------------------------------------------- | Detailed trace: -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| Thread 1 | Thread 2 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| | increment(): 0 | -| | counter.READ: 0 at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:85) | -| | switch | -| increment(): 0 | | -| counter.READ: 0 at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:85) | | -| counter.WRITE(1) at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:85) | | -| actionsJustForTrace() at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:86) | | -| put(1,2): null at JdkUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:102) | | -| putVal(1,2,false): null at ConcurrentHashMap.put(ConcurrentHashMap.java:1006) | | -| table.READ: null at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1014) | | -| initTable(): Node[]#1 at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1017) | | -| table.READ: null at ConcurrentHashMap.initTable(ConcurrentHashMap.java:2293) | | -| sizeCtl.READ: 0 at ConcurrentHashMap.initTable(ConcurrentHashMap.java:2294) | | -| compareAndSetInt(0,-1): true at ConcurrentHashMap.initTable(ConcurrentHashMap.java:2296) | | -| table.READ: null at ConcurrentHashMap.initTable(ConcurrentHashMap.java:2298) | | -| table.WRITE(Node[]#1) at ConcurrentHashMap.initTable(ConcurrentHashMap.java:2302) | | -| sizeCtl.WRITE(12) at ConcurrentHashMap.initTable(ConcurrentHashMap.java:2306) | | -| tabAt(Node[]#1,1): null at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1018) | | -| getReferenceAcquire(): null at ConcurrentHashMap.tabAt(ConcurrentHashMap.java:760) | | -| casTabAt(Node[]#1,1,null,Node#1): true at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1019) | | -| compareAndSetReference(null,Node#1): true at ConcurrentHashMap.casTabAt(ConcurrentHashMap.java:765) | | -| addCount(1,0) at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1075) | | -| counterCells.READ: null at ConcurrentHashMap.addCount(ConcurrentHashMap.java:2326) | | -| baseCount.READ: 0 at ConcurrentHashMap.addCount(ConcurrentHashMap.java:2326) | | -| compareAndSetLong(0,1): true at ConcurrentHashMap.addCount(ConcurrentHashMap.java:2327) | | -| sizeCtl.READ: 12 at ConcurrentHashMap.addCount(ConcurrentHashMap.java:2343) | | -| result: 0 | | -| | counter.WRITE(1) at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:85) | -| | actionsJustForTrace() at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:86) | -| | put(1,2): 2 at JdkUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:102) | -| | putVal(1,2,false): 2 at ConcurrentHashMap.put(ConcurrentHashMap.java:1006) | -| | table.READ: Node[]#1 at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1014) | -| | tabAt(Node[]#1,1): Node#1 at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1018) | -| | getReferenceAcquire(): Node#1 at ConcurrentHashMap.tabAt(ConcurrentHashMap.java:760) | -| | MONITORENTER at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1031) | -| | tabAt(Node[]#1,1): Node#1 at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1032) | -| | getReferenceAcquire(): Node#1 at ConcurrentHashMap.tabAt(ConcurrentHashMap.java:760) | -| | MONITOREXIT at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1065) | -| | result: 0 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:82) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:82) | | +| counter.WRITE(1) at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:82) | | +| actionsJustForTrace() at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:83) | | +| ConcurrentHashMap#1.put(1,2): null at JdkUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:99) | | +| putVal(1,2,false): null at ConcurrentHashMap.put(ConcurrentHashMap.java:1006) | | +| table.READ: null at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1014) | | +| initTable(): Array#1 at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1017) | | +| table.READ: null at ConcurrentHashMap.initTable(ConcurrentHashMap.java:2293) | | +| sizeCtl.READ: 0 at ConcurrentHashMap.initTable(ConcurrentHashMap.java:2294) | | +| sizeCtl.compareAndSetInt(0,-1): true at ConcurrentHashMap.initTable(ConcurrentHashMap.java:2296) | | +| table.READ: null at ConcurrentHashMap.initTable(ConcurrentHashMap.java:2298) | | +| table.WRITE(Array#1) at ConcurrentHashMap.initTable(ConcurrentHashMap.java:2302) | | +| sizeCtl.WRITE(12) at ConcurrentHashMap.initTable(ConcurrentHashMap.java:2306) | | +| ConcurrentHashMap.tabAt(Array#1,1): null at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1018) | | +| Array#1[1].getReferenceAcquire(): null at ConcurrentHashMap.tabAt(ConcurrentHashMap.java:760) | | +| ConcurrentHashMap.casTabAt(Array#1,1,null,Node#1): true at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1019) | | +| Array#1[1].compareAndSetReference(null,Node#1): true at ConcurrentHashMap.casTabAt(ConcurrentHashMap.java:765) | | +| addCount(1,0) at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1075) | | +| counterCells.READ: null at ConcurrentHashMap.addCount(ConcurrentHashMap.java:2326) | | +| baseCount.READ: 0 at ConcurrentHashMap.addCount(ConcurrentHashMap.java:2326) | | +| baseCount.compareAndSetLong(0,1): true at ConcurrentHashMap.addCount(ConcurrentHashMap.java:2327) | | +| sizeCtl.READ: 12 at ConcurrentHashMap.addCount(ConcurrentHashMap.java:2343) | | +| result: 0 | | +| | counter.WRITE(1) at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:82) | +| | actionsJustForTrace() at JdkUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:83) | +| | ConcurrentHashMap#1.put(1,2): 2 at JdkUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:99) | +| | putVal(1,2,false): 2 at ConcurrentHashMap.put(ConcurrentHashMap.java:1006) | +| | table.READ: Array#1 at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1014) | +| | ConcurrentHashMap.tabAt(Array#1,1): Node#1 at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1018) | +| | Array#1[1].getReferenceAcquire(): Node#1 at ConcurrentHashMap.tabAt(ConcurrentHashMap.java:760) | +| | MONITORENTER at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1031) | +| | ConcurrentHashMap.tabAt(Array#1,1): Node#1 at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1032) | +| | Array#1[1].getReferenceAcquire(): Node#1 at ConcurrentHashMap.tabAt(ConcurrentHashMap.java:760) | +| | MONITOREXIT at ConcurrentHashMap.putVal(ConcurrentHashMap.java:1065) | +| | result: 0 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/obstruction_freedom_violation_events_cut.txt b/src/jvm/test/resources/expected_logs/obstruction_freedom_violation_events_cut.txt index ccdc343bb..ba1b4a61e 100644 --- a/src/jvm/test/resources/expected_logs/obstruction_freedom_violation_events_cut.txt +++ b/src/jvm/test/resources/expected_logs/obstruction_freedom_violation_events_cut.txt @@ -6,35 +6,35 @@ | ------------------------ | The following interleaving leads to the error: -| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | enqueue(-1) | -| | enqueue(-1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:33) | -| | get(): Node#1 at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:27) | -| | compareAndSet(null,Node#2): true at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:28) | -| | switch | -| enqueue(1) | | -| enqueue(1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:33) | | -| /* The following events repeat infinitely: */ | | -| get(): Node#1 at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:27) | | -| compareAndSet(null,Node#3): false at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:28) | | -| /* An active lock was detected */ | | -| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | enqueue(-1) | +| | MSQueueBlocking#1.enqueue(-1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:33) | +| | tail.get(): Node#1 at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:27) | +| | Node#1.next.compareAndSet(null,Node#2): true at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:28) | +| | switch | +| enqueue(1) | | +| MSQueueBlocking#1.enqueue(1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:33) | | +| /* The following events repeat infinitely: */ | | +| tail.get(): Node#1 at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:27) | | +| Node#1.next.compareAndSet(null,Node#3): false at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:28) | | +| /* An active lock was detected */ | | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | Detailed trace: -| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | enqueue(-1) | -| | enqueue(-1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:33) | -| | get(): Node#1 at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:27) | -| | compareAndSet(null,Node#2): true at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:28) | -| | switch | -| enqueue(1) | | -| enqueue(1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:33) | | -| /* The following events repeat infinitely: */ | | -| get(): Node#1 at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:27) | | -| compareAndSet(null,Node#3): false at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:28) | | -| /* An active lock was detected */ | | -| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | enqueue(-1) | +| | MSQueueBlocking#1.enqueue(-1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:33) | +| | tail.get(): Node#1 at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:27) | +| | Node#1.next.compareAndSet(null,Node#2): true at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:28) | +| | switch | +| enqueue(1) | | +| MSQueueBlocking#1.enqueue(1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:33) | | +| /* The following events repeat infinitely: */ | | +| tail.get(): Node#1 at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:27) | | +| Node#1.next.compareAndSet(null,Node#3): false at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:28) | | +| /* An active lock was detected */ | | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/obstruction_freedom_violation_with_no_detected_cycle.txt b/src/jvm/test/resources/expected_logs/obstruction_freedom_violation_with_no_detected_cycle.txt index 6e09b1fbe..611ae7274 100644 --- a/src/jvm/test/resources/expected_logs/obstruction_freedom_violation_with_no_detected_cycle.txt +++ b/src/jvm/test/resources/expected_logs/obstruction_freedom_violation_with_no_detected_cycle.txt @@ -6,125 +6,125 @@ | ----------- | The following interleaving leads to the error: -| ------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | -| ------------------------------------------------------------------------------------------------------------------------------- | -| operation() | -| incrementManyTimes() at ObstructionFreedomActiveLockRepresentationTest.operation(ObstructionFreedomRepresentationTest.kt:34) | -| incrementManyTimes() at ObstructionFreedomActiveLockRepresentationTest.operation(ObstructionFreedomRepresentationTest.kt:37) | -| get(): 101 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:41) | -| /* An active lock was detected */ | -| ------------------------------------------------------------------------------------------------------------------------------- | +| --------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | +| --------------------------------------------------------------------------------------------------------------------------------------- | +| operation() | +| incrementManyTimes() at ObstructionFreedomActiveLockRepresentationTest.operation(ObstructionFreedomRepresentationTest.kt:34) | +| incrementManyTimes() at ObstructionFreedomActiveLockRepresentationTest.operation(ObstructionFreedomRepresentationTest.kt:37) | +| counter.get(): 101 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:41) | +| /* An active lock was detected */ | +| --------------------------------------------------------------------------------------------------------------------------------------- | Detailed trace: -| ------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | -| ------------------------------------------------------------------------------------------------------------------------------------------- | -| operation() | -| incrementManyTimes() at ObstructionFreedomActiveLockRepresentationTest.operation(ObstructionFreedomRepresentationTest.kt:34) | -| get(): 0 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:41) | -| incrementAndGet(): 1 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 2 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 3 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 4 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 5 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 6 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 7 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 8 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 9 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 10 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 11 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 12 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 13 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 14 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 15 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 16 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 17 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 18 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 19 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 20 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 21 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 22 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 23 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 24 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 25 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 26 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 27 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 28 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 29 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 30 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 31 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 32 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 33 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 34 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 35 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 36 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 37 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 38 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 39 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 40 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 41 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 42 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 43 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 44 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 45 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 46 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 47 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 48 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 49 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 50 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 51 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 52 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 53 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 54 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 55 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 56 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 57 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 58 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 59 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 60 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 61 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 62 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 63 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 64 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 65 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 66 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 67 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 68 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 69 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 70 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 71 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 72 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 73 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 74 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 75 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 76 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 77 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 78 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 79 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 80 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 81 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 82 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 83 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 84 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 85 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 86 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 87 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 88 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 89 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 90 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 91 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 92 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 93 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 94 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 95 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 96 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 97 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 98 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 99 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 100 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementAndGet(): 101 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | -| incrementManyTimes() at ObstructionFreedomActiveLockRepresentationTest.operation(ObstructionFreedomRepresentationTest.kt:37) | -| get(): 101 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:41) | -| /* An active lock was detected */ | -| ------------------------------------------------------------------------------------------------------------------------------------------- | +| --------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | +| --------------------------------------------------------------------------------------------------------------------------------------------------- | +| operation() | +| incrementManyTimes() at ObstructionFreedomActiveLockRepresentationTest.operation(ObstructionFreedomRepresentationTest.kt:34) | +| counter.get(): 0 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:41) | +| counter.incrementAndGet(): 1 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 2 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 3 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 4 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 5 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 6 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 7 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 8 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 9 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 10 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 11 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 12 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 13 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 14 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 15 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 16 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 17 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 18 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 19 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 20 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 21 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 22 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 23 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 24 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 25 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 26 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 27 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 28 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 29 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 30 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 31 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 32 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 33 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 34 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 35 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 36 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 37 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 38 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 39 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 40 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 41 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 42 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 43 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 44 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 45 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 46 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 47 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 48 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 49 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 50 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 51 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 52 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 53 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 54 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 55 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 56 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 57 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 58 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 59 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 60 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 61 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 62 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 63 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 64 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 65 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 66 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 67 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 68 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 69 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 70 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 71 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 72 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 73 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 74 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 75 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 76 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 77 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 78 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 79 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 80 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 81 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 82 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 83 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 84 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 85 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 86 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 87 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 88 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 89 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 90 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 91 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 92 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 93 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 94 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 95 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 96 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 97 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 98 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 99 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 100 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| counter.incrementAndGet(): 101 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:44) | +| incrementManyTimes() at ObstructionFreedomActiveLockRepresentationTest.operation(ObstructionFreedomRepresentationTest.kt:37) | +| counter.get(): 101 at ObstructionFreedomActiveLockRepresentationTest.incrementManyTimes(ObstructionFreedomRepresentationTest.kt:41) | +| /* An active lock was detected */ | +| --------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/owner_name_in_trace.txt b/src/jvm/test/resources/expected_logs/owner_name_in_trace.txt new file mode 100644 index 000000000..f8fe5fe75 --- /dev/null +++ b/src/jvm/test/resources/expected_logs/owner_name_in_trace.txt @@ -0,0 +1,76 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| readWriteTestMethod(): 6 at OwnerNameInTraceRepresentationTest.actionsForTrace(OwnerNameInTraceRepresentationTests.kt:24) | | +| value.WRITE(2) at OwnerNameInTraceRepresentationTest.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:31) | | +| Array#1[0].WRITE(4) at OwnerNameInTraceRepresentationTest.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:32) | | +| value.READ: 2 at OwnerNameInTraceRepresentationTest.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:33) | | +| Array#1[0].READ: 4 at OwnerNameInTraceRepresentationTest.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:33) | | +| stub.READ: StubClass#1 at OwnerNameInTraceRepresentationTest.actionsForTrace(OwnerNameInTraceRepresentationTests.kt:25) | | +| StubClass#1.readWriteTestMethod(): 7 at OwnerNameInTraceRepresentationTest.actionsForTrace(OwnerNameInTraceRepresentationTests.kt:26) | | +| value.WRITE(3) at OwnerNameInTraceRepresentationTest$StubClass.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:49) | | +| Array#2[0].WRITE(4) at OwnerNameInTraceRepresentationTest$StubClass.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:50) | | +| value.READ: 3 at OwnerNameInTraceRepresentationTest$StubClass.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:51) | | +| Array#2[0].READ: 4 at OwnerNameInTraceRepresentationTest$StubClass.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:51) | | +| doReadWriteWithOtherObject(): 6 at OwnerNameInTraceRepresentationTest.actionsForTrace(OwnerNameInTraceRepresentationTests.kt:27) | | +| stub.READ: StubClass#1 at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:37) | | +| StubClass#1.value.WRITE(2) at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:37) | | +| stub.READ: StubClass#1 at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:38) | | +| Array#2[0].WRITE(4) at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:38) | | +| stub.READ: StubClass#1 at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:39) | | +| StubClass#1.value.READ: 2 at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:39) | | +| stub.READ: StubClass#1 at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:39) | | +| Array#2[0].READ: 4 at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:39) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | readWriteTestMethod(): 6 at OwnerNameInTraceRepresentationTest.actionsForTrace(OwnerNameInTraceRepresentationTests.kt:24) | +| | value.WRITE(2) at OwnerNameInTraceRepresentationTest.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:31) | +| | Array#1[0].WRITE(4) at OwnerNameInTraceRepresentationTest.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:32) | +| | value.READ: 2 at OwnerNameInTraceRepresentationTest.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:33) | +| | Array#1[0].READ: 4 at OwnerNameInTraceRepresentationTest.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:33) | +| | stub.READ: StubClass#1 at OwnerNameInTraceRepresentationTest.actionsForTrace(OwnerNameInTraceRepresentationTests.kt:25) | +| | StubClass#1.readWriteTestMethod(): 7 at OwnerNameInTraceRepresentationTest.actionsForTrace(OwnerNameInTraceRepresentationTests.kt:26) | +| | value.WRITE(3) at OwnerNameInTraceRepresentationTest$StubClass.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:49) | +| | Array#2[0].WRITE(4) at OwnerNameInTraceRepresentationTest$StubClass.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:50) | +| | value.READ: 3 at OwnerNameInTraceRepresentationTest$StubClass.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:51) | +| | Array#2[0].READ: 4 at OwnerNameInTraceRepresentationTest$StubClass.readWriteTestMethod(OwnerNameInTraceRepresentationTests.kt:51) | +| | doReadWriteWithOtherObject(): 6 at OwnerNameInTraceRepresentationTest.actionsForTrace(OwnerNameInTraceRepresentationTests.kt:27) | +| | stub.READ: StubClass#1 at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:37) | +| | StubClass#1.value.WRITE(2) at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:37) | +| | stub.READ: StubClass#1 at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:38) | +| | Array#2[0].WRITE(4) at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:38) | +| | stub.READ: StubClass#1 at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:39) | +| | StubClass#1.value.READ: 2 at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:39) | +| | stub.READ: StubClass#1 at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:39) | +| | Array#2[0].READ: 4 at OwnerNameInTraceRepresentationTest.doReadWriteWithOtherObject(OwnerNameInTraceRepresentationTests.kt:39) | +| | result: 0 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/spin_lock_events_cut_inner_loop.txt b/src/jvm/test/resources/expected_logs/spin_lock_events_cut_inner_loop.txt index 6755ea9e3..c259f1274 100644 --- a/src/jvm/test/resources/expected_logs/spin_lock_events_cut_inner_loop.txt +++ b/src/jvm/test/resources/expected_logs/spin_lock_events_cut_inner_loop.txt @@ -21,128 +21,128 @@ All operations above the horizontal line | ----- | happen before those below the The following interleaving leads to the error: -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| one(): 1 | | -| one(): 1 | | -| one(): 1 | | -| one(): 1 | | -| two(): 2 | | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | two(): 2 | -| | two(): 2 | -| | two(): 2 | -| | one(): 1 | -| | one(): | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | switch | -| two(): | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| /* The following events repeat infinitely: */ | | -| compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | -| switch (reason: active lock detected) | | -| | /* The following events repeat infinitely: */ | -| | compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | -| | switch (reason: active lock detected) | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| one(): 1 | | +| one(): 1 | | +| one(): 1 | | +| one(): 1 | | +| two(): 2 | | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | two(): 2 | +| | two(): 2 | +| | two(): 2 | +| | one(): 1 | +| | one(): | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | switch | +| two(): | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| /* The following events repeat infinitely: */ | | +| sharedState1.compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | +| switch (reason: active lock detected) | | +| | /* The following events repeat infinitely: */ | +| | sharedState2.compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | +| | switch (reason: active lock detected) | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | All unfinished threads are in deadlock Detailed trace: -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| two(): 2 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | | -| set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | | -| result: 2 | | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | one(): 1 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | -| | result: 1 | -| | one(): | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | switch | -| two(): | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| /* The following events repeat infinitely: */ | | -| compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | -| length(): 10 at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:121) | | -| set(0,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | -| set(1,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | -| set(2,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | -| set(3,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | -| set(4,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | -| set(5,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | -| set(6,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | -| set(7,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | -| set(8,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | -| set(9,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | -| switch (reason: active lock detected) | | -| | /* The following events repeat infinitely: */ | -| | compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | -| | length(): 10 at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:121) | -| | set(0,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | -| | set(1,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | -| | set(2,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | -| | set(3,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | -| | set(4,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | -| | set(5,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | -| | set(6,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | -| | set(7,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | -| | set(8,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | -| | set(9,0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | -| | switch (reason: active lock detected) | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| two(): 2 | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | | +| result: 2 | | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | one(): 1 | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | +| | result: 1 | +| | one(): | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | switch | +| two(): | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| /* The following events repeat infinitely: */ | | +| sharedState1.compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | +| data.length(): 10 at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:121) | | +| data[0].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | +| data[1].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | +| data[2].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | +| data[3].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | +| data[4].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | +| data[5].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | +| data[6].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | +| data[7].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | +| data[8].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | +| data[9].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | | +| switch (reason: active lock detected) | | +| | /* The following events repeat infinitely: */ | +| | sharedState2.compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | +| | data.length(): 10 at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:121) | +| | data[0].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | +| | data[1].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | +| | data[2].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | +| | data[3].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | +| | data[4].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | +| | data[5].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | +| | data[6].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | +| | data[7].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | +| | data[8].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | +| | data[9].set(0) at SpinlockEventsCutWithInnerLoopActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:122) | +| | switch (reason: active lock detected) | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | All unfinished threads are in deadlock diff --git a/src/jvm/test/resources/expected_logs/spin_lock_events_cut_long_cycle.txt b/src/jvm/test/resources/expected_logs/spin_lock_events_cut_long_cycle.txt index 1f8aabfad..b09e41434 100644 --- a/src/jvm/test/resources/expected_logs/spin_lock_events_cut_long_cycle.txt +++ b/src/jvm/test/resources/expected_logs/spin_lock_events_cut_long_cycle.txt @@ -21,120 +21,120 @@ All operations above the horizontal line | ----- | happen before those below the The following interleaving leads to the error: -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| one(): 1 | | -| one(): 1 | | -| one(): 1 | | -| one(): 1 | | -| two(): 2 | | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | two(): 2 | -| | two(): 2 | -| | two(): 2 | -| | one(): 1 | -| | one(): | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | switch | -| two(): | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| /* The following events repeat infinitely: */ | | -| compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | -| switch (reason: active lock detected) | | -| | /* The following events repeat infinitely: */ | -| | compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | -| | switch (reason: active lock detected) | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| one(): 1 | | +| one(): 1 | | +| one(): 1 | | +| one(): 1 | | +| two(): 2 | | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | two(): 2 | +| | two(): 2 | +| | two(): 2 | +| | one(): 1 | +| | one(): | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | switch | +| two(): | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| /* The following events repeat infinitely: */ | | +| sharedState1.compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | +| switch (reason: active lock detected) | | +| | /* The following events repeat infinitely: */ | +| | sharedState2.compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | +| | switch (reason: active lock detected) | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | All unfinished threads are in deadlock Detailed trace: -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| two(): 2 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | | -| set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | | -| result: 2 | | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | one(): 1 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | -| | result: 1 | -| | one(): | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | switch | -| two(): | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| /* The following events repeat infinitely: */ | | -| compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | -| set(0,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:102) | | -| set(1,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:103) | | -| set(2,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:104) | | -| set(3,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:105) | | -| set(4,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:106) | | -| set(5,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:107) | | -| set(6,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:108) | | -| switch (reason: active lock detected) | | -| | /* The following events repeat infinitely: */ | -| | compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | -| | set(0,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:102) | -| | set(1,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:103) | -| | set(2,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:104) | -| | set(3,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:105) | -| | set(4,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:106) | -| | set(5,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:107) | -| | set(6,0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:108) | -| | switch (reason: active lock detected) | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| two(): 2 | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | | +| result: 2 | | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | one(): 1 | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | +| | result: 1 | +| | one(): | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | switch | +| two(): | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| /* The following events repeat infinitely: */ | | +| sharedState1.compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | +| data[0].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:102) | | +| data[1].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:103) | | +| data[2].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:104) | | +| data[3].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:105) | | +| data[4].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:106) | | +| data[5].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:107) | | +| data[6].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:108) | | +| switch (reason: active lock detected) | | +| | /* The following events repeat infinitely: */ | +| | sharedState2.compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | +| | data[0].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:102) | +| | data[1].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:103) | +| | data[2].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:104) | +| | data[3].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:105) | +| | data[4].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:106) | +| | data[5].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:107) | +| | data[6].set(0) at SpinlockEventsCutLongCycleActionsTest.meaninglessActions(SpinlockEventsCutTests.kt:108) | +| | switch (reason: active lock detected) | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | All unfinished threads are in deadlock diff --git a/src/jvm/test/resources/expected_logs/spin_lock_events_cut_single_action_cycle.txt b/src/jvm/test/resources/expected_logs/spin_lock_events_cut_single_action_cycle.txt index c58acbc54..c91a33d55 100644 --- a/src/jvm/test/resources/expected_logs/spin_lock_events_cut_single_action_cycle.txt +++ b/src/jvm/test/resources/expected_logs/spin_lock_events_cut_single_action_cycle.txt @@ -21,108 +21,108 @@ All operations above the horizontal line | ----- | happen before those below the The following interleaving leads to the error: -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| one(): 1 | | -| one(): 1 | | -| one(): 1 | | -| one(): 1 | | -| two(): 2 | | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | two(): 2 | -| | two(): 2 | -| | two(): 2 | -| | one(): 1 | -| | one(): | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | switch | -| two(): | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| /* The following events repeat infinitely: */ | | -| compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | -| switch (reason: active lock detected) | | -| | /* The following events repeat infinitely: */ | -| | compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | -| | switch (reason: active lock detected) | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| one(): 1 | | +| one(): 1 | | +| one(): 1 | | +| one(): 1 | | +| two(): 2 | | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | two(): 2 | +| | two(): 2 | +| | two(): 2 | +| | one(): 1 | +| | one(): | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | switch | +| two(): | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| /* The following events repeat infinitely: */ | | +| sharedState1.compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | +| switch (reason: active lock detected) | | +| | /* The following events repeat infinitely: */ | +| | sharedState2.compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | +| | switch (reason: active lock detected) | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | All unfinished threads are in deadlock Detailed trace: -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| two(): 2 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | | -| set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | | -| result: 2 | | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | one(): 1 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | -| | result: 1 | -| | one(): | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | switch | -| two(): | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| /* The following events repeat infinitely: */ | | -| compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | -| get(): false at SpinlockEventsCutShortLengthTest.meaninglessActions(SpinlockEventsCutTests.kt:56) | | -| switch (reason: active lock detected) | | -| | /* The following events repeat infinitely: */ | -| | compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | -| | get(): false at SpinlockEventsCutShortLengthTest.meaninglessActions(SpinlockEventsCutTests.kt:56) | -| | switch (reason: active lock detected) | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| two(): 2 | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | | +| result: 2 | | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | one(): 1 | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | +| | result: 1 | +| | one(): | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | switch | +| two(): | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| /* The following events repeat infinitely: */ | | +| sharedState1.compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | +| sharedStateAny.get(): false at SpinlockEventsCutShortLengthTest.meaninglessActions(SpinlockEventsCutTests.kt:56) | | +| switch (reason: active lock detected) | | +| | /* The following events repeat infinitely: */ | +| | sharedState2.compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | +| | sharedStateAny.get(): false at SpinlockEventsCutShortLengthTest.meaninglessActions(SpinlockEventsCutTests.kt:56) | +| | switch (reason: active lock detected) | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | All unfinished threads are in deadlock diff --git a/src/jvm/test/resources/expected_logs/spin_lock_events_cut_two_actions_cycle.txt b/src/jvm/test/resources/expected_logs/spin_lock_events_cut_two_actions_cycle.txt index 2aee5d2ce..e7f77cc61 100644 --- a/src/jvm/test/resources/expected_logs/spin_lock_events_cut_two_actions_cycle.txt +++ b/src/jvm/test/resources/expected_logs/spin_lock_events_cut_two_actions_cycle.txt @@ -21,110 +21,110 @@ All operations above the horizontal line | ----- | happen before those below the The following interleaving leads to the error: -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| one(): 1 | | -| one(): 1 | | -| one(): 1 | | -| one(): 1 | | -| two(): 2 | | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | two(): 2 | -| | two(): 2 | -| | two(): 2 | -| | one(): 1 | -| | one(): | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | switch | -| two(): | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| /* The following events repeat infinitely: */ | | -| compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | -| switch (reason: active lock detected) | | -| | /* The following events repeat infinitely: */ | -| | compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | -| | switch (reason: active lock detected) | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| one(): 1 | | +| one(): 1 | | +| one(): 1 | | +| one(): 1 | | +| two(): 2 | | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | two(): 2 | +| | two(): 2 | +| | two(): 2 | +| | one(): 1 | +| | one(): | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | switch | +| two(): | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| /* The following events repeat infinitely: */ | | +| sharedState1.compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | +| switch (reason: active lock detected) | | +| | /* The following events repeat infinitely: */ | +| | sharedState2.compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | +| | switch (reason: active lock detected) | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | All unfinished threads are in deadlock Detailed trace: -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| one(): 1 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | -| set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | -| result: 1 | | -| two(): 2 | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | | -| set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | | -| result: 2 | | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | two(): 2 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | -| | set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | -| | result: 2 | -| | one(): 1 | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | -| | set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | -| | result: 1 | -| | one(): | -| | compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | -| | switch | -| two(): | | -| compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | -| /* The following events repeat infinitely: */ | | -| compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | -| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | -| get(): false at SpinlockEventsCutMiddleLengthTest.meaninglessActions(SpinlockEventsCutTests.kt:71) | | -| set(true) at SpinlockEventsCutMiddleLengthTest.meaninglessActions(SpinlockEventsCutTests.kt:72) | | -| switch (reason: active lock detected) | | -| | /* The following events repeat infinitely: */ | -| | compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | -| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | -| | get(): true at SpinlockEventsCutMiddleLengthTest.meaninglessActions(SpinlockEventsCutTests.kt:71) | -| | set(false) at SpinlockEventsCutMiddleLengthTest.meaninglessActions(SpinlockEventsCutTests.kt:72) | -| | switch (reason: active lock detected) | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| one(): 1 | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | | +| result: 1 | | +| two(): 2 | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | | +| sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | | +| result: 2 | | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | two(): 2 | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:156) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:157) | +| | result: 2 | +| | one(): 1 | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:142) | +| | sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:143) | +| | result: 1 | +| | one(): | +| | sharedState1.compareAndSet(false,true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:136) | +| | switch | +| two(): | | +| sharedState2.compareAndSet(false,true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:150) | | +| /* The following events repeat infinitely: */ | | +| sharedState1.compareAndSet(false,true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:153) | | +| meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:154) | | +| sharedStateAny.get(): false at SpinlockEventsCutMiddleLengthTest.meaninglessActions(SpinlockEventsCutTests.kt:71) | | +| sharedStateAny.set(true) at SpinlockEventsCutMiddleLengthTest.meaninglessActions(SpinlockEventsCutTests.kt:72) | | +| switch (reason: active lock detected) | | +| | /* The following events repeat infinitely: */ | +| | sharedState2.compareAndSet(false,true): false at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:139) | +| | meaninglessActions() at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:140) | +| | sharedStateAny.get(): true at SpinlockEventsCutMiddleLengthTest.meaninglessActions(SpinlockEventsCutTests.kt:71) | +| | sharedStateAny.set(false) at SpinlockEventsCutMiddleLengthTest.meaninglessActions(SpinlockEventsCutTests.kt:72) | +| | switch (reason: active lock detected) | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | All unfinished threads are in deadlock diff --git a/src/jvm/test/resources/expected_logs/state_representation.txt b/src/jvm/test/resources/expected_logs/state_representation.txt index 0a0c22f5f..7134fd5a0 100644 --- a/src/jvm/test/resources/expected_logs/state_representation.txt +++ b/src/jvm/test/resources/expected_logs/state_representation.txt @@ -15,13 +15,13 @@ The following interleaving leads to the error: | ---------------------------------------------------------------------------------------------------------------------------- | | | operation(): 3 | | | counter.READ: AtomicInteger#1 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:35) | -| | incrementAndGet(): 1 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:35) | +| | counter.incrementAndGet(): 1 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:35) | | | STATE: 1 | | | counter.READ: AtomicInteger#1 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:36) | | | switch | | operation(): 2 | | | STATE: 3 | | -| | getAndIncrement(): 3 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:36) | +| | counter.getAndIncrement(): 3 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:36) | | | STATE: 4 | | | result: 3 | | ---------------------------------------------------------------------------------------------------------------------------- | @@ -32,19 +32,19 @@ Detailed trace: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | | operation(): 3 | | | counter.READ: AtomicInteger#1 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:35) | -| | incrementAndGet(): 1 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:35) | +| | counter.incrementAndGet(): 1 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:35) | | | STATE: 1 | | | counter.READ: AtomicInteger#1 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:36) | | | switch | | operation(): 2 | | | counter.READ: AtomicInteger#1 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:35) | | -| incrementAndGet(): 2 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:35) | | +| counter.incrementAndGet(): 2 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:35) | | | STATE: 2 | | | counter.READ: AtomicInteger#1 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:36) | | -| getAndIncrement(): 2 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:36) | | +| counter.getAndIncrement(): 2 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:36) | | | STATE: 3 | | | result: 2 | | -| | getAndIncrement(): 3 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:36) | +| | counter.getAndIncrement(): 3 at ModelCheckingStateReportingTest.operation(StateRepresentationTest.kt:36) | | | STATE: 4 | | | result: 3 | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/sun_unsafe_trace.txt b/src/jvm/test/resources/expected_logs/sun_unsafe_trace.txt index a17967051..a004b6f20 100644 --- a/src/jvm/test/resources/expected_logs/sun_unsafe_trace.txt +++ b/src/jvm/test/resources/expected_logs/sun_unsafe_trace.txt @@ -10,33 +10,33 @@ The following interleaving leads to the error: | Thread 1 | Thread 2 | | -------------------------------------------------------------------------------------------------------------------------------------------- | | | increment(): 0 | -| | counter.READ: 0 at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:37) | +| | counter.READ: 0 at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:35) | | | switch | | increment(): 0 | | -| | counter.WRITE(1) at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:37) | -| | actionsJustForTrace() at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:38) | +| | counter.WRITE(1) at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:35) | +| | actionsJustForTrace() at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:36) | | | result: 0 | | -------------------------------------------------------------------------------------------------------------------------------------------- | Detailed trace: -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | increment(): 0 | -| | counter.READ: 0 at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:37) | -| | switch | -| increment(): 0 | | -| counter.READ: 0 at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:37) | | -| counter.WRITE(1) at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:37) | | -| actionsJustForTrace() at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:38) | | -| node.READ: Node#1 at SunUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:53) | | -| compareAndSwapObject(Node#1,Node#2): true at SunUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:53) | | -| getAndSetObject(Node#3): Node#2 at SunUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:54) | | -| result: 0 | | -| | counter.WRITE(1) at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:37) | -| | actionsJustForTrace() at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:38) | -| | node.READ: Node#3 at SunUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:53) | -| | compareAndSwapObject(Node#3,Node#4): true at SunUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:53) | -| | getAndSetObject(Node#5): Node#4 at SunUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:54) | -| | result: 0 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:35) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:35) | | +| counter.WRITE(1) at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:35) | | +| actionsJustForTrace() at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:36) | | +| node.READ: IntWrapper#1 at SunUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:51) | | +| node.compareAndSwapObject(IntWrapper#1,IntWrapper#2): true at SunUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:51) | | +| node.getAndSetObject(IntWrapper#3): IntWrapper#2 at SunUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:52) | | +| result: 0 | | +| | counter.WRITE(1) at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:35) | +| | actionsJustForTrace() at SunUnsafeTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:36) | +| | node.READ: IntWrapper#3 at SunUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:51) | +| | node.compareAndSwapObject(IntWrapper#3,IntWrapper#4): true at SunUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:51) | +| | node.getAndSetObject(IntWrapper#5): IntWrapper#4 at SunUnsafeTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:52) | +| | result: 0 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/suspend_trace_reporting.txt b/src/jvm/test/resources/expected_logs/suspend_trace_reporting.txt index 3244cfdac..851a8fd77 100644 --- a/src/jvm/test/resources/expected_logs/suspend_trace_reporting.txt +++ b/src/jvm/test/resources/expected_logs/suspend_trace_reporting.txt @@ -11,9 +11,9 @@ The following interleaving leads to the error: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | bar(): -1 | | | barStarted.WRITE(true) at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:38) | | -| lock(null): Unit#1 at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:73) | | -| lock$suspendImpl(MutexImpl#1,null,): Unit#1 at MutexImpl.lock(Mutex.kt:0) | | -| tryLock(null): true at MutexImpl.lock$suspendImpl(Mutex.kt:171) | | +| MutexImpl#1.lock(null): Unit#1 at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:73) | | +| MutexImpl.lock$suspendImpl(MutexImpl#1,null,): Unit#1 at MutexImpl.lock(Mutex.kt:0) | | +| MutexImpl#1.tryLock(null): true at MutexImpl.lock$suspendImpl(Mutex.kt:171) | | | tryLockImpl(null): 0 at MutexImpl.tryLock(Mutex.kt:183) | | | tryAcquire(): true at MutexImpl.tryLockImpl(Mutex.kt:189) | | | owner.get(): at MutexImpl.tryLockImpl(Mutex.kt:190) | | @@ -21,12 +21,12 @@ The following interleaving leads to the error: | | foo(): SUSPENDED + void | | | barStarted.READ: true at SuspendTraceReportingTest.foo(SuspendTraceReportingTest.kt:29) | | | canEnterForbiddenBlock.WRITE(true) at SuspendTraceReportingTest.foo(SuspendTraceReportingTest.kt:29) | -| | lock(null): COROUTINE_SUSPENDED at SuspendTraceReportingTest.foo(SuspendTraceReportingTest.kt:63) | -| | lock$suspendImpl(MutexImpl#1,null,): COROUTINE_SUSPENDED at MutexImpl.lock(Mutex.kt:0) | -| | tryLock(null): false at MutexImpl.lock$suspendImpl(Mutex.kt:171) | -| | lockSuspend(null): COROUTINE_SUSPENDED at MutexImpl.lock$suspendImpl(Mutex.kt:172) | +| | MutexImpl#1.lock(null): COROUTINE_SUSPENDED at SuspendTraceReportingTest.foo(SuspendTraceReportingTest.kt:63) | +| | MutexImpl.lock$suspendImpl(MutexImpl#1,null,): COROUTINE_SUSPENDED at MutexImpl.lock(Mutex.kt:0) | +| | MutexImpl#1.tryLock(null): false at MutexImpl.lock$suspendImpl(Mutex.kt:171) | +| | MutexImpl#1.lockSuspend(null): COROUTINE_SUSPENDED at MutexImpl.lock$suspendImpl(Mutex.kt:172) | | | acquire() at MutexImpl.lockSuspend(Mutex.kt:177) | -| | getResult(): COROUTINE_SUSPENDED at MutexImpl.lockSuspend(Mutex.kt:321) | +| | .getResult(): COROUTINE_SUSPENDED at MutexImpl.lockSuspend(Mutex.kt:321) | | | trySuspend(): true at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:300) | | | getParentHandle(): null at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:310) | | | installParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:311) | @@ -35,110 +35,110 @@ The following interleaving leads to the error: | owner.set(null) at MutexImpl.tryLockImpl(Mutex.kt:191) | | | counter.READ: 0 at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:40) | | | counter.WRITE(1) at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:40) | | -| unlock(null) at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:77) | | +| MutexImpl#1.unlock(null) at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:77) | | | canEnterForbiddenBlock.READ: true at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:42) | | | result: -1 | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | Detailed trace: -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| bar(): -1 | | -| barStarted.WRITE(true) at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:38) | | -| lock(null): Unit#1 at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:73) | | -| lock$suspendImpl(MutexImpl#1,null,): Unit#1 at MutexImpl.lock(Mutex.kt:0) | | -| tryLock(null): true at MutexImpl.lock$suspendImpl(Mutex.kt:171) | | -| tryLockImpl(null): 0 at MutexImpl.tryLock(Mutex.kt:183) | | -| tryAcquire(): true at MutexImpl.tryLockImpl(Mutex.kt:189) | | -| _availablePermits.get(): 1 at SemaphoreImpl.tryAcquire(Semaphore.kt:159) | | -| _availablePermits.compareAndSet(1,0): true at SemaphoreImpl.tryAcquire(Semaphore.kt:171) | | -| owner.get(): at MutexImpl.tryLockImpl(Mutex.kt:190) | | -| switch | | -| | foo(): SUSPENDED + void | -| | barStarted.READ: true at SuspendTraceReportingTest.foo(SuspendTraceReportingTest.kt:29) | -| | canEnterForbiddenBlock.WRITE(true) at SuspendTraceReportingTest.foo(SuspendTraceReportingTest.kt:29) | -| | lock(null): COROUTINE_SUSPENDED at SuspendTraceReportingTest.foo(SuspendTraceReportingTest.kt:63) | -| | lock$suspendImpl(MutexImpl#1,null,): COROUTINE_SUSPENDED at MutexImpl.lock(Mutex.kt:0) | -| | tryLock(null): false at MutexImpl.lock$suspendImpl(Mutex.kt:171) | -| | tryLockImpl(null): 1 at MutexImpl.tryLock(Mutex.kt:183) | -| | tryAcquire(): false at MutexImpl.tryLockImpl(Mutex.kt:189) | -| | _availablePermits.get(): 0 at SemaphoreImpl.tryAcquire(Semaphore.kt:159) | -| | lockSuspend(null): COROUTINE_SUSPENDED at MutexImpl.lock$suspendImpl(Mutex.kt:172) | -| | acquire() at MutexImpl.lockSuspend(Mutex.kt:177) | -| | decPermits(): 0 at SemaphoreImpl.acquire(Semaphore.kt:413) | -| | _availablePermits.getAndDecrement(): 0 at SemaphoreImpl.decPermits(Semaphore.kt:237) | -| | addAcquireToQueue(): true at SemaphoreImpl.acquire(Semaphore.kt:199) | -| | tail.get(): SemaphoreSegment#1 at SemaphoreImpl.addAcquireToQueue(Semaphore.kt:286) | -| | enqIdx.getAndIncrement(): 0 at SemaphoreImpl.addAcquireToQueue(Semaphore.kt:287) | -| | findSegmentInternal(SemaphoreSegment#1,0,createNewSegment$1): SemaphoreSegment#1 at SemaphoreImpl.addAcquireToQueue(Semaphore.kt:432) | -| | isRemoved(): false at ConcurrentLinkedListKt.findSegmentInternal(ConcurrentLinkedList.kt:26) | -| | cleanedAndPointers.get(): 131072 at Segment.isRemoved(ConcurrentLinkedList.kt:222) | -| | tail.get(): SemaphoreSegment#1 at SemaphoreImpl.addAcquireToQueue(Semaphore.kt:433) | -| | compareAndSet(0,null,): true at SemaphoreImpl.addAcquireToQueue(Semaphore.kt:442) | -| | invokeOnCancellation(SemaphoreSegment#1,0) at SemaphoreImpl.addAcquireToQueue(Semaphore.kt:294) | -| | invokeOnCancellation(SemaphoreSegment#1,0) at MutexImpl$CancellableContinuationWithOwner.invokeOnCancellation(Mutex.kt:0) | -| | _decisionAndIndex.get(): 536870911 at CancellableContinuationImpl.invokeOnCancellation(CancellableContinuationImpl.kt:0) | -| | _decisionAndIndex.compareAndSet(536870911,0): true at CancellableContinuationImpl.invokeOnCancellation(CancellableContinuationImpl.kt:392) | -| | invokeOnCancellationImpl(SemaphoreSegment#1) at CancellableContinuationImpl.invokeOnCancellation(CancellableContinuationImpl.kt:394) | -| | _state.get(): Active#1 at CancellableContinuationImpl.invokeOnCancellationImpl(CancellableContinuationImpl.kt:403) | -| | _state.compareAndSet(Active#1,SemaphoreSegment#1): true at CancellableContinuationImpl.invokeOnCancellationImpl(CancellableContinuationImpl.kt:407) | -| | getResult(): COROUTINE_SUSPENDED at MutexImpl.lockSuspend(Mutex.kt:321) | -| | trySuspend(): true at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:300) | -| | _decisionAndIndex.get(): 0 at CancellableContinuationImpl.trySuspend(CancellableContinuationImpl.kt:0) | -| | _decisionAndIndex.compareAndSet(0,536870912): true at CancellableContinuationImpl.trySuspend(CancellableContinuationImpl.kt:278) | -| | getParentHandle(): null at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:310) | -| | _parentHandle.get(): null at CancellableContinuationImpl.getParentHandle(CancellableContinuationImpl.kt:106) | -| | installParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:311) | -| | _parentHandle.compareAndSet(null,ChildContinuation#1): true at CancellableContinuationImpl.installParentHandle(CancellableContinuationImpl.kt:352) | -| | switch (reason: coroutine is suspended) | -| | result: SUSPENDED + void | -| owner.set(null) at MutexImpl.tryLockImpl(Mutex.kt:191) | | -| counter.READ: 0 at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:40) | | -| counter.WRITE(1) at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:40) | | -| unlock(null) at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:77) | | -| isLocked(): true at MutexImpl.unlock(Mutex.kt:213) | | -| getAvailablePermits(): 0 at MutexImpl.isLocked(Mutex.kt:149) | | -| _availablePermits.get(): -1 at SemaphoreImpl.getAvailablePermits(Semaphore.kt:152) | | -| owner.get(): null at MutexImpl.unlock(Mutex.kt:215) | | -| owner.compareAndSet(null,): true at MutexImpl.unlock(Mutex.kt:220) | | -| release() at MutexImpl.unlock(Mutex.kt:222) | | -| _availablePermits.getAndIncrement(): -1 at SemaphoreImpl.release(Semaphore.kt:250) | | -| tryResumeNextFromQueue(): true at SemaphoreImpl.release(Semaphore.kt:265) | | -| head.get(): SemaphoreSegment#1 at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:319) | | -| deqIdx.getAndIncrement(): 0 at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:320) | | -| findSegmentInternal(SemaphoreSegment#1,0,createNewSegment$1): SemaphoreSegment#1 at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:446) | | -| isRemoved(): false at ConcurrentLinkedListKt.findSegmentInternal(ConcurrentLinkedList.kt:26) | | -| cleanedAndPointers.get(): 131072 at Segment.isRemoved(ConcurrentLinkedList.kt:222) | | -| head.get(): SemaphoreSegment#1 at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:447) | | -| cleanPrev() at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:325) | | -| _prev.lazySet(null) at ConcurrentLinkedListNode.cleanPrev(ConcurrentLinkedList.kt:132) | | -| getAndSet(0,): at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:456) | | -| tryResumeAcquire(): true at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:340) | | -| tryResume(Unit#1,null,onCancellationRelease$1): at SemaphoreImpl.tryResumeAcquire(Semaphore.kt:347) | | -| tryResume(Unit#1,null,onCancellationRelease$1): at MutexImpl$CancellableContinuationWithOwner.tryResume(Mutex.kt:250) | | -| owner.get(): at MutexImpl$CancellableContinuationWithOwner.tryResume(Mutex.kt:257) | | -| tryResume(Unit#1,null,token$1): at MutexImpl$CancellableContinuationWithOwner.tryResume(Mutex.kt:258) | | -| tryResumeImpl(Unit#1,null,token$1): at CancellableContinuationImpl.tryResume(CancellableContinuationImpl.kt:582) | | -| _state.get(): SemaphoreSegment#1 at CancellableContinuationImpl.tryResumeImpl(CancellableContinuationImpl.kt:0) | | -| _state.compareAndSet(SemaphoreSegment#1,CompletedContinuation#1): true at CancellableContinuationImpl.tryResumeImpl(CancellableContinuationImpl.kt:541) | | -| detachChildIfNonResuable() at CancellableContinuationImpl.tryResumeImpl(CancellableContinuationImpl.kt:542) | | -| detachChild$kotlinx_coroutines_core() at CancellableContinuationImpl.detachChildIfNonResuable(CancellableContinuationImpl.kt:565) | | -| getParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.detachChild$kotlinx_coroutines_core(CancellableContinuationImpl.kt:572) | | -| _parentHandle.get(): ChildContinuation#1 at CancellableContinuationImpl.getParentHandle(CancellableContinuationImpl.kt:106) | | -| _parentHandle.set(NonDisposableHandle#1) at CancellableContinuationImpl.detachChild$kotlinx_coroutines_core(CancellableContinuationImpl.kt:574) | | -| owner.get(): at MutexImpl$CancellableContinuationWithOwner.tryResume(Mutex.kt:264) | | -| owner.set(null) at MutexImpl$CancellableContinuationWithOwner.tryResume(Mutex.kt:265) | | -| completeResume() at SemaphoreImpl.tryResumeAcquire(Semaphore.kt:349) | | -| completeResume() at MutexImpl$CancellableContinuationWithOwner.completeResume(Mutex.kt:0) | | -| dispatchResume(1) at CancellableContinuationImpl.completeResume(CancellableContinuationImpl.kt:590) | | -| tryResume(): false at CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:472) | | -| _decisionAndIndex.get(): 536870912 at CancellableContinuationImpl.tryResume(CancellableContinuationImpl.kt:0) | | -| dispatch(,1) at CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:474) | | -| resume(,,false) at DispatchedTaskKt.dispatch(DispatchedTask.kt:168) | | -| takeState$kotlinx_coroutines_core(): CompletedContinuation#1 at DispatchedTaskKt.resume(DispatchedTask.kt:174) | | -| getState$kotlinx_coroutines_core(): CompletedContinuation#1 at CancellableContinuationImpl.takeState$kotlinx_coroutines_core(CancellableContinuationImpl.kt:168) | | -| _state.get(): CompletedContinuation#1 at CancellableContinuationImpl.getState$kotlinx_coroutines_core(CancellableContinuationImpl.kt:108) | | -| canEnterForbiddenBlock.READ: true at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:42) | | -| result: -1 | | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| bar(): -1 | | +| barStarted.WRITE(true) at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:38) | | +| MutexImpl#1.lock(null): Unit#1 at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:73) | | +| MutexImpl.lock$suspendImpl(MutexImpl#1,null,): Unit#1 at MutexImpl.lock(Mutex.kt:0) | | +| MutexImpl#1.tryLock(null): true at MutexImpl.lock$suspendImpl(Mutex.kt:171) | | +| tryLockImpl(null): 0 at MutexImpl.tryLock(Mutex.kt:183) | | +| tryAcquire(): true at MutexImpl.tryLockImpl(Mutex.kt:189) | | +| _availablePermits.get(): 1 at SemaphoreImpl.tryAcquire(Semaphore.kt:159) | | +| _availablePermits.compareAndSet(1,0): true at SemaphoreImpl.tryAcquire(Semaphore.kt:171) | | +| owner.get(): at MutexImpl.tryLockImpl(Mutex.kt:190) | | +| switch | | +| | foo(): SUSPENDED + void | +| | barStarted.READ: true at SuspendTraceReportingTest.foo(SuspendTraceReportingTest.kt:29) | +| | canEnterForbiddenBlock.WRITE(true) at SuspendTraceReportingTest.foo(SuspendTraceReportingTest.kt:29) | +| | MutexImpl#1.lock(null): COROUTINE_SUSPENDED at SuspendTraceReportingTest.foo(SuspendTraceReportingTest.kt:63) | +| | MutexImpl.lock$suspendImpl(MutexImpl#1,null,): COROUTINE_SUSPENDED at MutexImpl.lock(Mutex.kt:0) | +| | MutexImpl#1.tryLock(null): false at MutexImpl.lock$suspendImpl(Mutex.kt:171) | +| | tryLockImpl(null): 1 at MutexImpl.tryLock(Mutex.kt:183) | +| | tryAcquire(): false at MutexImpl.tryLockImpl(Mutex.kt:189) | +| | _availablePermits.get(): 0 at SemaphoreImpl.tryAcquire(Semaphore.kt:159) | +| | MutexImpl#1.lockSuspend(null): COROUTINE_SUSPENDED at MutexImpl.lock$suspendImpl(Mutex.kt:172) | +| | acquire() at MutexImpl.lockSuspend(Mutex.kt:177) | +| | decPermits(): 0 at SemaphoreImpl.acquire(Semaphore.kt:413) | +| | _availablePermits.getAndDecrement(): 0 at SemaphoreImpl.decPermits(Semaphore.kt:237) | +| | addAcquireToQueue(): true at SemaphoreImpl.acquire(Semaphore.kt:199) | +| | tail.get(): SemaphoreSegment#1 at SemaphoreImpl.addAcquireToQueue(Semaphore.kt:286) | +| | enqIdx.getAndIncrement(): 0 at SemaphoreImpl.addAcquireToQueue(Semaphore.kt:287) | +| | ConcurrentLinkedListKt.findSegmentInternal(SemaphoreSegment#1,0,createNewSegment$1): SemaphoreSegment#1 at SemaphoreImpl.addAcquireToQueue(Semaphore.kt:432) | +| | SemaphoreSegment#1.isRemoved(): false at ConcurrentLinkedListKt.findSegmentInternal(ConcurrentLinkedList.kt:26) | +| | cleanedAndPointers.get(): 131072 at Segment.isRemoved(ConcurrentLinkedList.kt:222) | +| | tail.get(): SemaphoreSegment#1 at SemaphoreImpl.addAcquireToQueue(Semaphore.kt:433) | +| | SemaphoreSegment#1.acquirers[0].compareAndSet(null,): true at SemaphoreImpl.addAcquireToQueue(Semaphore.kt:442) | +| | .invokeOnCancellation(SemaphoreSegment#1,0) at SemaphoreImpl.addAcquireToQueue(Semaphore.kt:294) | +| | .invokeOnCancellation(SemaphoreSegment#1,0) at MutexImpl$CancellableContinuationWithOwner.invokeOnCancellation(Mutex.kt:0) | +| | _decisionAndIndex.get(): 536870911 at CancellableContinuationImpl.invokeOnCancellation(CancellableContinuationImpl.kt:0) | +| | _decisionAndIndex.compareAndSet(536870911,0): true at CancellableContinuationImpl.invokeOnCancellation(CancellableContinuationImpl.kt:392) | +| | invokeOnCancellationImpl(SemaphoreSegment#1) at CancellableContinuationImpl.invokeOnCancellation(CancellableContinuationImpl.kt:394) | +| | _state.get(): Active#1 at CancellableContinuationImpl.invokeOnCancellationImpl(CancellableContinuationImpl.kt:403) | +| | _state.compareAndSet(Active#1,SemaphoreSegment#1): true at CancellableContinuationImpl.invokeOnCancellationImpl(CancellableContinuationImpl.kt:407) | +| | .getResult(): COROUTINE_SUSPENDED at MutexImpl.lockSuspend(Mutex.kt:321) | +| | trySuspend(): true at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:300) | +| | _decisionAndIndex.get(): 0 at CancellableContinuationImpl.trySuspend(CancellableContinuationImpl.kt:0) | +| | _decisionAndIndex.compareAndSet(0,536870912): true at CancellableContinuationImpl.trySuspend(CancellableContinuationImpl.kt:278) | +| | getParentHandle(): null at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:310) | +| | _parentHandle.get(): null at CancellableContinuationImpl.getParentHandle(CancellableContinuationImpl.kt:106) | +| | installParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:311) | +| | _parentHandle.compareAndSet(null,ChildContinuation#1): true at CancellableContinuationImpl.installParentHandle(CancellableContinuationImpl.kt:352) | +| | switch (reason: coroutine is suspended) | +| | result: SUSPENDED + void | +| owner.set(null) at MutexImpl.tryLockImpl(Mutex.kt:191) | | +| counter.READ: 0 at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:40) | | +| counter.WRITE(1) at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:40) | | +| MutexImpl#1.unlock(null) at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:77) | | +| isLocked(): true at MutexImpl.unlock(Mutex.kt:213) | | +| getAvailablePermits(): 0 at MutexImpl.isLocked(Mutex.kt:149) | | +| _availablePermits.get(): -1 at SemaphoreImpl.getAvailablePermits(Semaphore.kt:152) | | +| owner.get(): null at MutexImpl.unlock(Mutex.kt:215) | | +| owner.compareAndSet(null,): true at MutexImpl.unlock(Mutex.kt:220) | | +| release() at MutexImpl.unlock(Mutex.kt:222) | | +| _availablePermits.getAndIncrement(): -1 at SemaphoreImpl.release(Semaphore.kt:250) | | +| tryResumeNextFromQueue(): true at SemaphoreImpl.release(Semaphore.kt:265) | | +| head.get(): SemaphoreSegment#1 at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:319) | | +| deqIdx.getAndIncrement(): 0 at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:320) | | +| ConcurrentLinkedListKt.findSegmentInternal(SemaphoreSegment#1,0,createNewSegment$1): SemaphoreSegment#1 at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:446) | | +| SemaphoreSegment#1.isRemoved(): false at ConcurrentLinkedListKt.findSegmentInternal(ConcurrentLinkedList.kt:26) | | +| cleanedAndPointers.get(): 131072 at Segment.isRemoved(ConcurrentLinkedList.kt:222) | | +| head.get(): SemaphoreSegment#1 at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:447) | | +| SemaphoreSegment#1.cleanPrev() at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:325) | | +| _prev.lazySet(null) at ConcurrentLinkedListNode.cleanPrev(ConcurrentLinkedList.kt:132) | | +| SemaphoreSegment#1.acquirers[0].getAndSet(): at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:456) | | +| tryResumeAcquire(): true at SemaphoreImpl.tryResumeNextFromQueue(Semaphore.kt:340) | | +| .tryResume(Unit#1,null,onCancellationRelease$1): at SemaphoreImpl.tryResumeAcquire(Semaphore.kt:347) | | +| tryResume(Unit#1,null,onCancellationRelease$1): at MutexImpl$CancellableContinuationWithOwner.tryResume(Mutex.kt:250) | | +| owner.get(): at MutexImpl$CancellableContinuationWithOwner.tryResume(Mutex.kt:257) | | +| .tryResume(Unit#1,null,token$1): at MutexImpl$CancellableContinuationWithOwner.tryResume(Mutex.kt:258) | | +| tryResumeImpl(Unit#1,null,token$1): at CancellableContinuationImpl.tryResume(CancellableContinuationImpl.kt:582) | | +| _state.get(): SemaphoreSegment#1 at CancellableContinuationImpl.tryResumeImpl(CancellableContinuationImpl.kt:0) | | +| _state.compareAndSet(SemaphoreSegment#1,CompletedContinuation#1): true at CancellableContinuationImpl.tryResumeImpl(CancellableContinuationImpl.kt:541) | | +| detachChildIfNonResuable() at CancellableContinuationImpl.tryResumeImpl(CancellableContinuationImpl.kt:542) | | +| detachChild$kotlinx_coroutines_core() at CancellableContinuationImpl.detachChildIfNonResuable(CancellableContinuationImpl.kt:565) | | +| getParentHandle(): ChildContinuation#1 at CancellableContinuationImpl.detachChild$kotlinx_coroutines_core(CancellableContinuationImpl.kt:572) | | +| _parentHandle.get(): ChildContinuation#1 at CancellableContinuationImpl.getParentHandle(CancellableContinuationImpl.kt:106) | | +| _parentHandle.set(NonDisposableHandle#1) at CancellableContinuationImpl.detachChild$kotlinx_coroutines_core(CancellableContinuationImpl.kt:574) | | +| owner.get(): at MutexImpl$CancellableContinuationWithOwner.tryResume(Mutex.kt:264) | | +| owner.set(null) at MutexImpl$CancellableContinuationWithOwner.tryResume(Mutex.kt:265) | | +| .completeResume() at SemaphoreImpl.tryResumeAcquire(Semaphore.kt:349) | | +| .completeResume() at MutexImpl$CancellableContinuationWithOwner.completeResume(Mutex.kt:0) | | +| dispatchResume(1) at CancellableContinuationImpl.completeResume(CancellableContinuationImpl.kt:590) | | +| tryResume(): false at CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:472) | | +| _decisionAndIndex.get(): 536870912 at CancellableContinuationImpl.tryResume(CancellableContinuationImpl.kt:0) | | +| DispatchedTaskKt.dispatch(,1) at CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:474) | | +| DispatchedTaskKt.resume(,,false) at DispatchedTaskKt.dispatch(DispatchedTask.kt:168) | | +| .takeState$kotlinx_coroutines_core(): CompletedContinuation#1 at DispatchedTaskKt.resume(DispatchedTask.kt:174) | | +| getState$kotlinx_coroutines_core(): CompletedContinuation#1 at CancellableContinuationImpl.takeState$kotlinx_coroutines_core(CancellableContinuationImpl.kt:168) | | +| _state.get(): CompletedContinuation#1 at CancellableContinuationImpl.getState$kotlinx_coroutines_core(CancellableContinuationImpl.kt:108) | | +| canEnterForbiddenBlock.READ: true at SuspendTraceReportingTest.bar(SuspendTraceReportingTest.kt:42) | | +| result: -1 | | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/switch_in_the_middle_of_spin_cycle_causes_error.txt b/src/jvm/test/resources/expected_logs/switch_in_the_middle_of_spin_cycle_causes_error.txt index afb1eb5b2..d336ddebb 100644 --- a/src/jvm/test/resources/expected_logs/switch_in_the_middle_of_spin_cycle_causes_error.txt +++ b/src/jvm/test/resources/expected_logs/switch_in_the_middle_of_spin_cycle_causes_error.txt @@ -17,31 +17,31 @@ The following interleaving leads to the error: | | switch | | causeSpinLock(): IllegalStateException #1 | | | counter.READ: AtomicInteger#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:39) | | -| incrementAndGet(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:39) | | +| counter.incrementAndGet(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:39) | | | shouldAlwaysBeZero.READ: AtomicInteger#2 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:41) | | | switch | | | | counter.READ: AtomicInteger#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:50) | | | /* The following events repeat infinitely: */ | -| | get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:50) | +| | counter.get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:50) | | | counter.READ: AtomicInteger#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:51) | -| | get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:51) | +| | counter.get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:51) | | | shouldAlwaysBeZero.READ: AtomicInteger#2 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:52) | -| | incrementAndGet(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:52) | +| | shouldAlwaysBeZero.incrementAndGet(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:52) | | | illegalInterleavingFound.READ: AtomicBoolean#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:53) | -| | get(): false at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:53) | +| | illegalInterleavingFound.get(): false at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:53) | | | shouldAlwaysBeZero.READ: AtomicInteger#2 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:54) | | | switch (reason: active lock detected) | -| get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:41) | | +| shouldAlwaysBeZero.get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:41) | | | illegalInterleavingFound.READ: AtomicBoolean#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:42) | | -| set(true) at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:42) | | +| illegalInterleavingFound.set(true) at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:42) | | | result: IllegalStateException #1 | | -| | decrementAndGet(): 0 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:54) | +| | shouldAlwaysBeZero.decrementAndGet(): 0 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:54) | | | counter.READ: AtomicInteger#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:51) | -| | get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:51) | +| | counter.get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:51) | | | shouldAlwaysBeZero.READ: AtomicInteger#2 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:52) | -| | incrementAndGet(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:52) | +| | shouldAlwaysBeZero.incrementAndGet(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:52) | | | illegalInterleavingFound.READ: AtomicBoolean#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:53) | -| | get(): true at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:53) | +| | illegalInterleavingFound.get(): true at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:53) | | | result: IllegalStateException #2 | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -60,30 +60,30 @@ Detailed trace: | | switch | | causeSpinLock(): IllegalStateException #1 | | | counter.READ: AtomicInteger#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:39) | | -| incrementAndGet(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:39) | | +| counter.incrementAndGet(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:39) | | | shouldAlwaysBeZero.READ: AtomicInteger#2 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:41) | | | switch | | | | counter.READ: AtomicInteger#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:50) | | | /* The following events repeat infinitely: */ | -| | get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:50) | +| | counter.get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:50) | | | counter.READ: AtomicInteger#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:51) | -| | get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:51) | +| | counter.get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:51) | | | shouldAlwaysBeZero.READ: AtomicInteger#2 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:52) | -| | incrementAndGet(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:52) | +| | shouldAlwaysBeZero.incrementAndGet(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:52) | | | illegalInterleavingFound.READ: AtomicBoolean#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:53) | -| | get(): false at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:53) | +| | illegalInterleavingFound.get(): false at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:53) | | | shouldAlwaysBeZero.READ: AtomicInteger#2 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:54) | | | switch (reason: active lock detected) | -| get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:41) | | +| shouldAlwaysBeZero.get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:41) | | | illegalInterleavingFound.READ: AtomicBoolean#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:42) | | -| set(true) at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:42) | | +| illegalInterleavingFound.set(true) at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.causeSpinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:42) | | | result: IllegalStateException #1 | | -| | decrementAndGet(): 0 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:54) | +| | shouldAlwaysBeZero.decrementAndGet(): 0 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:54) | | | counter.READ: AtomicInteger#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:51) | -| | get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:51) | +| | counter.get(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:51) | | | shouldAlwaysBeZero.READ: AtomicInteger#2 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:52) | -| | incrementAndGet(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:52) | +| | shouldAlwaysBeZero.incrementAndGet(): 1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:52) | | | illegalInterleavingFound.READ: AtomicBoolean#1 at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:53) | -| | get(): true at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:53) | +| | illegalInterleavingFound.get(): true at InterleavingAnalysisPresentInSpinCycleFirstIterationTest.spinLock(InterleavingAnalysisPresentInSpinCycleFirstIterationTest.kt:53) | | | result: IllegalStateException #2 | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/unsafe_representation_trace.txt b/src/jvm/test/resources/expected_logs/unsafe_representation_trace.txt new file mode 100644 index 000000000..33382694c --- /dev/null +++ b/src/jvm/test/resources/expected_logs/unsafe_representation_trace.txt @@ -0,0 +1,48 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| Array#1[2].getObject(): IntWrapper#1 at UnsafeTraceRepresentationTest.actionsForTrace(UnsafeTraceRepresentationTest.kt:23) | | +| node.compareAndSwapObject(IntWrapper#2,IntWrapper#3): true at UnsafeTraceRepresentationTest.actionsForTrace(UnsafeTraceRepresentationTest.kt:24) | | +| value.READ: 2 at UnsafeTraceRepresentationTest.actionsForTrace(UnsafeTraceRepresentationTest.kt:25) | | +| value.compareAndSwapInt(2,3): true at UnsafeTraceRepresentationTest.actionsForTrace(UnsafeTraceRepresentationTest.kt:25) | | +| UnsafeTraceRepresentationTest.staticNode.compareAndSwapObject(IntWrapper#4,IntWrapper#5): false at UnsafeTraceRepresentationTest.actionsForTrace(UnsafeTraceRepresentationTest.kt:27) | | +| IntWrapper#3.value.compareAndSwapInt(4,6): true at UnsafeTraceRepresentationTest.actionsForTrace(UnsafeTraceRepresentationTest.kt:28) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | Array#1[2].getObject(): IntWrapper#1 at UnsafeTraceRepresentationTest.actionsForTrace(UnsafeTraceRepresentationTest.kt:23) | +| | node.compareAndSwapObject(IntWrapper#3,IntWrapper#6): true at UnsafeTraceRepresentationTest.actionsForTrace(UnsafeTraceRepresentationTest.kt:24) | +| | value.READ: 3 at UnsafeTraceRepresentationTest.actionsForTrace(UnsafeTraceRepresentationTest.kt:25) | +| | value.compareAndSwapInt(3,3): true at UnsafeTraceRepresentationTest.actionsForTrace(UnsafeTraceRepresentationTest.kt:25) | +| | UnsafeTraceRepresentationTest.staticNode.compareAndSwapObject(IntWrapper#4,IntWrapper#7): false at UnsafeTraceRepresentationTest.actionsForTrace(UnsafeTraceRepresentationTest.kt:27) | +| | IntWrapper#6.value.compareAndSwapInt(4,6): true at UnsafeTraceRepresentationTest.actionsForTrace(UnsafeTraceRepresentationTest.kt:28) | +| | result: 0 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/var_handle/varhandle_boolean_representation.txt b/src/jvm/test/resources/expected_logs/var_handle/varhandle_boolean_representation.txt new file mode 100644 index 000000000..9a4dd6818 --- /dev/null +++ b/src/jvm/test/resources/expected_logs/var_handle/varhandle_boolean_representation.txt @@ -0,0 +1,56 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| number.READ: false at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:216) | | +| number.compareAndSet(false,false): true at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:216) | | +| number.set(true) at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:217) | | +| VarHandleBooleanRepresentationTest.staticNumber.READ: false at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:219) | | +| VarHandleBooleanRepresentationTest.staticNumber.compareAndSet(false,false): true at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:219) | | +| VarHandleBooleanRepresentationTest.staticNumber.set(false) at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:220) | | +| array.READ: BooleanArray#1 at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:222) | | +| BooleanArray#1[1].compareAndSet(false,false): true at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:222) | | +| array.READ: BooleanArray#1 at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:223) | | +| BooleanArray#1[1].set(true) at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:223) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | number.READ: true at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:216) | +| | number.compareAndSet(true,false): true at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:216) | +| | number.set(true) at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:217) | +| | VarHandleBooleanRepresentationTest.staticNumber.READ: false at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:219) | +| | VarHandleBooleanRepresentationTest.staticNumber.compareAndSet(false,false): true at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:219) | +| | VarHandleBooleanRepresentationTest.staticNumber.set(false) at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:220) | +| | array.READ: BooleanArray#1 at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:222) | +| | BooleanArray#1[1].compareAndSet(false,false): false at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:222) | +| | array.READ: BooleanArray#1 at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:223) | +| | BooleanArray#1[1].set(true) at VarHandleBooleanRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:223) | +| | result: 0 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/var_handle/varhandle_byte_representation.txt b/src/jvm/test/resources/expected_logs/var_handle/varhandle_byte_representation.txt new file mode 100644 index 000000000..89e878595 --- /dev/null +++ b/src/jvm/test/resources/expected_logs/var_handle/varhandle_byte_representation.txt @@ -0,0 +1,56 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| number.READ: 1 at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:142) | | +| number.compareAndSet(1,1): true at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:142) | | +| number.set(2) at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:143) | | +| VarHandleByteRepresentationTest.staticNumber.READ: 3 at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:145) | | +| VarHandleByteRepresentationTest.staticNumber.compareAndSet(3,1): true at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:145) | | +| VarHandleByteRepresentationTest.staticNumber.set(3) at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:146) | | +| array.READ: ByteArray#1 at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:148) | | +| ByteArray#1[1].compareAndSet(3,1): false at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:148) | | +| array.READ: ByteArray#1 at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:149) | | +| ByteArray#1[1].set(2) at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:149) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | number.READ: 2 at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:142) | +| | number.compareAndSet(2,1): true at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:142) | +| | number.set(2) at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:143) | +| | VarHandleByteRepresentationTest.staticNumber.READ: 3 at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:145) | +| | VarHandleByteRepresentationTest.staticNumber.compareAndSet(3,1): true at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:145) | +| | VarHandleByteRepresentationTest.staticNumber.set(3) at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:146) | +| | array.READ: ByteArray#1 at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:148) | +| | ByteArray#1[1].compareAndSet(3,1): false at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:148) | +| | array.READ: ByteArray#1 at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:149) | +| | ByteArray#1[1].set(2) at VarHandleByteRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:149) | +| | result: 0 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/var_handle/varhandle_char_representation.txt b/src/jvm/test/resources/expected_logs/var_handle/varhandle_char_representation.txt new file mode 100644 index 000000000..4f658fe37 --- /dev/null +++ b/src/jvm/test/resources/expected_logs/var_handle/varhandle_char_representation.txt @@ -0,0 +1,56 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| number.READ: 1 at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:179) | | +| number.compareAndSet(1,1): true at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:179) | | +| number.set(2) at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:180) | | +| VarHandleCharRepresentationTest.staticNumber.READ: 3 at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:182) | | +| VarHandleCharRepresentationTest.staticNumber.compareAndSet(3,1): true at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:182) | | +| VarHandleCharRepresentationTest.staticNumber.set(3) at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:183) | | +| array.READ: CharArray#1 at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:185) | | +| CharArray#1[1].compareAndSet(3,1): false at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:185) | | +| array.READ: CharArray#1 at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:186) | | +| CharArray#1[1].set(2) at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:186) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | number.READ: 2 at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:179) | +| | number.compareAndSet(2,1): true at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:179) | +| | number.set(2) at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:180) | +| | VarHandleCharRepresentationTest.staticNumber.READ: 3 at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:182) | +| | VarHandleCharRepresentationTest.staticNumber.compareAndSet(3,1): true at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:182) | +| | VarHandleCharRepresentationTest.staticNumber.set(3) at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:183) | +| | array.READ: CharArray#1 at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:185) | +| | CharArray#1[1].compareAndSet(3,1): false at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:185) | +| | array.READ: CharArray#1 at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:186) | +| | CharArray#1[1].set(2) at VarHandleCharRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:186) | +| | result: 0 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/var_handle/varhandle_double_representation.txt b/src/jvm/test/resources/expected_logs/var_handle/varhandle_double_representation.txt new file mode 100644 index 000000000..e4682bf6e --- /dev/null +++ b/src/jvm/test/resources/expected_logs/var_handle/varhandle_double_representation.txt @@ -0,0 +1,56 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| number.READ: 1.0 at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:327) | | +| number.compareAndSet(1.0,1.0): true at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:327) | | +| number.set(2.0) at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:328) | | +| VarHandleDoubleRepresentationTest.staticNumber.READ: 3.0 at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:330) | | +| VarHandleDoubleRepresentationTest.staticNumber.compareAndSet(3.0,1.0): true at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:330) | | +| VarHandleDoubleRepresentationTest.staticNumber.set(3.0) at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:331) | | +| array.READ: DoubleArray#1 at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:333) | | +| DoubleArray#1[1].compareAndSet(3.0,1.0): false at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:333) | | +| array.READ: DoubleArray#1 at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:334) | | +| DoubleArray#1[1].set(2.0) at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:334) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | number.READ: 2.0 at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:327) | +| | number.compareAndSet(2.0,1.0): true at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:327) | +| | number.set(2.0) at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:328) | +| | VarHandleDoubleRepresentationTest.staticNumber.READ: 3.0 at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:330) | +| | VarHandleDoubleRepresentationTest.staticNumber.compareAndSet(3.0,1.0): true at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:330) | +| | VarHandleDoubleRepresentationTest.staticNumber.set(3.0) at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:331) | +| | array.READ: DoubleArray#1 at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:333) | +| | DoubleArray#1[1].compareAndSet(3.0,1.0): false at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:333) | +| | array.READ: DoubleArray#1 at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:334) | +| | DoubleArray#1[1].set(2.0) at VarHandleDoubleRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:334) | +| | result: 0 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/var_handle/varhandle_float_representation.txt b/src/jvm/test/resources/expected_logs/var_handle/varhandle_float_representation.txt new file mode 100644 index 000000000..4634eb4d8 --- /dev/null +++ b/src/jvm/test/resources/expected_logs/var_handle/varhandle_float_representation.txt @@ -0,0 +1,56 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| number.READ: 1.0 at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:290) | | +| number.compareAndSet(1.0,1.0): true at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:290) | | +| number.set(2.0) at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:291) | | +| VarHandleFloatRepresentationTest.staticNumber.READ: 3.0 at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:293) | | +| VarHandleFloatRepresentationTest.staticNumber.compareAndSet(3.0,1.0): true at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:293) | | +| VarHandleFloatRepresentationTest.staticNumber.set(3.0) at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:294) | | +| array.READ: FloatArray#1 at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:296) | | +| FloatArray#1[1].compareAndSet(3.0,1.0): false at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:296) | | +| array.READ: FloatArray#1 at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:297) | | +| FloatArray#1[1].set(2.0) at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:297) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | number.READ: 2.0 at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:290) | +| | number.compareAndSet(2.0,1.0): true at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:290) | +| | number.set(2.0) at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:291) | +| | VarHandleFloatRepresentationTest.staticNumber.READ: 3.0 at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:293) | +| | VarHandleFloatRepresentationTest.staticNumber.compareAndSet(3.0,1.0): true at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:293) | +| | VarHandleFloatRepresentationTest.staticNumber.set(3.0) at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:294) | +| | array.READ: FloatArray#1 at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:296) | +| | FloatArray#1[1].compareAndSet(3.0,1.0): false at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:296) | +| | array.READ: FloatArray#1 at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:297) | +| | FloatArray#1[1].set(2.0) at VarHandleFloatRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:297) | +| | result: 0 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/var_handle/varhandle_int_representation.txt b/src/jvm/test/resources/expected_logs/var_handle/varhandle_int_representation.txt new file mode 100644 index 000000000..6aa3df9b6 --- /dev/null +++ b/src/jvm/test/resources/expected_logs/var_handle/varhandle_int_representation.txt @@ -0,0 +1,56 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| number.READ: 1 at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:70) | | +| number.compareAndSet(1,2): true at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:70) | | +| number.set(3) at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:71) | | +| VarHandleIntRepresentationTest.staticNumber.READ: 3 at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:73) | | +| VarHandleIntRepresentationTest.staticNumber.compareAndSet(3,2): true at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:73) | | +| VarHandleIntRepresentationTest.staticNumber.set(3) at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:74) | | +| array.READ: IntArray#1 at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:76) | | +| IntArray#1[1].compareAndSet(1,1): true at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:76) | | +| array.READ: IntArray#1 at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:77) | | +| IntArray#1[1].set(1) at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:77) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | number.READ: 3 at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:70) | +| | number.compareAndSet(3,2): true at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:70) | +| | number.set(3) at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:71) | +| | VarHandleIntRepresentationTest.staticNumber.READ: 3 at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:73) | +| | VarHandleIntRepresentationTest.staticNumber.compareAndSet(3,2): true at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:73) | +| | VarHandleIntRepresentationTest.staticNumber.set(3) at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:74) | +| | array.READ: IntArray#1 at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:76) | +| | IntArray#1[1].compareAndSet(1,1): true at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:76) | +| | array.READ: IntArray#1 at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:77) | +| | IntArray#1[1].set(1) at VarHandleIntRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:77) | +| | result: 0 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/var_handle/varhandle_long_representation.txt b/src/jvm/test/resources/expected_logs/var_handle/varhandle_long_representation.txt new file mode 100644 index 000000000..bea024558 --- /dev/null +++ b/src/jvm/test/resources/expected_logs/var_handle/varhandle_long_representation.txt @@ -0,0 +1,56 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| number.READ: 1 at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:253) | | +| number.compareAndSet(1,1): true at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:253) | | +| number.set(2) at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:254) | | +| VarHandleLongRepresentationTest.staticNumber.READ: 3 at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:256) | | +| VarHandleLongRepresentationTest.staticNumber.compareAndSet(3,1): true at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:256) | | +| VarHandleLongRepresentationTest.staticNumber.set(3) at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:257) | | +| array.READ: LongArray#1 at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:259) | | +| LongArray#1[1].compareAndSet(3,1): false at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:259) | | +| array.READ: LongArray#1 at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:260) | | +| LongArray#1[1].set(2) at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:260) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | number.READ: 2 at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:253) | +| | number.compareAndSet(2,1): true at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:253) | +| | number.set(2) at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:254) | +| | VarHandleLongRepresentationTest.staticNumber.READ: 3 at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:256) | +| | VarHandleLongRepresentationTest.staticNumber.compareAndSet(3,1): true at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:256) | +| | VarHandleLongRepresentationTest.staticNumber.set(3) at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:257) | +| | array.READ: LongArray#1 at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:259) | +| | LongArray#1[1].compareAndSet(3,1): false at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:259) | +| | array.READ: LongArray#1 at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:260) | +| | LongArray#1[1].set(2) at VarHandleLongRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:260) | +| | result: 0 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/var_handle/varhandle_reference_representation.txt b/src/jvm/test/resources/expected_logs/var_handle/varhandle_reference_representation.txt new file mode 100644 index 000000000..5ff0b4426 --- /dev/null +++ b/src/jvm/test/resources/expected_logs/var_handle/varhandle_reference_representation.txt @@ -0,0 +1,60 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| wrapper.READ: IntWrapper#1 at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:25) | | +| wrapper.compareAndSet(IntWrapper#1,IntWrapper#2): true at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:25) | | +| wrapper.set(IntWrapper#3) at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:26) | | +| wrapper.READ: IntWrapper#3 at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:28) | | +| VarHandleReferenceRepresentationTest.staticWrapper.compareAndSet(IntWrapper#3,IntWrapper#4): false at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:28) | | +| VarHandleReferenceRepresentationTest.staticWrapper.set(IntWrapper#5) at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:29) | | +| array.READ: Array#1 at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:31) | | +| Array#1[1].compareAndSet(IntWrapper#6,IntWrapper#7): false at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:31) | | +| array.READ: Array#1 at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:32) | | +| Array#1[1].set(IntWrapper#8) at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:32) | | +| Wrapper#1.value.compareAndSet(1,2): true at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:34) | | +| Wrapper#1.value.set(3) at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:35) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | wrapper.READ: IntWrapper#3 at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:25) | +| | wrapper.compareAndSet(IntWrapper#3,IntWrapper#9): true at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:25) | +| | wrapper.set(IntWrapper#10) at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:26) | +| | wrapper.READ: IntWrapper#10 at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:28) | +| | VarHandleReferenceRepresentationTest.staticWrapper.compareAndSet(IntWrapper#10,IntWrapper#11): false at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:28) | +| | VarHandleReferenceRepresentationTest.staticWrapper.set(IntWrapper#12) at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:29) | +| | array.READ: Array#1 at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:31) | +| | Array#1[1].compareAndSet(IntWrapper#13,IntWrapper#14): false at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:31) | +| | array.READ: Array#1 at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:32) | +| | Array#1[1].set(IntWrapper#15) at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:32) | +| | Wrapper#1.value.compareAndSet(1,2): false at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:34) | +| | Wrapper#1.value.set(3) at VarHandleReferenceRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:35) | +| | result: 0 | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/var_handle/varhandle_short_representation.txt b/src/jvm/test/resources/expected_logs/var_handle/varhandle_short_representation.txt new file mode 100644 index 000000000..3ee73ea40 --- /dev/null +++ b/src/jvm/test/resources/expected_logs/var_handle/varhandle_short_representation.txt @@ -0,0 +1,56 @@ += Invalid execution results = +| ------------------------------- | +| Thread 1 | Thread 2 | +| ------------------------------- | +| increment(): 0 | increment(): 0 | +| ------------------------------- | + +The following interleaving leads to the error: +| ---------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ---------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | result: 0 | +| ---------------------------------------------------------------------------------------- | + +Detailed trace: +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Thread 1 | Thread 2 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | increment(): 0 | +| | counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | switch | +| increment(): 0 | | +| counter.READ: 0 at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | | +| actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | | +| number.READ: 1 at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:105) | | +| number.compareAndSet(1,1): true at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:105) | | +| number.set(2) at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:106) | | +| VarHandleShortRepresentationTest.staticNumber.READ: 3 at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:108) | | +| VarHandleShortRepresentationTest.staticNumber.compareAndSet(3,1): true at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:108) | | +| VarHandleShortRepresentationTest.staticNumber.set(3) at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:109) | | +| array.READ: ShortArray#1 at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:111) | | +| ShortArray#1[1].compareAndSet(3,1): false at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:111) | | +| array.READ: ShortArray#1 at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:112) | | +| ShortArray#1[1].set(2) at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:112) | | +| result: 0 | | +| | counter.WRITE(1) at BaseFailingTest.increment(BaseFailingTest.kt:30) | +| | actionsForTrace() at BaseFailingTest.increment(BaseFailingTest.kt:31) | +| | number.READ: 2 at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:105) | +| | number.compareAndSet(2,1): true at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:105) | +| | number.set(2) at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:106) | +| | VarHandleShortRepresentationTest.staticNumber.READ: 3 at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:108) | +| | VarHandleShortRepresentationTest.staticNumber.compareAndSet(3,1): true at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:108) | +| | VarHandleShortRepresentationTest.staticNumber.set(3) at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:109) | +| | array.READ: ShortArray#1 at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:111) | +| | ShortArray#1[1].compareAndSet(3,1): false at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:111) | +| | array.READ: ShortArray#1 at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:112) | +| | ShortArray#1[1].set(2) at VarHandleShortRepresentationTest.actionsForTrace(VarHandleRepresentationTests.kt:112) | +| | result: 0 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/src/jvm/test/resources/expected_logs/varhandle_trace.txt b/src/jvm/test/resources/expected_logs/varhandle_trace.txt deleted file mode 100644 index 9e963cb89..000000000 --- a/src/jvm/test/resources/expected_logs/varhandle_trace.txt +++ /dev/null @@ -1,42 +0,0 @@ -= Invalid execution results = -| ------------------------------- | -| Thread 1 | Thread 2 | -| ------------------------------- | -| increment(): 0 | increment(): 0 | -| ------------------------------- | - -The following interleaving leads to the error: -| --------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| --------------------------------------------------------------------------------------------------------------------------------------------- | -| | increment(): 0 | -| | counter.READ: 0 at VarHandleTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:175) | -| | switch | -| increment(): 0 | | -| | counter.WRITE(1) at VarHandleTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:175) | -| | actionsJustForTrace() at VarHandleTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:176) | -| | result: 0 | -| --------------------------------------------------------------------------------------------------------------------------------------------- | - -Detailed trace: -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Thread 1 | Thread 2 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| | increment(): 0 | -| | counter.READ: 0 at VarHandleTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:175) | -| | switch | -| increment(): 0 | | -| counter.READ: 0 at VarHandleTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:175) | | -| counter.WRITE(1) at VarHandleTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:175) | | -| actionsJustForTrace() at VarHandleTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:176) | | -| node.READ: Node#1 at VarHandleTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:191) | | -| compareAndSet(Node#1,Node#2): true at VarHandleTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:191) | | -| set(Node#3) at VarHandleTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:192) | | -| result: 0 | | -| | counter.WRITE(1) at VarHandleTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:175) | -| | actionsJustForTrace() at VarHandleTraceRepresentationTest.increment(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:176) | -| | node.READ: Node#3 at VarHandleTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:191) | -| | compareAndSet(Node#3,Node#4): true at VarHandleTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:191) | -| | set(Node#5) at VarHandleTraceRepresentationTest.actionsJustForTrace(UnsafeUpdaterVarHandleTraceRepresentationTests.kt:192) | -| | result: 0 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |