diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index ae413962b8d..00fa566c00e 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -2421,9 +2421,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map #ifndef KONAN_NO_THREADS #include @@ -471,7 +472,10 @@ RUNTIME_NOTHROW void Kotlin_initRuntimeIfNeededFromKotlin() { } } -void CallInitGlobalPossiblyLock(int volatile* state, void (*init)()) { +} // extern "C" + +namespace { +void callInitGlobalPossiblyLockImpl(int volatile* state, void (*init)()) { int localState = *state; if (localState == FILE_INITIALIZED) return; if (localState == FILE_FAILED_TO_INITIALIZE) @@ -502,6 +506,7 @@ void CallInitGlobalPossiblyLock(int volatile* state, void (*init)()) { throw; } #endif + std::atomic_thread_fence(std::memory_order_release); *state = FILE_INITIALIZED; } else { // Switch to the native state to avoid dead-locks. @@ -514,6 +519,16 @@ void CallInitGlobalPossiblyLock(int volatile* state, void (*init)()) { } while (localState != FILE_INITIALIZED); } } +} + +extern "C" { + +NO_INLINE void CallInitGlobalPossiblyLock(int volatile* state, void (*init)()) { + callInitGlobalPossiblyLockImpl(state, init); + // Ensure proper synchronization around reading/writing of [state] (release barrier defined in callInitGlobalPossiblyLockImpl), + // also there is an acquire load of [state] in IrToBitcode.kt::evaluateFileGlobalInitializerCall. + std::atomic_thread_fence(std::memory_order_acquire); +} void CallInitThreadLocal(int volatile* globalState, int* localState, void (*init)()) { if (*localState == FILE_FAILED_TO_INITIALIZE || (globalState != nullptr && *globalState == FILE_FAILED_TO_INITIALIZE))