[K/N][runtime][codegen] Fixed a problem with synchronization

During globals initialization proper synchronization is required for ARM cpus

 #KT-53243 Fixed
This commit is contained in:
Igor Chevdar
2022-07-21 11:32:47 +03:00
committed by Space
parent a3b33901d8
commit 652f6923b3
2 changed files with 17 additions and 3 deletions
+16 -1
View File
@@ -28,6 +28,7 @@
#include "Worker.h"
#include "KString.h"
#include "std_support/New.hpp"
#include <atomic>
#ifndef KONAN_NO_THREADS
#include <thread>
@@ -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))