[Openmp-commits] [openmp] d6a0957 - [OpenMP] changing OMP rtl to use shared memory instead of env variable
via Openmp-commits
openmp-commits at lists.llvm.org
Mon Oct 26 09:02:50 PDT 2020
Author: AndreyChurbanov
Date: 2020-10-26T19:02:21+03:00
New Revision: d6a0957467e86d5a87964d45fae18733e212c86f
URL: https://github.com/llvm/llvm-project/commit/d6a0957467e86d5a87964d45fae18733e212c86f
DIFF: https://github.com/llvm/llvm-project/commit/d6a0957467e86d5a87964d45fae18733e212c86f.diff
LOG: [OpenMP] changing OMP rtl to use shared memory instead of env variable
Patch by Erdner, Todd <todd.erdner at intel.com>
Differential Revision: https://reviews.llvm.org/D89898
Added:
Modified:
openmp/runtime/cmake/LibompHandleFlags.cmake
openmp/runtime/cmake/config-ix.cmake
openmp/runtime/src/kmp_runtime.cpp
Removed:
################################################################################
diff --git a/openmp/runtime/cmake/LibompHandleFlags.cmake b/openmp/runtime/cmake/LibompHandleFlags.cmake
index 0b8e3a35c888..9f0fc6b6390e 100644
--- a/openmp/runtime/cmake/LibompHandleFlags.cmake
+++ b/openmp/runtime/cmake/LibompHandleFlags.cmake
@@ -125,6 +125,9 @@ function(libomp_get_libflags libflags)
if(${IA32})
libomp_append(libflags_local -lirc_pic LIBOMP_HAVE_IRC_PIC_LIBRARY)
endif()
+ if(LIBOMP_HAVE_SHM_OPEN_WITH_LRT)
+ libomp_append(libflags_local -lrt)
+ endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "DragonFly|FreeBSD")
libomp_append(libflags_local "-Wl,--no-as-needed" LIBOMP_HAVE_AS_NEEDED_FLAG)
libomp_append(libflags_local "-lm")
diff --git a/openmp/runtime/cmake/config-ix.cmake b/openmp/runtime/cmake/config-ix.cmake
index 3419dd8cd788..f13290a9bc4a 100644
--- a/openmp/runtime/cmake/config-ix.cmake
+++ b/openmp/runtime/cmake/config-ix.cmake
@@ -14,6 +14,7 @@ include(CheckCXXCompilerFlag)
include(CheckIncludeFile)
include(CheckLibraryExists)
include(CheckIncludeFiles)
+include(CheckSymbolExists)
include(LibompCheckLinkerFlag)
include(LibompCheckFortranFlag)
@@ -95,6 +96,14 @@ if(${LIBOMP_FORTRAN_MODULES})
libomp_check_fortran_flag(-m32 LIBOMP_HAVE_M32_FORTRAN_FLAG)
endif()
+# Check for Unix shared memory
+check_symbol_exists(shm_open "sys/mman.h" LIBOMP_HAVE_SHM_OPEN_NO_LRT)
+if (NOT LIBOMP_HAVE_SHM_OPEN_NO_LRT)
+ set(CMAKE_REQUIRED_LIBRARIES -lrt)
+ check_symbol_exists(shm_open "sys/mman.h" LIBOMP_HAVE_SHM_OPEN_WITH_LRT)
+ set(CMAKE_REQUIRED_LIBRARIES)
+endif()
+
# Check linker flags
if(WIN32)
libomp_check_linker_flag(/SAFESEH LIBOMP_HAVE_SAFESEH_FLAG)
diff --git a/openmp/runtime/src/kmp_runtime.cpp b/openmp/runtime/src/kmp_runtime.cpp
index b8337fe27bf7..71a55e82476d 100644
--- a/openmp/runtime/src/kmp_runtime.cpp
+++ b/openmp/runtime/src/kmp_runtime.cpp
@@ -41,6 +41,15 @@
#include "tsan_annotations.h"
+#if KMP_OS_WINDOWS
+// windows does not need include files as it doesn't use shared memory
+#else
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#define SHM_SIZE 1024
+#endif
+
#if defined(KMP_GOMP_COMPAT)
char const __kmp_version_alt_comp[] =
KMP_VERSION_PREFIX "alternative compiler support: yes";
@@ -6139,7 +6148,6 @@ void __kmp_internal_end_library(int gtid_req) {
}
KMP_MB(); /* Flush all pending memory write invalidates. */
-
/* find out who we are and what we should do */
{
int gtid = (gtid_req >= 0) ? gtid_req : __kmp_gtid_get_specific();
@@ -6181,6 +6189,10 @@ void __kmp_internal_end_library(int gtid_req) {
if (__kmp_debug_buf)
__kmp_dump_debug_buffer();
#endif
+ // added unregister library call here when we switch to shm linux
+ // if we don't, it will leave lots of files in /dev/shm
+ // cleanup shared memory file before exiting.
+ __kmp_unregister_library();
return;
}
}
@@ -6393,16 +6405,61 @@ void __kmp_register_library_startup(void) {
char *value = NULL; // Actual value of the environment variable.
+#if KMP_OS_UNIX && KMP_DYNAMIC_LIB // shared memory is with dynamic library
+ char *shm_name = __kmp_str_format("/%s", name);
+ int shm_preexist = 0;
+ char *data1;
+ int fd1 = shm_open(shm_name, O_CREAT | O_EXCL | O_RDWR, 0666);
+ if ((fd1 == -1) && (errno == EEXIST)) {
+ // file didn't open because it already exists.
+ // try opening existing file
+ fd1 = shm_open(shm_name, O_RDWR, 0666);
+ if (fd1 == -1) { // file didn't open
+ // error out here
+ __kmp_fatal(KMP_MSG(FunctionError, "Can't open SHM"), KMP_ERR(0),
+ __kmp_msg_null);
+ } else {
+ // able to open existing file
+ shm_preexist = 1;
+ }
+ } else if (fd1 == -1) { // SHM didn't open; it was due to error other than
+ // already exists.
+ // error out here.
+ __kmp_fatal(KMP_MSG(FunctionError, "Can't open SHM2"), KMP_ERR(errno),
+ __kmp_msg_null);
+ }
+ if (shm_preexist == 0) {
+ // we created SHM now set size
+ if (ftruncate(fd1, SHM_SIZE) == -1) {
+ // error occured setting size;
+ __kmp_fatal(KMP_MSG(FunctionError, "Can't set size of SHM"),
+ KMP_ERR(errno), __kmp_msg_null);
+ }
+ }
+ data1 =
+ (char *)mmap(0, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd1, 0);
+ if (data1 == MAP_FAILED) {
+ // failed to map shared memory
+ __kmp_fatal(KMP_MSG(FunctionError, "Can't map SHM"), KMP_ERR(errno),
+ __kmp_msg_null);
+ }
+ if (shm_preexist == 0) { // set data to SHM, set value
+ KMP_STRCPY_S(data1, SHM_SIZE, __kmp_registration_str);
+ }
+ // Read value from either what we just wrote or existing file.
+ value = __kmp_str_format("%s", data1); // read value from SHM
+ munmap(data1, SHM_SIZE);
+ close(fd1);
+#else // Windows and unix with static library
// Set environment variable, but do not overwrite if it is exist.
__kmp_env_set(name, __kmp_registration_str, 0);
- // Check the variable is written.
+ // read value to see if it got set
value = __kmp_env_get(name);
- if (value != NULL && strcmp(value, __kmp_registration_str) == 0) {
+#endif
+ if (value != NULL && strcmp(value, __kmp_registration_str) == 0) {
done = 1; // Ok, environment variable set successfully, exit the loop.
-
} else {
-
// Oops. Write failed. Another copy of OpenMP RTL is in memory.
// Check whether it alive or dead.
int neighbor = 0; // 0 -- unknown status, 1 -- alive, 2 -- dead.
@@ -6452,14 +6509,23 @@ void __kmp_register_library_startup(void) {
done = 1; // Exit the loop.
} break;
case 2: { // Neighbor is dead.
+
+#if KMP_OS_UNIX && KMP_DYNAMIC_LIB // shared memory is with dynamic library
+ // close shared memory.
+ shm_unlink(shm_name); // this removes file in /dev/shm
+#else
// Clear the variable and try to register library again.
__kmp_env_unset(name);
+#endif
} break;
default: { KMP_DEBUG_ASSERT(0); } break;
}
}
KMP_INTERNAL_FREE((void *)value);
- }
+#if KMP_OS_UNIX && KMP_DYNAMIC_LIB // shared memory is with dynamic library
+ KMP_INTERNAL_FREE((void *)shm_name);
+#endif
+ } // while
KMP_INTERNAL_FREE((void *)name);
} // func __kmp_register_library_startup
@@ -6467,15 +6533,40 @@ void __kmp_register_library_startup(void) {
void __kmp_unregister_library(void) {
char *name = __kmp_reg_status_name();
- char *value = __kmp_env_get(name);
+ char *value = NULL;
+
+#if KMP_OS_UNIX && KMP_DYNAMIC_LIB // shared memory is with dynamic library
+ char *shm_name = __kmp_str_format("/%s", name);
+ int fd1 = shm_open(shm_name, O_RDONLY, 0666);
+ if (fd1 == -1) {
+ // file did not open. return.
+ return;
+ }
+ char *data1 = (char *)mmap(0, SHM_SIZE, PROT_READ, MAP_SHARED, fd1, 0);
+ if (data1 != MAP_FAILED) {
+ value = __kmp_str_format("%s", data1); // read value from SHM
+ munmap(data1, SHM_SIZE);
+ }
+ close(fd1);
+#else
+ value = __kmp_env_get(name);
+#endif
KMP_DEBUG_ASSERT(__kmp_registration_flag != 0);
KMP_DEBUG_ASSERT(__kmp_registration_str != NULL);
if (value != NULL && strcmp(value, __kmp_registration_str) == 0) {
- // Ok, this is our variable. Delete it.
+// Ok, this is our variable. Delete it.
+#if KMP_OS_UNIX && KMP_DYNAMIC_LIB // shared memory is with dynamic library
+ shm_unlink(shm_name); // this removes file in /dev/shm
+#else
__kmp_env_unset(name);
+#endif
}
+#if KMP_OS_UNIX && KMP_DYNAMIC_LIB // shared memory is with dynamic library
+ KMP_INTERNAL_FREE(shm_name);
+#endif
+
KMP_INTERNAL_FREE(__kmp_registration_str);
KMP_INTERNAL_FREE(value);
KMP_INTERNAL_FREE(name);
More information about the Openmp-commits
mailing list