diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index f887c460182..b6bb39c9f1f 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -1044,6 +1044,12 @@ task worker11(type: KonanLocalTest) { source = "runtime/workers/worker11.kt" } +standaloneTest("worker_threadlocal_no_leak") { + disabled = project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build and pthreads. + source = "runtime/workers/worker_threadlocal_no_leak.kt" + flags = ['-g'] +} + task freeze0(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') // No workers on WASM. goldValue = "frozen bit is true\n" + diff --git a/kotlin-native/backend.native/tests/runtime/workers/worker_threadlocal_no_leak.kt b/kotlin-native/backend.native/tests/runtime/workers/worker_threadlocal_no_leak.kt new file mode 100644 index 00000000000..567e6d1f185 --- /dev/null +++ b/kotlin-native/backend.native/tests/runtime/workers/worker_threadlocal_no_leak.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +import kotlin.native.concurrent.* + +@ThreadLocal +var x = Any() + +fun main() { + val worker = Worker.start() + + worker.execute(TransferMode.SAFE, {}) { + println(x) // Make sure x is initialized + }.result + + worker.requestTermination().result +} diff --git a/kotlin-native/runtime/src/main/cpp/Runtime.cpp b/kotlin-native/runtime/src/main/cpp/Runtime.cpp index 1457e92e1c1..da49b8973f7 100644 --- a/kotlin-native/runtime/src/main/cpp/Runtime.cpp +++ b/kotlin-native/runtime/src/main/cpp/Runtime.cpp @@ -224,11 +224,6 @@ KBoolean Konan_Platform_isDebugBinary() { return KonanNeedDebugInfo ? true : false; } -void Kotlin_zeroOutTLSGlobals() { - if (runtimeState != nullptr && runtimeState->memoryState != nullptr) - InitOrDeinitGlobalVariables(DEINIT_THREAD_LOCAL_GLOBALS, runtimeState->memoryState); -} - bool Kotlin_memoryLeakCheckerEnabled() { return g_checkLeaks; } diff --git a/kotlin-native/runtime/src/main/cpp/Runtime.h b/kotlin-native/runtime/src/main/cpp/Runtime.h index 1b296f7b7ea..8c81d4125ef 100644 --- a/kotlin-native/runtime/src/main/cpp/Runtime.h +++ b/kotlin-native/runtime/src/main/cpp/Runtime.h @@ -31,9 +31,6 @@ void Kotlin_deinitRuntimeIfNeeded(); // Appends given node to an initializer list. void AppendToInitializersTail(struct InitNode*); -// Zero out all Kotlin thread local globals. -void Kotlin_zeroOutTLSGlobals(); - bool Kotlin_memoryLeakCheckerEnabled(); bool Kotlin_cleanersLeakCheckerEnabled(); diff --git a/kotlin-native/runtime/src/main/cpp/Worker.cpp b/kotlin-native/runtime/src/main/cpp/Worker.cpp index 0f9279bcbf6..2f9175f7dd0 100644 --- a/kotlin-native/runtime/src/main/cpp/Worker.cpp +++ b/kotlin-native/runtime/src/main/cpp/Worker.cpp @@ -815,10 +815,6 @@ void* workerRoutine(void* argument) { if (worker->processQueueElement(true) == JOB_TERMINATE) break; } while (true); - // Runtime deinit callback could be called when TLS is already zeroed out, so clear memory - // here explicitly. to make sure leak detector properly works. - Kotlin_zeroOutTLSGlobals(); - return nullptr; }