aboutsummaryrefslogtreecommitdiff
path: root/runtime/src/z_Linux_util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/src/z_Linux_util.cpp')
-rw-r--r--runtime/src/z_Linux_util.cpp89
1 files changed, 78 insertions, 11 deletions
diff --git a/runtime/src/z_Linux_util.cpp b/runtime/src/z_Linux_util.cpp
index 1983fc2b9834..0ee12927e4bf 100644
--- a/runtime/src/z_Linux_util.cpp
+++ b/runtime/src/z_Linux_util.cpp
@@ -50,6 +50,9 @@
#include <mach/mach.h>
#include <sys/sysctl.h>
#elif KMP_OS_DRAGONFLY || KMP_OS_FREEBSD
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
#include <pthread_np.h>
#elif KMP_OS_NETBSD
#include <sys/types.h>
@@ -97,7 +100,7 @@ static void __kmp_print_cond(char *buffer, kmp_cond_align_t *cond) {
}
#endif
-#if (KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED)
+#if ((KMP_OS_LINUX || KMP_OS_FREEBSD) && KMP_AFFINITY_SUPPORTED)
/* Affinity support */
@@ -119,16 +122,21 @@ void __kmp_affinity_bind_thread(int which) {
void __kmp_affinity_determine_capable(const char *env_var) {
// Check and see if the OS supports thread affinity.
+#if KMP_OS_LINUX
#define KMP_CPU_SET_SIZE_LIMIT (1024 * 1024)
+#elif KMP_OS_FREEBSD
+#define KMP_CPU_SET_SIZE_LIMIT (sizeof(cpuset_t))
+#endif
- int gCode;
- int sCode;
- unsigned char *buf;
- buf = (unsigned char *)KMP_INTERNAL_MALLOC(KMP_CPU_SET_SIZE_LIMIT);
+#if KMP_OS_LINUX
// If Linux* OS:
// If the syscall fails or returns a suggestion for the size,
// then we don't have to search for an appropriate size.
+ int gCode;
+ int sCode;
+ unsigned char *buf;
+ buf = (unsigned char *)KMP_INTERNAL_MALLOC(KMP_CPU_SET_SIZE_LIMIT);
gCode = syscall(__NR_sched_getaffinity, 0, KMP_CPU_SET_SIZE_LIMIT, buf);
KA_TRACE(30, ("__kmp_affinity_determine_capable: "
"initial getaffinity call returned %d errno = %d\n",
@@ -267,6 +275,23 @@ void __kmp_affinity_determine_capable(const char *env_var) {
}
}
}
+#elif KMP_OS_FREEBSD
+ int gCode;
+ unsigned char *buf;
+ buf = (unsigned char *)KMP_INTERNAL_MALLOC(KMP_CPU_SET_SIZE_LIMIT);
+ gCode = pthread_getaffinity_np(pthread_self(), KMP_CPU_SET_SIZE_LIMIT, reinterpret_cast<cpuset_t *>(buf));
+ KA_TRACE(30, ("__kmp_affinity_determine_capable: "
+ "initial getaffinity call returned %d errno = %d\n",
+ gCode, errno));
+ if (gCode == 0) {
+ KMP_AFFINITY_ENABLE(KMP_CPU_SET_SIZE_LIMIT);
+ KA_TRACE(10, ("__kmp_affinity_determine_capable: "
+ "affinity supported (mask size %d)\n"<
+ (int)__kmp_affin_mask_size));
+ KMP_INTERNAL_FREE(buf);
+ return;
+ }
+#endif
// save uncaught error code
// int error = errno;
KMP_INTERNAL_FREE(buf);
@@ -802,6 +827,13 @@ void __kmp_create_worker(int gtid, kmp_info_t *th, size_t stack_size) {
and also gives the user the stack space they requested for all threads */
stack_size += gtid * __kmp_stkoffset * 2;
+#if defined(__ANDROID__) && __ANDROID_API__ < 19
+ // Round the stack size to a multiple of the page size. Older versions of
+ // Android (until KitKat) would fail pthread_attr_setstacksize with EINVAL
+ // if the stack size was not a multiple of the page size.
+ stack_size = (stack_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+#endif
+
KA_TRACE(10, ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, "
"__kmp_stksize = %lu bytes, final stacksize = %lu bytes\n",
gtid, KMP_DEFAULT_STKSIZE, __kmp_stksize, stack_size));
@@ -1972,7 +2004,7 @@ int __kmp_is_address_mapped(void *addr) {
int found = 0;
int rc;
-#if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_HURD
+#if KMP_OS_LINUX || KMP_OS_HURD
/* On GNUish OSes, read the /proc/<pid>/maps pseudo-file to get all the address
ranges mapped into the address space. */
@@ -2010,6 +2042,44 @@ int __kmp_is_address_mapped(void *addr) {
// Free resources.
fclose(file);
KMP_INTERNAL_FREE(name);
+#elif KMP_OS_FREEBSD
+ char *buf;
+ size_t lstsz;
+ int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid()};
+ rc = sysctl(mib, 4, NULL, &lstsz, NULL, 0);
+ if (rc < 0)
+ return 0;
+ // We pass from number of vm entry's semantic
+ // to size of whole entry map list.
+ lstsz = lstsz * 4 / 3;
+ buf = reinterpret_cast<char *>(kmpc_malloc(lstsz));
+ rc = sysctl(mib, 4, buf, &lstsz, NULL, 0);
+ if (rc < 0) {
+ kmpc_free(buf);
+ return 0;
+ }
+
+ char *lw = buf;
+ char *up = buf + lstsz;
+
+ while (lw < up) {
+ struct kinfo_vmentry *cur = reinterpret_cast<struct kinfo_vmentry *>(lw);
+ size_t cursz = cur->kve_structsize;
+ if (cursz == 0)
+ break;
+ void *start = reinterpret_cast<void *>(cur->kve_start);
+ void *end = reinterpret_cast<void *>(cur->kve_end);
+ // Readable/Writable addresses within current map entry
+ if ((addr >= start) && (addr < end)) {
+ if ((cur->kve_protection & KVME_PROT_READ) != 0 &&
+ (cur->kve_protection & KVME_PROT_WRITE) != 0) {
+ found = 1;
+ break;
+ }
+ }
+ lw += cursz;
+ }
+ kmpc_free(buf);
#elif KMP_OS_DARWIN
@@ -2331,7 +2401,8 @@ finish: // Clean up and exit.
#endif // USE_LOAD_BALANCE
#if !(KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_MIC || \
- ((KMP_OS_LINUX || KMP_OS_DARWIN) && KMP_ARCH_AARCH64) || KMP_ARCH_PPC64)
+ ((KMP_OS_LINUX || KMP_OS_DARWIN) && KMP_ARCH_AARCH64) || \
+ KMP_ARCH_PPC64 || KMP_ARCH_RISCV64)
// we really only need the case with 1 argument, because CLANG always build
// a struct of pointers to shared variables referenced in the outlined function
@@ -2415,10 +2486,6 @@ int __kmp_invoke_microtask(microtask_t pkfn, int gtid, int tid, int argc,
break;
}
-#if OMPT_SUPPORT
- *exit_frame_ptr = 0;
-#endif
-
return 1;
}