Index: openmp/runtime/src/kmp_affinity.h =================================================================== --- openmp/runtime/src/kmp_affinity.h +++ openmp/runtime/src/kmp_affinity.h @@ -160,7 +160,7 @@ }; #endif /* KMP_USE_HWLOC */ -#if KMP_OS_LINUX || KMP_OS_FREEBSD +#if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_DARWIN #if KMP_OS_LINUX /* On some of the older OS's that we build on, these constants aren't present in #included from . They must be the same on @@ -238,6 +238,10 @@ #elif KMP_OS_FREEBSD #include #include +#elif KMP_OS_DARWIN +#include +#include +#include #endif class KMPNativeAffinity : public KMPAffinity { class Mask : public KMPAffinity::Mask { @@ -306,6 +310,20 @@ int r = pthread_getaffinity_np(pthread_self(), __kmp_affin_mask_size, reinterpret_cast(mask)); int retval = (r == 0 ? 0 : -1); +#elif KMP_OS_DARWIN + boolean_t def = false; + int max_proc = __kmp_aux_get_affinity_max_proc(); + mach_msg_type_number_t cnt = THREAD_AFFINITY_POLICY_COUNT; + thread_affinity_policy_data_t tmask[max_proc]; + for (size_t i = 0; i < max_proc; i++) { + kern_return_t r = thread_policy_get( + mach_thread_self(), THREAD_AFFINITY_POLICY, + reinterpret_cast(&tmask[i]), &cnt, &def); + if (r != KERN_SUCCESS) + return -1; + set(tmask[i].affinity_tag); + } + int retval = 0; #endif if (retval >= 0) { return 0; @@ -326,6 +344,21 @@ int r = pthread_setaffinity_np(pthread_self(), __kmp_affin_mask_size, reinterpret_cast(mask)); int retval = (r == 0 ? 0 : -1); +#elif KMP_OS_DARWIN + int max_proc = __kmp_aux_get_affinity_max_proc(); + thread_affinity_policy_data_t tmask[max_proc]; + int index = begin(); + + for (size_t i = 0; i < max_proc, index < end(); i ++) { + tmask[i].affinity_tag = index; + kern_return_t r = thread_policy_set( + mach_thread_self(), THREAD_AFFINITY_POLICY, + reinterpret_cast(&tmask[i]), THREAD_AFFINITY_POLICY_COUNT); + if (r != KERN_SUCCESS) + return -1; + index = next(index); + } + int retval = 0; #endif if (retval >= 0) { return 0; @@ -364,7 +397,7 @@ } api_type get_api_type() const override { return NATIVE_OS; } }; -#endif /* KMP_OS_LINUX || KMP_OS_FREEBSD */ +#endif /* KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_DARWIN */ #if KMP_OS_WINDOWS class KMPNativeAffinity : public KMPAffinity { Index: openmp/runtime/src/kmp_affinity.cpp =================================================================== --- openmp/runtime/src/kmp_affinity.cpp +++ openmp/runtime/src/kmp_affinity.cpp @@ -5300,7 +5300,7 @@ } } -#if KMP_OS_LINUX || KMP_OS_FREEBSD +#if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_DARWIN // We don't need this entry for Windows because // there is GetProcessAffinityMask() api // Index: openmp/runtime/src/kmp_os.h =================================================================== --- openmp/runtime/src/kmp_os.h +++ openmp/runtime/src/kmp_os.h @@ -69,7 +69,7 @@ #error Unknown compiler #endif -#if (KMP_OS_LINUX || KMP_OS_WINDOWS || KMP_OS_FREEBSD) && !KMP_OS_CNK +#if (KMP_OS_LINUX || KMP_OS_WINDOWS || KMP_OS_FREEBSD || KMP_OS_DARWIN) && !KMP_OS_CNK #define KMP_AFFINITY_SUPPORTED 1 #if KMP_OS_WINDOWS && KMP_ARCH_X86_64 #define KMP_GROUP_AFFINITY 1 Index: openmp/runtime/src/kmp_runtime.cpp =================================================================== --- openmp/runtime/src/kmp_runtime.cpp +++ openmp/runtime/src/kmp_runtime.cpp @@ -4493,7 +4493,7 @@ KF_TRACE(10, ("__kmp_initialize_team: exit: team=%p\n", team)); } -#if (KMP_OS_LINUX || KMP_OS_FREEBSD) && KMP_AFFINITY_SUPPORTED +#if (KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_DARWIN) && 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_partition_places(team); #endif } else { // team->t.t_nproc < new_nproc -#if (KMP_OS_LINUX || KMP_OS_FREEBSD) && KMP_AFFINITY_SUPPORTED +#if (KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_DARWIN) && KMP_AFFINITY_SUPPORTED kmp_affin_mask_t *old_mask; if (KMP_AFFINITY_CAPABLE()) { KMP_CPU_ALLOC(old_mask); @@ -5090,7 +5090,7 @@ __kmp_reinitialize_team(team, new_icvs, NULL); } -#if (KMP_OS_LINUX || KMP_OS_FREEBSD) && KMP_AFFINITY_SUPPORTED +#if (KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_DARWIN) && 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 @@ } } -#if (KMP_OS_LINUX || KMP_OS_FREEBSD) && KMP_AFFINITY_SUPPORTED +#if (KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_DARWIN) && KMP_AFFINITY_SUPPORTED if (KMP_AFFINITY_CAPABLE()) { /* Restore initial master thread's affinity mask */ __kmp_set_system_affinity(old_mask, TRUE); Index: openmp/runtime/src/z_Linux_util.cpp =================================================================== --- openmp/runtime/src/z_Linux_util.cpp +++ openmp/runtime/src/z_Linux_util.cpp @@ -100,7 +100,7 @@ } #endif -#if ((KMP_OS_LINUX || KMP_OS_FREEBSD) && KMP_AFFINITY_SUPPORTED) +#if ((KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_DARWIN) && KMP_AFFINITY_SUPPORTED) /* Affinity support */ @@ -126,6 +126,8 @@ #define KMP_CPU_SET_SIZE_LIMIT (1024 * 1024) #elif KMP_OS_FREEBSD #define KMP_CPU_SET_SIZE_LIMIT (sizeof(cpuset_t)) +#elif KMP_OS_DARWIN +#define KMP_CPU_SET_SIZE_LIMIT (sizeof(thread_affinity_policy_data_t)) #endif @@ -291,6 +293,25 @@ KMP_INTERNAL_FREE(buf); return; } +#elif KMP_OS_DARWIN + kern_return_t gCode; + unsigned char *buf; + boolean_t def = true; + mach_msg_type_number_t cnt = THREAD_AFFINITY_POLICY_COUNT; + buf = (unsigned char *)KMP_INTERNAL_MALLOC(KMP_CPU_SET_SIZE_LIMIT); + gCode = thread_policy_get(mach_thread_self(), THREAD_AFFINITY_POLICY, + reinterpret_cast(buf), &cnt, &def); + KA_TRACE(30, ("__kmp_affinity_determine_capable: " + "initial getaffinity call returned %d errno = %d\n", + gCode, errno)); + if (gCode == KERN_SUCCESS) { + 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;