aboutsummaryrefslogtreecommitdiff
path: root/libgomp
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-05-30 14:05:30 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2017-05-30 14:05:30 +0200
commit01275e1e5a8d45f35121f4ce7345dd62e55cf60e (patch)
tree6e6e460487e536f7cc1a6782355c11a9cc9266ce /libgomp
parentba7629e2dd50baaa34acb9430c2087073685c0fa (diff)
downloadgcc-01275e1e5a8d45f35121f4ce7345dd62e55cf60e.zip
gcc-01275e1e5a8d45f35121f4ce7345dd62e55cf60e.tar.gz
gcc-01275e1e5a8d45f35121f4ce7345dd62e55cf60e.tar.bz2
re PR libgomp/80822 (libgomp incorrect affinity when OMP_PLACES=threads)
PR libgomp/80822 * config/linux/affinity.c (gomp_affinity_init_level_1): New function. (gomp_affinity_init_level): Use it. Always analyze the core and thread sibling lists, depending on level just pick up what CPUs to put together into a place vs. whether add multiple ordered places. From-SVN: r248683
Diffstat (limited to 'libgomp')
-rw-r--r--libgomp/ChangeLog8
-rw-r--r--libgomp/config/linux/affinity.c173
2 files changed, 98 insertions, 83 deletions
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 8adc10b..a51228b 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,11 @@
+2017-05-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/80822
+ * config/linux/affinity.c (gomp_affinity_init_level_1): New function.
+ (gomp_affinity_init_level): Use it. Always analyze the core and thread
+ sibling lists, depending on level just pick up what CPUs to put
+ together into a place vs. whether add multiple ordered places.
+
2017-05-24 Thomas Schwinge <thomas@codesourcery.com>
* openacc.h (acc_async_wait, acc_async_wait_all): New prototypes.
diff --git a/libgomp/config/linux/affinity.c b/libgomp/config/linux/affinity.c
index c5b2cb8..cbc9687 100644
--- a/libgomp/config/linux/affinity.c
+++ b/libgomp/config/linux/affinity.c
@@ -222,10 +222,87 @@ gomp_affinity_finalize_place_list (bool quiet)
return true;
}
+static void
+gomp_affinity_init_level_1 (int level, int this_level, unsigned long count,
+ cpu_set_t *copy, char *name, bool quiet)
+{
+ size_t prefix_len = sizeof ("/sys/devices/system/cpu/cpu") - 1;
+ FILE *f;
+ char *line = NULL;
+ size_t linelen = 0;
+ unsigned long i, max = 8 * 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, this_level == 3 ? "core" : "thread");
+ f = fopen (name, "r");
+ if (f == NULL)
+ {
+ CPU_CLR_S (i, gomp_cpuset_size, copy);
+ continue;
+ }
+ if (getline (&line, &linelen, f) > 0)
+ {
+ char *p = line;
+ void *pl = gomp_places_list[gomp_places_list_len];
+ if (level == this_level)
+ 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))
+ continue;
+ else if (this_level == 3 && level < this_level)
+ gomp_affinity_init_level_1 (level, 2, count, copy,
+ name, quiet);
+ else
+ {
+ if (level == 1)
+ {
+ pl = gomp_places_list[gomp_places_list_len];
+ gomp_affinity_init_place (pl);
+ }
+ if (gomp_affinity_add_cpus (pl, first, 1, 0, true))
+ {
+ CPU_CLR_S (first, gomp_cpuset_size, copy);
+ if (level == 1)
+ gomp_places_list_len++;
+ }
+ }
+ if (*p == ',')
+ ++p;
+ }
+ if (level == this_level
+ && !CPU_ISSET_S (i, gomp_cpuset_size, copy))
+ gomp_places_list_len++;
+ CPU_CLR_S (i, gomp_cpuset_size, copy);
+ }
+ fclose (f);
+ }
+ free (line);
+}
+
bool
gomp_affinity_init_level (int level, unsigned long count, bool quiet)
{
- unsigned long i, max = 8 * gomp_cpuset_size;
+ char name[sizeof ("/sys/devices/system/cpu/cpu/topology/"
+ "thread_siblings_list") + 3 * sizeof (unsigned long)];
+ cpu_set_t *copy;
if (gomp_cpusetp)
{
@@ -238,90 +315,20 @@ gomp_affinity_init_level (int level, unsigned long count, bool 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
+
+ copy = gomp_alloca (gomp_cpuset_size);
+ strcpy (name, "/sys/devices/system/cpu/cpu");
+ memcpy (copy, gomp_cpusetp, gomp_cpuset_size);
+ gomp_affinity_init_level_1 (level, 3, count, copy, name, quiet);
+ if (gomp_places_list_len == 0)
{
- 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;
+ if (!quiet)
+ gomp_error ("Error reading core/socket topology");
+ free (gomp_places_list);
+ gomp_places_list = NULL;
+ return false;
}
- return false;
+ return true;
}
void