From 1b71136cdaf9a6ab3d01149bac31459fa91ea4a6 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 29 Jan 2025 12:56:49 -0800 Subject: [PATCH] Cleanup membarrier portability (#111943) Fixes #111776 --- src/coreclr/gc/unix/config.gc.h.in | 1 + src/coreclr/gc/unix/configure.cmake | 1 + src/coreclr/gc/unix/gcenv.unix.cpp | 46 ++++++++++---------------- src/coreclr/pal/src/config.h.in | 2 +- src/coreclr/pal/src/configure.cmake | 1 + src/coreclr/pal/src/thread/process.cpp | 40 ++++++++-------------- 6 files changed, 35 insertions(+), 56 deletions(-) diff --git a/src/coreclr/gc/unix/config.gc.h.in b/src/coreclr/gc/unix/config.gc.h.in index 01cb767798fbcd..dfc38aea6b8470 100644 --- a/src/coreclr/gc/unix/config.gc.h.in +++ b/src/coreclr/gc/unix/config.gc.h.in @@ -6,6 +6,7 @@ #cmakedefine01 HAVE_SYS_TIME_H #cmakedefine01 HAVE_SYS_MMAN_H +#cmakedefine01 HAVE_SYS_MEMBARRIER_H #cmakedefine01 HAVE_PTHREAD_THREADID_NP #cmakedefine01 HAVE_PTHREAD_GETTHREADID_NP #cmakedefine01 HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY diff --git a/src/coreclr/gc/unix/configure.cmake b/src/coreclr/gc/unix/configure.cmake index c3b301f58938f0..8d33b81a32f727 100644 --- a/src/coreclr/gc/unix/configure.cmake +++ b/src/coreclr/gc/unix/configure.cmake @@ -11,6 +11,7 @@ include(CheckLibraryExists) check_include_files(sys/time.h HAVE_SYS_TIME_H) check_include_files(sys/mman.h HAVE_SYS_MMAN_H) check_include_files(pthread_np.h HAVE_PTHREAD_NP_H) +check_include_files(sys/membarrier.h HAVE_SYS_MEMBARRIER_H) check_function_exists(vm_allocate HAVE_VM_ALLOCATE) check_function_exists(sysctlbyname HAVE_SYSCTLBYNAME) diff --git a/src/coreclr/gc/unix/gcenv.unix.cpp b/src/coreclr/gc/unix/gcenv.unix.cpp index 37ce5943a20ff8..43588c66eb015a 100644 --- a/src/coreclr/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/gc/unix/gcenv.unix.cpp @@ -29,6 +29,14 @@ #include #endif +#ifdef __linux__ +#include +#include +#define membarrier(...) syscall(__NR_membarrier, __VA_ARGS__) +#elif HAVE_SYS_MEMBARRIER_H +#include +#endif + #include #undef min @@ -94,10 +102,6 @@ extern "C" #include #endif // __HAIKU__ -#ifdef __linux__ -#include // __NR_membarrier -#endif - #if HAVE_PTHREAD_NP_H #include #endif @@ -132,29 +136,9 @@ typedef cpuset_t cpu_set_t; // The cached total number of CPUs that can be used in the OS. static uint32_t g_totalCpuCount = 0; -// -// Helper membarrier function -// -#ifdef __NR_membarrier -# define membarrier(...) syscall(__NR_membarrier, __VA_ARGS__) -#else -# define membarrier(...) -ENOSYS -#endif - -enum membarrier_cmd -{ - MEMBARRIER_CMD_QUERY = 0, - MEMBARRIER_CMD_GLOBAL = (1 << 0), - MEMBARRIER_CMD_GLOBAL_EXPEDITED = (1 << 1), - MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED = (1 << 2), - MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3), - MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4), - MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 5), - MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 6) -}; - bool CanFlushUsingMembarrier() { +#if defined(__linux__) || HAVE_SYS_MEMBARRIER_H #ifdef TARGET_ANDROID // Avoid calling membarrier on older Android versions where membarrier @@ -169,15 +153,16 @@ bool CanFlushUsingMembarrier() // Starting with Linux kernel 4.14, process memory barriers can be generated // using MEMBARRIER_CMD_PRIVATE_EXPEDITED. - int mask = membarrier(MEMBARRIER_CMD_QUERY, 0); + int mask = membarrier(MEMBARRIER_CMD_QUERY, 0, 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) + membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0, 0) == 0) { return true; } +#endif return false; } @@ -423,12 +408,15 @@ bool GCToOSInterface::CanGetCurrentProcessorNumber() // Flush write buffers of processors that are executing threads of the current process void GCToOSInterface::FlushProcessWriteBuffers() { +#if defined(__linux__) || HAVE_SYS_MEMBARRIER_H if (s_flushUsingMemBarrier) { - int status = membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0); + int status = membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0, 0); assert(status == 0 && "Failed to flush using membarrier"); } - else if (g_helperPage != 0) + else +#endif + if (g_helperPage != 0) { int status = pthread_mutex_lock(&g_flushProcessWriteBuffersMutex); assert(status == 0 && "Failed to lock the flushProcessWriteBuffersMutex lock"); diff --git a/src/coreclr/pal/src/config.h.in b/src/coreclr/pal/src/config.h.in index a3c83373d6d955..a47712a855fe46 100644 --- a/src/coreclr/pal/src/config.h.in +++ b/src/coreclr/pal/src/config.h.in @@ -13,12 +13,12 @@ #cmakedefine01 HAVE_CRT_EXTERNS_H #cmakedefine01 HAVE_SYS_TIME_H #cmakedefine01 HAVE_PTHREAD_NP_H +#cmakedefine01 HAVE_SYS_MEMBARRIER_H #cmakedefine01 HAVE_SYS_LWP_H #cmakedefine01 HAVE_LWP_H #cmakedefine01 HAVE_RUNETYPE_H #cmakedefine01 HAVE_GNU_LIBNAMES_H #cmakedefine01 HAVE_PRCTL_H -#cmakedefine01 HAVE_PTHREAD_NP_H #cmakedefine01 HAVE_AUXV_HWCAP_H #cmakedefine01 HAVE_SYS_PTRACE_H #cmakedefine01 HAVE_SYS_UCONTEXT_H diff --git a/src/coreclr/pal/src/configure.cmake b/src/coreclr/pal/src/configure.cmake index bc4f3258b44b3a..4ba3ab6f53ce0d 100644 --- a/src/coreclr/pal/src/configure.cmake +++ b/src/coreclr/pal/src/configure.cmake @@ -40,6 +40,7 @@ check_include_files(procfs.h HAVE_PROCFS_H) check_include_files(crt_externs.h HAVE_CRT_EXTERNS_H) check_include_files(sys/time.h HAVE_SYS_TIME_H) check_include_files(pthread_np.h HAVE_PTHREAD_NP_H) +check_include_files(sys/membarrier.h HAVE_SYS_MEMBARRIER_H) check_include_files(sys/lwp.h HAVE_SYS_LWP_H) check_include_files(lwp.h HAVE_LWP_H) check_include_files(runetype.h HAVE_RUNETYPE_H) diff --git a/src/coreclr/pal/src/thread/process.cpp b/src/coreclr/pal/src/thread/process.cpp index b50838750c478f..20c09eb357dd2e 100644 --- a/src/coreclr/pal/src/thread/process.cpp +++ b/src/coreclr/pal/src/thread/process.cpp @@ -64,7 +64,11 @@ SET_DEFAULT_DEBUG_CHANNEL(PROCESS); // some headers have code with asserts, so d #include #ifdef __linux__ -#include // __NR_membarrier +#include +#include +#define membarrier(...) syscall(__NR_membarrier, __VA_ARGS__) +#elif HAVE_SYS_MEMBARRIER_H +#include #endif #ifdef __APPLE__ @@ -125,27 +129,6 @@ CObjectType CorUnix::otProcess( CObjectType::NoOwner ); -// -// Helper membarrier function -// -#ifdef __NR_membarrier -# define membarrier(...) syscall(__NR_membarrier, __VA_ARGS__) -#else -# define membarrier(...) -ENOSYS -#endif - -enum membarrier_cmd -{ - MEMBARRIER_CMD_QUERY = 0, - MEMBARRIER_CMD_GLOBAL = (1 << 0), - MEMBARRIER_CMD_GLOBAL_EXPEDITED = (1 << 1), - MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED = (1 << 2), - MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3), - MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4), - MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 5), - MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 6) -}; - // // Tracks if the OS supports FlushProcessWriteBuffers using membarrier // @@ -2581,19 +2564,21 @@ InitializeFlushProcessWriteBuffers() _ASSERTE(s_helperPage == 0); _ASSERTE(s_flushUsingMemBarrier == 0); +#if defined(__linux__) || HAVE_SYS_MEMBARRIER_H // Starting with Linux kernel 4.14, process memory barriers can be generated // using MEMBARRIER_CMD_PRIVATE_EXPEDITED. - int mask = membarrier(MEMBARRIER_CMD_QUERY, 0); + int mask = membarrier(MEMBARRIER_CMD_QUERY, 0, 0); if (mask >= 0 && mask & MEMBARRIER_CMD_PRIVATE_EXPEDITED) { // Register intent to use the private expedited command. - if (membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0) == 0) + if (membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0, 0) == 0) { s_flushUsingMemBarrier = TRUE; return TRUE; } } +#endif #ifdef TARGET_APPLE return TRUE; @@ -2649,12 +2634,15 @@ VOID PALAPI FlushProcessWriteBuffers() { +#if defined(__linux__) || HAVE_SYS_MEMBARRIER_H if (s_flushUsingMemBarrier) { - int status = membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0); + int status = membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0, 0); FATAL_ASSERT(status == 0, "Failed to flush using membarrier"); } - else if (s_helperPage != 0) + else +#endif + if (s_helperPage != 0) { int status = pthread_mutex_lock(&flushProcessWriteBuffersMutex); FATAL_ASSERT(status == 0, "Failed to lock the flushProcessWriteBuffersMutex lock");