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:
Родитель
9365a442ae
Коммит
3a6191259d
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче