Commit 01275e1e by Jakub Jelinek Committed by Jakub Jelinek

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
parent ba7629e2
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.
......
......@@ -222,60 +222,32 @@ gomp_affinity_finalize_place_list (bool quiet)
return true;
}
bool
gomp_affinity_init_level (int level, unsigned long count, bool quiet)
static void
gomp_affinity_init_level_1 (int level, int this_level, unsigned long count,
cpu_set_t *copy, char *name, 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;
unsigned long i, max = 8 * gomp_cpuset_size;
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");
i, this_level == 3 ? "core" : "thread");
f = fopen (name, "r");
if (f != NULL)
if (f == NULL)
{
CPU_CLR_S (i, gomp_cpuset_size, copy);
continue;
}
if (getline (&line, &linelen, f) > 0)
{
char *p = line;
bool seen_i = false;
void *pl = gomp_places_list[gomp_places_list_len];
if (level == this_level)
gomp_affinity_init_place (pl);
while (*p && *p != '\n')
{
......@@ -293,35 +265,70 @@ gomp_affinity_init_level (int level, unsigned long count, bool quiet)
break;
}
for (; first <= last; first++)
if (CPU_ISSET_S (first, gomp_cpuset_size, copy)
&& gomp_affinity_add_cpus (pl, first, 1, 0,
true))
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 (first == i)
seen_i = true;
if (level == 1)
gomp_places_list_len++;
}
}
if (*p == ',')
++p;
}
if (seen_i)
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)
{
char name[sizeof ("/sys/devices/system/cpu/cpu/topology/"
"thread_siblings_list") + 3 * sizeof (unsigned long)];
cpu_set_t *copy;
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;
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)
{
if (!quiet)
gomp_error ("Error reading %s topology",
level == 2 ? "core" : "socket");
gomp_error ("Error reading core/socket topology");
free (gomp_places_list);
gomp_places_list = NULL;
return false;
}
return true;
}
return false;
}
void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment