aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Carlier <devnexen@gmail.com>2019-10-08 21:25:30 +0000
committerDavid Carlier <devnexen@gmail.com>2019-10-08 21:25:30 +0000
commitcb6f3c46a841e47718564ca40f49af8bcfc57c3a (patch)
tree5b7d1c38316e0ff0b44ab49d4d5c9c22c0f1474d
parentace8505db1e11227e9007a2ac55ffaeccf88a65c (diff)
downloadopenmp-cb6f3c46a841e47718564ca40f49af8bcfc57c3a.tar.gz
[OpenMP] Enable thread affinity on FreeBSD
Reviewers: chandlerc, jlpeyton, jdoerfert, dim Reviewed-By: dim Differential Revision: https://reviews.llvm.org/D68580 git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@374118 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--runtime/src/kmp.h2
-rw-r--r--runtime/src/kmp_affinity.cpp4
-rw-r--r--runtime/src/kmp_affinity.h17
-rw-r--r--runtime/src/kmp_os.h2
-rw-r--r--runtime/src/kmp_runtime.cpp8
-rw-r--r--runtime/src/z_Linux_util.cpp32
6 files changed, 51 insertions, 14 deletions
diff --git a/runtime/src/kmp.h b/runtime/src/kmp.h
index a0b4202..23eebe6 100644
--- a/runtime/src/kmp.h
+++ b/runtime/src/kmp.h
@@ -3341,7 +3341,7 @@ extern int __kmp_aux_set_affinity_mask_proc(int proc, void **mask);
extern int __kmp_aux_unset_affinity_mask_proc(int proc, void **mask);
extern int __kmp_aux_get_affinity_mask_proc(int proc, void **mask);
extern void __kmp_balanced_affinity(kmp_info_t *th, int team_size);
-#if KMP_OS_LINUX
+#if KMP_OS_LINUX || KMP_OS_FREEBSD
extern int kmp_set_thread_affinity_mask_initial(void);
#endif
#endif /* KMP_AFFINITY_SUPPORTED */
diff --git a/runtime/src/kmp_affinity.cpp b/runtime/src/kmp_affinity.cpp
index 372c300..4c7ed31 100644
--- a/runtime/src/kmp_affinity.cpp
+++ b/runtime/src/kmp_affinity.cpp
@@ -1968,7 +1968,7 @@ static void __kmp_dispatch_set_hierarchy_values() {
__kmp_hier_max_units[kmp_hier_layer_e::LAYER_THREAD + 1] =
nPackages * nCoresPerPkg * __kmp_nThreadsPerCore;
__kmp_hier_max_units[kmp_hier_layer_e::LAYER_L1 + 1] = __kmp_ncores;
-#if KMP_ARCH_X86_64 && (KMP_OS_LINUX || KMP_OS_WINDOWS)
+#if KMP_ARCH_X86_64 && (KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_WINDOWS)
if (__kmp_mic_type >= mic3)
__kmp_hier_max_units[kmp_hier_layer_e::LAYER_L2 + 1] = __kmp_ncores / 2;
else
@@ -1982,7 +1982,7 @@ static void __kmp_dispatch_set_hierarchy_values() {
__kmp_hier_threads_per[kmp_hier_layer_e::LAYER_THREAD + 1] = 1;
__kmp_hier_threads_per[kmp_hier_layer_e::LAYER_L1 + 1] =
__kmp_nThreadsPerCore;
-#if KMP_ARCH_X86_64 && (KMP_OS_LINUX || KMP_OS_WINDOWS)
+#if KMP_ARCH_X86_64 && (KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_WINDOWS)
if (__kmp_mic_type >= mic3)
__kmp_hier_threads_per[kmp_hier_layer_e::LAYER_L2 + 1] =
2 * __kmp_nThreadsPerCore;
diff --git a/runtime/src/kmp_affinity.h b/runtime/src/kmp_affinity.h
index c00ad36..f270bb6 100644
--- a/runtime/src/kmp_affinity.h
+++ b/runtime/src/kmp_affinity.h
@@ -160,6 +160,7 @@ public:
};
#endif /* KMP_USE_HWLOC */
+#if KMP_OS_LINUX || KMP_OS_FREEBSD
#if KMP_OS_LINUX
/* On some of the older OS's that we build on, these constants aren't present
in <asm/unistd.h> #included from <sys.syscall.h>. They must be the same on
@@ -234,6 +235,10 @@ public:
#endif /* __NR_sched_getaffinity */
#error Unknown or unsupported architecture
#endif /* KMP_ARCH_* */
+#elif KMP_OS_FREEBSD
+#include <pthread.h>
+#include <pthread_np.h>
+#endif
class KMPNativeAffinity : public KMPAffinity {
class Mask : public KMPAffinity::Mask {
typedef unsigned char mask_t;
@@ -294,8 +299,13 @@ class KMPNativeAffinity : public KMPAffinity {
int get_system_affinity(bool abort_on_error) override {
KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
"Illegal get affinity operation when not capable");
+#if KMP_OS_LINUX
int retval =
syscall(__NR_sched_getaffinity, 0, __kmp_affin_mask_size, mask);
+#elif KMP_OS_FREEBSD
+ int retval =
+ pthread_getaffinity_np(pthread_self(), __kmp_affin_mask_size, reinterpret_cast<cpuset_t *>(mask));
+#endif
if (retval >= 0) {
return 0;
}
@@ -308,8 +318,13 @@ class KMPNativeAffinity : public KMPAffinity {
int set_system_affinity(bool abort_on_error) const override {
KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
"Illegal get affinity operation when not capable");
+#if KMP_OS_LINUX
int retval =
syscall(__NR_sched_setaffinity, 0, __kmp_affin_mask_size, mask);
+#elif KMP_OS_FREEBSD
+ int retval =
+ pthread_setaffinity_np(pthread_self(), __kmp_affin_mask_size, reinterpret_cast<cpuset_t *>(mask));
+#endif
if (retval >= 0) {
return 0;
}
@@ -347,7 +362,7 @@ class KMPNativeAffinity : public KMPAffinity {
}
api_type get_api_type() const override { return NATIVE_OS; }
};
-#endif /* KMP_OS_LINUX */
+#endif /* KMP_OS_LINUX || KMP_OS_FREEBSD */
#if KMP_OS_WINDOWS
class KMPNativeAffinity : public KMPAffinity {
diff --git a/runtime/src/kmp_os.h b/runtime/src/kmp_os.h
index ca3af3a..cd942a9 100644
--- a/runtime/src/kmp_os.h
+++ b/runtime/src/kmp_os.h
@@ -69,7 +69,7 @@
#error Unknown compiler
#endif
-#if (KMP_OS_LINUX || KMP_OS_WINDOWS) && !KMP_OS_CNK
+#if (KMP_OS_LINUX || KMP_OS_WINDOWS || KMP_OS_FREEBSD) && !KMP_OS_CNK
#define KMP_AFFINITY_SUPPORTED 1
#if KMP_OS_WINDOWS && KMP_ARCH_X86_64
#define KMP_GROUP_AFFINITY 1
diff --git a/runtime/src/kmp_runtime.cpp b/runtime/src/kmp_runtime.cpp
index 82d4c26..dd6e0ff 100644
--- a/runtime/src/kmp_runtime.cpp
+++ b/runtime/src/kmp_runtime.cpp
@@ -4493,7 +4493,7 @@ static void __kmp_initialize_team(kmp_team_t *team, int new_nproc,
KF_TRACE(10, ("__kmp_initialize_team: exit: team=%p\n", team));
}
-#if KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED
+#if (KMP_OS_LINUX || KMP_OS_FREEBSD) && KMP_AFFINITY_SUPPORTED
/* Sets full mask for thread and returns old mask, no changes to structures. */
static void
__kmp_set_thread_affinity_mask_full_tmp(kmp_affin_mask_t *old_mask) {
@@ -5041,7 +5041,7 @@ __kmp_allocate_team(kmp_root_t *root, int new_nproc, int max_nproc,
__kmp_partition_places(team);
#endif
} else { // team->t.t_nproc < new_nproc
-#if KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED
+#if (KMP_OS_LINUX || KMP_OS_FREEBSD) && KMP_AFFINITY_SUPPORTED
kmp_affin_mask_t *old_mask;
if (KMP_AFFINITY_CAPABLE()) {
KMP_CPU_ALLOC(old_mask);
@@ -5090,7 +5090,7 @@ __kmp_allocate_team(kmp_root_t *root, int new_nproc, int max_nproc,
__kmp_reinitialize_team(team, new_icvs, NULL);
}
-#if KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED
+#if (KMP_OS_LINUX || KMP_OS_FREEBSD) && KMP_AFFINITY_SUPPORTED
/* Temporarily set full mask for master thread before creation of
workers. The reason is that workers inherit the affinity from master,
so if a lot of workers are created on the single core quickly, they
@@ -5125,7 +5125,7 @@ __kmp_allocate_team(kmp_root_t *root, int new_nproc, int max_nproc,
}
}
-#if KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED
+#if (KMP_OS_LINUX || KMP_OS_FREEBSD) && KMP_AFFINITY_SUPPORTED
if (KMP_AFFINITY_CAPABLE()) {
/* Restore initial master thread's affinity mask */
__kmp_set_system_affinity(old_mask, TRUE);
diff --git a/runtime/src/z_Linux_util.cpp b/runtime/src/z_Linux_util.cpp
index 871be62..0ee1292 100644
--- a/runtime/src/z_Linux_util.cpp
+++ b/runtime/src/z_Linux_util.cpp
@@ -100,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 */
@@ -122,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",
@@ -270,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);