From e4ba7a600e70bce0065a2fde0f2f85cdee746cfb Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Tue, 20 Apr 2010 17:37:51 +0200
Subject: [PATCH] re PR libgomp/43706 (scheduling two threads on one core leads
 to starvation)

	PR libgomp/43706
	* config/linux/affinity.c (gomp_init_affinity): Decrease
	gomp_available_cpus if affinity mask confines the process to fewer
	CPUs.
	* config/linux/proc.c (get_num_procs): If gomp_cpu_affinity is
	non-NULL, just return gomp_available_cpus.

From-SVN: r158565
---
 libgomp/ChangeLog               |  7 +++++++
 libgomp/config/linux/affinity.c | 17 ++++++++++++++---
 libgomp/config/linux/proc.c     | 24 ++++++------------------
 3 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 7756ac15a2e0..95c1f00cac9e 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,5 +1,12 @@
 2010-04-20  Jakub Jelinek  <jakub@redhat.com>
 
+	PR libgomp/43706
+	* config/linux/affinity.c (gomp_init_affinity): Decrease
+	gomp_available_cpus if affinity mask confines the process to fewer
+	CPUs.
+	* config/linux/proc.c (get_num_procs): If gomp_cpu_affinity is
+	non-NULL, just return gomp_available_cpus.
+
 	PR libgomp/43569
 	* sections.c (gomp_sections_init): Initialize ws->mode.
 
diff --git a/libgomp/config/linux/affinity.c b/libgomp/config/linux/affinity.c
index 40519e8896ae..da9f3d8fdcb0 100644
--- a/libgomp/config/linux/affinity.c
+++ b/libgomp/config/linux/affinity.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
    Contributed by Jakub Jelinek <jakub@redhat.com>.
 
    This file is part of the GNU OpenMP Library (libgomp).
@@ -39,8 +39,9 @@ static unsigned int affinity_counter;
 void
 gomp_init_affinity (void)
 {
-  cpu_set_t cpuset;
+  cpu_set_t cpuset, cpusetnew;
   size_t idx, widx;
+  unsigned long cpus = 0;
 
   if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset), &cpuset))
     {
@@ -51,10 +52,18 @@ gomp_init_affinity (void)
       return;
     }
 
+  CPU_ZERO (&cpusetnew);
   for (widx = idx = 0; idx < gomp_cpu_affinity_len; idx++)
     if (gomp_cpu_affinity[idx] < CPU_SETSIZE
         && CPU_ISSET (gomp_cpu_affinity[idx], &cpuset))
-      gomp_cpu_affinity[widx++] = gomp_cpu_affinity[idx];
+      {
+	if (! CPU_ISSET (gomp_cpu_affinity[idx], &cpusetnew))
+	  {
+	    cpus++;
+	    CPU_SET (gomp_cpu_affinity[idx], &cpusetnew);
+	  }
+	gomp_cpu_affinity[widx++] = gomp_cpu_affinity[idx];
+      }
 
   if (widx == 0)
     {
@@ -66,6 +75,8 @@ gomp_init_affinity (void)
     }
 
   gomp_cpu_affinity_len = widx;
+  if (cpus < gomp_available_cpus)
+    gomp_available_cpus = cpus;
   CPU_ZERO (&cpuset);
   CPU_SET (gomp_cpu_affinity[0], &cpuset);
   pthread_setaffinity_np (pthread_self (), sizeof (cpuset), &cpuset);
diff --git a/libgomp/config/linux/proc.c b/libgomp/config/linux/proc.c
index dad6237e6099..01f51dfa1938 100644
--- a/libgomp/config/linux/proc.c
+++ b/libgomp/config/linux/proc.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
    Contributed by Jakub Jelinek <jakub@redhat.com>.
 
    This file is part of the GNU OpenMP Library (libgomp).
@@ -104,26 +105,13 @@ get_num_procs (void)
     }
   else
     {
-      size_t idx;
-      static int affinity_cpus;
-
       /* 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.  */
-      CPU_ZERO (&cpuset);
-      if (affinity_cpus == 0)
-	{
-	  int cpus = 0;
-	  for (idx = 0; idx < gomp_cpu_affinity_len; idx++)
-	    if (! CPU_ISSET (gomp_cpu_affinity[idx], &cpuset))
-	      {
-		cpus++;
-		CPU_SET (gomp_cpu_affinity[idx], &cpuset);
-	      }
-	  affinity_cpus = cpus;
-	}
-      return affinity_cpus;
+	 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
 #ifdef _SC_NPROCESSORS_ONLN
-- 
GitLab