Android; Add additional check before using membarrier (#8320)

Calling membarrier on Android before version Q can kill the whole process. 
This implements an additional check when build with TARGET_ANDROID.
Refactor the check in a separate function as it got quite large.
This commit is contained in:
RalfKornmannEnvision 2020-09-13 02:09:56 +02:00 коммит произвёл GitHub
Родитель 9365a442ae
Коммит 3a6191259d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 36 добавлений и 11 удалений

Просмотреть файл

@ -168,6 +168,39 @@ enum membarrier_cmd
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 6)
};
bool CanFlushUsingMembarrier()
{
#ifdef TARGET_ANDROID
// Calling membarrier on older Android versions can just kill the process
#ifdef __ANDROID_API_Q__
int api_level = android_get_device_api_level();
if (api_level < __ANDROID_API_Q__)
{
return false;
}
#else
return false;
#endif // __ANDROID_API_Q__
#endif // TARGET_ANDROID
// Starting with Linux kernel 4.14, process memory barriers can be generated
// using MEMBARRIER_CMD_PRIVATE_EXPEDITED.
int mask = membarrier(MEMBARRIER_CMD_QUERY, 0);
if (mask >= 0 &&
mask & MEMBARRIER_CMD_PRIVATE_EXPEDITED &&
// Register intent to use the private expedited command.
membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0) == 0)
{
return true;
}
return false;
}
//
// Tracks if the OS supports FlushProcessWriteBuffers using membarrier
//
@ -324,17 +357,9 @@ bool GCToOSInterface::Initialize()
assert(s_flushUsingMemBarrier == 0);
// Starting with Linux kernel 4.14, process memory barriers can be generated
// using MEMBARRIER_CMD_PRIVATE_EXPEDITED.
int mask = membarrier(MEMBARRIER_CMD_QUERY, 0);
if (mask >= 0 &&
mask & MEMBARRIER_CMD_PRIVATE_EXPEDITED &&
// Register intent to use the private expedited command.
membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0) == 0)
{
s_flushUsingMemBarrier = TRUE;
}
else
s_flushUsingMemBarrier = CanFlushUsingMembarrier();
if (!s_flushUsingMemBarrier)
{
assert(g_helperPage == 0);