static int ATL_setmyaffinity() /* * Attempts to sets the affinity of an already-running thread. The * aff_set flag is set to true whether we succeed or not (no point in * trying multiple times). * RETURNS: 0 on success, non-zero error code on error */ { int bindID; bindID = omp_get_thread_num(); #ifdef ATL_RANK_IS_PROCESSORID bindID = bindID % ATL_AFF_NUMID; #else bindID = ATL_affinityIDs[bindID%ATL_AFF_NUMID]; #endif #ifdef ATL_PAFF_PLPA plpa_cpu_set_t cpuset; PLPA_CPU_ZERO(&cpuset); PLPA_CPU_SET(bindID, &cpuset); if (me->paff_set) return(0); me->paff_set = 1; return(plpa_sched_setaffinity((pid_t)0, sizeof(cpuset), &cpuset)); #elif defined(ATL_PAFF_PBIND) return(processor_bind(P_LWPID, P_MYID, bindID, NULL)); #elif defined(ATL_PAFF_SCHED) cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(bindID, &cpuset); if (me->paff_set) return(0); me->paff_set = 1; return(sched_setaffinity(0, sizeof(cpuset), &cpuset)); #elif defined (ATL_PAFF_RUNON) if (me->paff_set) return(0); me->paff_set = 1; return(pthread_setrunon_np(bindID)); #elif defined(ATL_PAFF_BINDP) if (me->paff_set) return(0); me->paff_set = 1; return(bindprocessor(BINDTHREAD, thread_self(), bindID)); #elif defined(ATL_PAFF_CPUSET) /* untried FreeBSD code */ cpuset_t mycpuset; CPU_ZERO(&mycpuset); /* no manpage, so guess works like linux */ CPU_SET(bindID, &mycpuset); if (me->paff_set) return(0); me->paff_set = 1; return(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(mycpuset), &mycpuset)); #endif return(0); }
#ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_SYSCTL # ifdef HAVE_SYS_TYPES_H # include <sys/types.h> # endif # ifdef HAVE_SYS_SYSCTL_H # include <sys/sysctl.h> # endif #endif #if defined(HAVE_SYSCONF) && defined(HAVE_UNISTD_H) # include <unistd.h> #endif #include <plpa.h> #include "qt_affinity.h" #include "shufflesheps.h" qthread_shepherd_id_t guess_num_shepherds(void); qthread_worker_id_t guess_num_workers_per_shep(qthread_shepherd_id_t nshepherds); void INTERNAL qt_affinity_init(qthread_shepherd_id_t *nbshepherds, qthread_worker_id_t *nbworkers) { /*{{{ */ if (*nbshepherds == 0) { *nbshepherds = guess_num_shepherds(); if (*nbshepherds <= 0) { *nbshepherds = 1; } } if (*nbworkers == 0) { *nbworkers = guess_num_workers_per_shep(*nbshepherds); if (*nbworkers <= 0) { *nbworkers = 1; } } } /*}}} */ qthread_shepherd_id_t INTERNAL guess_num_shepherds(void) { /*{{{ */ qthread_shepherd_id_t nshepherds = 1; #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) /* Linux */ long ret = sysconf(_SC_NPROCESSORS_CONF); nshepherds = (ret > 0) ? ret : 1; #elif defined(HAVE_SYSCTL) && defined(CTL_HW) && defined(HW_NCPU) int name[2] = { CTL_HW, HW_NCPU }; uint32_t oldv; size_t oldvlen = sizeof(oldv); if (sysctl(name, 2, &oldv, &oldvlen, NULL, 0) >= 0) { assert(oldvlen == sizeof(oldv)); nshepherds = (int)oldv; } #endif /* if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) */ return nshepherds; } /*}}} */ #ifdef QTHREAD_MULTITHREADED_SHEPHERDS void INTERNAL qt_affinity_set(qthread_worker_t *me) { /*{{{ */ plpa_cpu_set_t *cpuset = (plpa_cpu_set_t *)MALLOC(sizeof(plpa_cpu_set_t)); PLPA_CPU_ZERO(cpuset); PLPA_CPU_SET(me->packed_worker_id, cpuset); if ((plpa_sched_setaffinity(0, sizeof(plpa_cpu_set_t), cpuset) < 0) && (errno != EINVAL)) { perror("plpa setaffinity"); } FREE(cpuset, sizeof(plpa_cpu_set_t)); } /*}}} */ #else /* ifdef QTHREAD_MULTITHREADED_SHEPHERDS */ void INTERNAL qt_affinity_set(qthread_shepherd_t *me) { /*{{{ */ plpa_cpu_set_t *cpuset = (plpa_cpu_set_t *)MALLOC(sizeof(plpa_cpu_set_t)); PLPA_CPU_ZERO(cpuset); PLPA_CPU_SET(me->node, cpuset); if ((plpa_sched_setaffinity(0, sizeof(plpa_cpu_set_t), cpuset) < 0) && (errno != EINVAL)) { perror("plpa setaffinity"); } FREE(cpuset, sizeof(plpa_cpu_set_t)); } /*}}} */
/****** shepherd_binding/bind_process_to_mask() ************************************* * NAME * bind_process_to_mask() -- Binds a process to a given cpuset (mask). * * SYNOPSIS * static bool bind_process_to_mask(const pid_t pid, const plpa_cpu_set_t * cpuset) * * FUNCTION * Binds a process to a given cpuset. * * INPUTS * const pid_t pid - Process to bind * const plpa_cpu_set_t cpuset - Processors to bind processes to * * RESULT * static bool - true if successful, false otherwise * * NOTES * MT-NOTE: bind_process_to_mask() is not MT safe * *******************************************************************************/ static bool bind_process_to_mask(const pid_t pid, const plpa_cpu_set_t cpuset) { if (has_core_binding()) { /* we only need core binding capabilites, no topology is required */ /* DG TODO delete addres and change header in order to make cputset to pointer */ if (plpa_sched_setaffinity(pid, sizeof(plpa_cpu_set_t), &cpuset) != 0) { return false; } else { return true; } } return false; }