Skip to content
This repository has been archived by the owner on Aug 10, 2021. It is now read-only.

Very preliminary relaxed mode draft. #3129

Merged
merged 4 commits into from
Jul 4, 2019
Merged

Very preliminary relaxed mode draft. #3129

merged 4 commits into from
Jul 4, 2019

Conversation

olonho
Copy link
Contributor

@olonho olonho commented Jun 28, 2019

No description provided.

@olonho olonho force-pushed the relaxed-mode branch 3 times, most recently from a6e3145 to a8f1e8b Compare July 2, 2019 10:29
void AddRefFromAssociatedObject(const ObjHeader* object) RUNTIME_NOTHROW;
void ReleaseRefFromAssociatedObject(const ObjHeader* object) RUNTIME_NOTHROW;
void ReleaseRefFromAssociatedObject(const ObjHeader* object);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is RUNTIME_NOTHROW removed intentionally?

if (container != nullptr)
enqueueDecrementRC</* CanCollect = */ true>(container);
if (value != nullptr)
ReleaseHeapRef(value);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this remove object before return? (like it was in swapHeapRefLocked).

@@ -1825,12 +1792,12 @@ OBJ_GETTER(swapHeapRefLocked,
shallRelease = oldValue != nullptr;
}
unlock(spinlock);
if (shallRelease) {
releaseHeapRef(oldValue);
}
// No need to rememberNewContainer(), as oldValue is already
// present on this worker.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, is this correct? Doesn't seem so when oldValue != expectedValue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment was indeed wrong.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment is still wrong, and the behaviour is wrong too.
The following test crashes:

import kotlin.test.*
import kotlin.native.concurrent.*

val atomicRef = AtomicReference<Any?>(Any().freeze())
val semaphore = AtomicInt(0)

@Test fun runTest() {
    semaphore.value = 0
    val worker = Worker.start()
    val future = worker.execute(TransferMode.SAFE, { null }) {
        val value = atomicRef.compareAndSwap(null, null)
        semaphore.increment()
        while (semaphore.value != 2) {}
        println(value.toString() != "")
    }
    while (semaphore.value != 1) {}
    atomicRef.value = null
    kotlin.native.internal.GC.collect()
    semaphore.increment()
    future.result
    worker.requestTermination().result
}

(based on worker10).
Generally atomicRef.compareAndSwap(Any().freeze(), null) is the same as atomicRef.value, and if the latter requires rememberNewContainer, then the former requires this too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for bringing my attention to this problem. Fixed.

zeroStackRef<true>(location);
}
void ZeroStackRefRelaxed(ObjHeader** location) {
zeroStackRef<true>(location);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is true correct here?

/**
* If binary was compiled in debug mode.
*/
public val isDebugBinary: Boolean
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe related: #2562

@@ -163,4 +163,22 @@ val stableHolder2 = StableRef.create(("hello" to "world").freeze())
semaphore.increment()
future.result
worker.requestTermination().result
}

@Test fun runTest6() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test doesn't fail even without the fix applied.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, better use fresh atomic ref here.

ReleaseHeapRef(oldValue);
} else {
if (IsStrictMemoryModel && oldValue != expectedValue)
rememberNewContainer(oldValue->container());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it too late to perform this after unlock?

@olonho olonho merged commit 81eb6b2 into master Jul 4, 2019
@olonho olonho deleted the relaxed-mode branch July 4, 2019 10:58
qurbonzoda pushed a commit to qurbonzoda/kotlin-native that referenced this pull request Jul 9, 2019
@omiwrench
Copy link

Could we get some documentation on how to enable this relaxed mode?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants