static int get_num_procs (void) { #ifdef HAVE_PTHREAD_AFFINITY_NP if (gomp_places_list == NULL) { /* Count only the CPUs this process can use. */ if (gomp_cpusetp && pthread_getaffinity_np (pthread_self (), gomp_get_cpuset_size, gomp_cpusetp) == 0) { int ret = gomp_cpuset_popcount (gomp_get_cpuset_size, gomp_cpusetp); return ret != 0 ? ret : 1; } } else { /* We can't use pthread_getaffinity_np in this case (we have changed it ourselves, it binds to just one CPU). Count instead the number of different CPUs we are using. gomp_init_affinity updated gomp_available_cpus to the number of CPUs in the GOMP_AFFINITY mask that we are allowed to use though. */ return gomp_available_cpus; } #endif #if defined(__ANDROID__) return sc_nprocessors_actu (); #elif defined(_SC_NPROCESSORS_ONLN) return sysconf (_SC_NPROCESSORS_ONLN); #else return gomp_icv (false)->nthreads_var; #endif }
int omp_get_place_num_procs (int place_num) { if (place_num < 0 || place_num >= gomp_places_list_len) return 0; cpu_set_t *cpusetp = (cpu_set_t *) gomp_places_list[place_num]; return gomp_cpuset_popcount (gomp_cpuset_size, cpusetp); }
bool gomp_affinity_finalize_place_list (bool quiet) { unsigned long i, j; for (i = 0, j = 0; i < gomp_places_list_len; i++) { cpu_set_t *cpusetp = (cpu_set_t *) gomp_places_list[i]; bool nonempty = false; #ifdef CPU_AND_S CPU_AND_S (gomp_cpuset_size, cpusetp, cpusetp, gomp_cpusetp); nonempty = gomp_cpuset_popcount (gomp_cpuset_size, cpusetp) != 0; #else unsigned long k, max = gomp_cpuset_size / sizeof (cpusetp->__bits[0]); for (k = 0; k < max; k++) if ((cpusetp->__bits[k] &= gomp_cpusetp->__bits[k]) != 0) nonempty = true; #endif if (nonempty) gomp_places_list[j++] = gomp_places_list[i]; } if (j == 0) { if (!quiet) gomp_error ("None of the places contain usable logical CPUs"); return false; } else if (j < gomp_places_list_len) { if (!quiet) gomp_error ("Number of places reduced from %ld to %ld because some " "places didn't contain any usable logical CPUs", gomp_places_list_len, j); gomp_places_list_len = j; } return true; }
void gomp_init_num_threads (void) { #ifdef HAVE_PTHREAD_AFFINITY_NP #if defined (_SC_NPROCESSORS_CONF) && defined (CPU_ALLOC_SIZE) gomp_cpuset_size = sysconf (_SC_NPROCESSORS_CONF); gomp_cpuset_size = CPU_ALLOC_SIZE (gomp_cpuset_size); #else gomp_cpuset_size = sizeof (cpu_set_t); #endif gomp_cpusetp = (cpu_set_t *) gomp_malloc (gomp_cpuset_size); do { int ret = pthread_getaffinity_np (pthread_self (), gomp_cpuset_size, gomp_cpusetp); if (ret == 0) { /* Count only the CPUs this process can use. */ gomp_global_icv.nthreads_var = gomp_cpuset_popcount (gomp_cpuset_size, gomp_cpusetp); if (gomp_global_icv.nthreads_var == 0) break; gomp_get_cpuset_size = gomp_cpuset_size; #ifdef CPU_ALLOC_SIZE unsigned long i; for (i = gomp_cpuset_size * 8; i; i--) if (CPU_ISSET_S (i - 1, gomp_cpuset_size, gomp_cpusetp)) break; gomp_cpuset_size = CPU_ALLOC_SIZE (i); #endif return; } if (ret != EINVAL) break; #ifdef CPU_ALLOC_SIZE if (gomp_cpuset_size < sizeof (cpu_set_t)) gomp_cpuset_size = sizeof (cpu_set_t); else gomp_cpuset_size = gomp_cpuset_size * 2; if (gomp_cpuset_size < 8 * sizeof (cpu_set_t)) gomp_cpusetp = (cpu_set_t *) gomp_realloc (gomp_cpusetp, gomp_cpuset_size); else { /* Avoid gomp_fatal if too large memory allocation would be requested, e.g. kernel returning EINVAL all the time. */ void *p = realloc (gomp_cpusetp, gomp_cpuset_size); if (p == NULL) break; gomp_cpusetp = (cpu_set_t *) p; } #else break; #endif } while (1); gomp_cpuset_size = 0; gomp_global_icv.nthreads_var = 1; free (gomp_cpusetp); gomp_cpusetp = NULL; #endif #if defined(__ANDROID__) gomp_global_icv.nthreads_var = sc_nprocessors_actu (); #elif defined(_SC_NPROCESSORS_ONLN) gomp_global_icv.nthreads_var = sysconf (_SC_NPROCESSORS_ONLN); #endif }
bool gomp_affinity_init_level (int level, unsigned long count, bool quiet) { unsigned long i, max = 8 * gomp_cpuset_size; if (gomp_cpusetp) { unsigned long maxcount = gomp_cpuset_popcount (gomp_cpuset_size, gomp_cpusetp); if (count > maxcount) count = maxcount; } gomp_places_list = gomp_affinity_alloc (count, quiet); gomp_places_list_len = 0; if (gomp_places_list == NULL) return false; /* SMT (threads). */ if (level == 1) { for (i = 0; i < max && gomp_places_list_len < count; i++) if (CPU_ISSET_S (i, gomp_cpuset_size, gomp_cpusetp)) { gomp_affinity_init_place (gomp_places_list[gomp_places_list_len]); gomp_affinity_add_cpus (gomp_places_list[gomp_places_list_len], i, 1, 0, true); ++gomp_places_list_len; } return true; } else { char name[sizeof ("/sys/devices/system/cpu/cpu/topology/" "thread_siblings_list") + 3 * sizeof (unsigned long)]; size_t prefix_len = sizeof ("/sys/devices/system/cpu/cpu") - 1; cpu_set_t *copy = gomp_alloca (gomp_cpuset_size); FILE *f; char *line = NULL; size_t linelen = 0; memcpy (name, "/sys/devices/system/cpu/cpu", prefix_len); memcpy (copy, gomp_cpusetp, gomp_cpuset_size); for (i = 0; i < max && gomp_places_list_len < count; i++) if (CPU_ISSET_S (i, gomp_cpuset_size, copy)) { sprintf (name + prefix_len, "%lu/topology/%s_siblings_list", i, level == 2 ? "thread" : "core"); f = fopen (name, "r"); if (f != NULL) { if (getline (&line, &linelen, f) > 0) { char *p = line; bool seen_i = false; void *pl = gomp_places_list[gomp_places_list_len]; gomp_affinity_init_place (pl); while (*p && *p != '\n') { unsigned long first, last; errno = 0; first = strtoul (p, &p, 10); if (errno) break; last = first; if (*p == '-') { errno = 0; last = strtoul (p + 1, &p, 10); if (errno || last < first) break; } for (; first <= last; first++) if (CPU_ISSET_S (first, gomp_cpuset_size, copy) && gomp_affinity_add_cpus (pl, first, 1, 0, true)) { CPU_CLR_S (first, gomp_cpuset_size, copy); if (first == i) seen_i = true; } if (*p == ',') ++p; } if (seen_i) gomp_places_list_len++; } fclose (f); } } if (gomp_places_list_len == 0) { if (!quiet) gomp_error ("Error reading %s topology", level == 2 ? "core" : "socket"); free (gomp_places_list); gomp_places_list = NULL; return false; } return true; } return false; }