[m-rev.] diff: Fis thread pinning when libhwloc is not available.

Paul Bone pbone at csse.unimelb.edu.au
Wed Oct 19 16:50:27 AEDT 2011


glibc provides a type called cpu_set_t, see CPU_SET(3).  These types are
bitfields with one bit per cpu to represent a set of cpus.  These types
have an arbitrary width.  However, the man page is misleading about how to
specify the size of a cpuset (bits or bytes) to macros and functions than
manipulate it.  This patch corrects this problem.

runtime/mercury_context.c:
    Fix how the size of a CPU_SET is specified.

    Fix MR_pin_thread_no_locking() so that it returns a valid result if
    the thread could not be pinned or the loop (in this function) was never
    executed.

    Users can never set MR_num_processors, so remove the code that presumes
    they can.

Index: runtime/mercury_context.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_context.c,v
retrieving revision 1.101
diff -u -p -b -r1.101 mercury_context.c
--- runtime/mercury_context.c	16 Oct 2011 03:34:39 -0000	1.101
+++ runtime/mercury_context.c	19 Oct 2011 05:40:12 -0000
@@ -177,6 +177,8 @@ static hwloc_topology_t MR_hw_topology;
 static hwloc_cpuset_t   MR_hw_available_pus = NULL;
 #else /* MR_HAVE_SCHED_SETAFFINITY */
 static cpu_set_t        *MR_available_cpus;
+/* The number of CPUs that MR_available_cpus can refer to */
+static unsigned         MR_cpuset_size = 0;
 #endif
 #endif
 
@@ -345,7 +347,7 @@ MR_pin_thread_no_locking(void)
     fprintf(stderr, "Currently running on cpu %d\n", cpu);
 #endif
 
-    for (i = 0; i < MR_num_processors && MR_thread_pinning; i++) {
+    for (i = 0; (i < MR_num_processors) && MR_thread_pinning; i++) {
         if (MR_do_pin_thread((cpu + i) % MR_num_processors)) {
 #ifdef MR_DEBUG_THREAD_PINNING
             fprintf(stderr, "Pinned to cpu %d\n", (cpu + i) % MR_num_processors);
@@ -353,7 +355,7 @@ MR_pin_thread_no_locking(void)
 #endif
             MR_num_threads_left_to_pin--;
             MR_make_cpu_unavailable((cpu + i) % MR_num_processors);
-            break;
+            return (cpu + i) % MR_num_processors;
         }
         if (!MR_thread_pinning) {
             /*
@@ -366,7 +368,8 @@ MR_pin_thread_no_locking(void)
             break;
         }
     }
-    return (cpu + 1) % MR_num_processors;
+
+    return cpu;
 }
 
 unsigned
@@ -416,15 +419,7 @@ static void MR_setup_thread_pinning(void
     ** gathered by using sysconf.  But the number of CPUs in the CPU_SET is the
     ** actual number of CPUs that this process is restricted to.
     */
-  #if defined(MR_HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
-    num_processors = sysconf(_SC_NPROCESSORS_ONLN);
-  #else
-    /*
-    ** The user may have supplied MR_num_processors
-    */
-    num_processors = (MR_num_processors > 1 ? MR_num_processors : 1)
-  #endif
-    num_processors = CPU_COUNT_S(num_processors, MR_available_cpus);
+    num_processors = CPU_COUNT_S(MR_cpuset_size, MR_available_cpus);
 #endif
     MR_num_processors = num_processors;
 
@@ -450,7 +445,7 @@ static void MR_setup_thread_pinning(void
   ** if we autodetected the number of CPUs without error.
   */
 #if 0
-    if (MR_num_threads > 1) {
+    if (MR_num_processors > 1) {
         MR_thread_pinning = MR_TRUE;
     }
 #endif
@@ -513,13 +508,13 @@ MR_do_pin_thread(int cpu)
         return MR_FALSE;
     }
 #elif defined(MR_HAVE_SCHED_SETAFFINITY)
-    if (CPU_COUNT_S(MR_num_processors, MR_available_cpus) == 0) {
+    if (CPU_COUNT_S(MR_cpuset_size, MR_available_cpus) == 0) {
         /*
         ** As above, reset the available cpus.
         */
         MR_reset_available_cpus();
     }
-    if (!CPU_ISSET_S(cpu, MR_num_processors, MR_available_cpus)) {
+    if (!CPU_ISSET_S(cpu, MR_cpuset_size, MR_available_cpus)) {
         return MR_FALSE;
     }
 #endif
@@ -537,9 +532,9 @@ MR_do_pin_thread(int cpu)
 
     cpus = CPU_ALLOC(MR_num_processors);
 
-    CPU_ZERO_S(MR_num_processors, cpus);
-    CPU_SET_S(cpu, MR_num_processors, cpus);
-    if (sched_setaffinity(0, CPU_ALLOC_SIZE(MR_num_processors), cpus) == -1) {
+    CPU_ZERO_S(MR_cpuset_size, cpus);
+    CPU_SET_S(cpu, MR_cpuset_size, cpus);
+    if (sched_setaffinity(0, MR_cpuset_size, cpus) == -1) {
         perror("Warning: Couldn't set CPU affinity: ");
         /*
         ** If this failed once, it will probably fail again,
@@ -581,23 +576,30 @@ static void MR_reset_available_cpus(void
 
     hwloc_cpuset_free(inherited_binding);
 #elif defined(MR_HAVE_SCHED_GETAFFINITY)
+    unsigned cpuset_size;
     unsigned num_processors;
 
+    if (MR_cpuset_size) {
+        cpuset_size = MR_cpuset_size;
+        num_processors = MR_num_processors;
+    } else {
   #if defined(MR_HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
     num_processors = sysconf(_SC_NPROCESSORS_ONLN);
   #else
     /*
-    ** The user may have supplied MR_num_processors
+        ** Make the CPU set at least 32 processors wide.
     */
-    num_processors = (MR_num_processors > 1 ? MR_num_processors : 1)
+        num_processors = 32;
   #endif
+        cpuset_size = CPU_ALLOC_SIZE(num_processors);
+        MR_cpuset_size = cpuset_size;
+    }
 
     if (MR_available_cpus == NULL) {
         MR_available_cpus = CPU_ALLOC(num_processors);
     }
 
-    if (-1 == sched_getaffinity(0, CPU_ALLOC_SIZE(num_processors),
-        MR_available_cpus))
+    if (-1 == sched_getaffinity(0, cpuset_size, MR_available_cpus))
     {
         perror("Couldn't get CPU affinity");
         MR_thread_pinning = MR_FALSE;
@@ -618,7 +620,7 @@ static void MR_make_cpu_unavailable(int 
     pu = hwloc_get_obj_by_type(MR_hw_topology, HWLOC_OBJ_PU, cpu);
     MR_make_pu_unavailable(pu);
 #elif defined(MR_HAVE_SCHED_SETAFFINITY)
-    CPU_CLR_S(cpu, MR_num_processors, MR_available_cpus);
+    CPU_CLR_S(cpu, MR_cpuset_size, MR_available_cpus);
 #endif
 }
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 489 bytes
Desc: Digital signature
URL: <http://lists.mercurylang.org/archives/reviews/attachments/20111019/25541365/attachment.sig>


More information about the reviews mailing list