[OpenMP] Enable thread affinity on FreeBSD

Reviewers: chandlerc, jlpeyton, jdoerfert, dim

Reviewed-By: dim

Differential Revision: https://reviews.llvm.org/D68580

llvm-svn: 374118
This commit is contained in:
David Carlier 2019-10-08 21:25:30 +00:00
parent 6399db2f6f
commit f61f13d4e7
6 changed files with 51 additions and 14 deletions

View File

@ -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 */

View File

@ -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;

View File

@ -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 {

View File

@ -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

View File

@ -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);

View File

@ -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
#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);
// 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.
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);