[PATCH] libnuma:

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Cliff Wickman <cpw@xxxxxxx>

The numa_num_task_cpus() function should return the number of cpu's
available to the caller.  It was returning his highest available cpu
number (+1).
That was an erroneous assumption when the caller is in a cpuset where
available cpu's are not numbered 0..N.

Likewise, numa_num_task_nodes() was doing the same thing.

This patch adds a numa_bitmask_weight() function to count set bits in the map
and makes it available for user convenience as well.
    
Signed-off-by: Cliff Wickman <cpw@xxxxxxx>

---
 libnuma.c         |   55 ++++++++++++++++++++++++++++--------------------------
 numa.3            |    8 +++++++
 versions.ldscript |    1 
 3 files changed, 38 insertions(+), 26 deletions(-)

Index: numactl-dev/libnuma.c
===================================================================
--- numactl-dev.orig/libnuma.c
+++ numactl-dev/libnuma.c
@@ -67,8 +67,8 @@ static __thread unsigned int mbind_flags
 static int sizes_set=0;
 static int maxconfigurednode = -1;
 static int maxconfiguredcpu = -1;
-static int maxprocnode = -1;
-static int maxproccpu = -1;
+static int numprocnode = -1;
+static int numproccpu = -1;
 static int nodemask_sz = 0;
 static int cpumask_sz = 0;
 
@@ -230,6 +230,18 @@ numa_bitmask_equal(const struct bitmask
 			return 0;
 	return 1;
 }
+
+/* Hamming Weight: number of set bits */
+unsigned int numa_bitmask_weight(const struct bitmask *bmp)
+{
+	unsigned int i;
+	unsigned int w = 0;
+	for (i = 0; i < bmp->size; i++)
+		if (_getbit(bmp, i))
+			w++;
+	return w;
+}
+
 /* *****end of bitmask_  routines ************ */
 
 /* Next two can be overwritten by the application for different error handling */
@@ -386,8 +398,7 @@ done:
 
 /*
  * Read a mask consisting of a sequence of hexadecimal longs separated by
- * commas. Order them correctly and return the number of the last bit
- * set.
+ * commas. Order them correctly and return the number of bits set.
  */
 static int
 read_mask(char *s, struct bitmask *bmp)
@@ -436,17 +447,10 @@ read_mask(char *s, struct bitmask *bmp)
 
 		bmp->maskp[m++] = x;
 	}
-	m--;
-
-	/* Poor mans fls() */
-	for(i = bitsperlong - 1; i >= 0; i--)
-		if (test_bit(i, bmp->maskp + m))
-			break;
-
 	/*
-	 * Return the last bit set
+	 * Return the number of bits set
 	 */
-	return bitsperlong * m + i;
+	return numa_bitmask_weight(bmp);
 }
 
 /*
@@ -477,11 +481,10 @@ set_task_constraints(void)
 		char  *mask = strrchr(buffer,'\t') + 1;
 
 		if (strncmp(buffer,"Cpus_allowed:",13) == 0)
-			maxproccpu = read_mask(mask, numa_all_cpus_ptr);
+			numproccpu = read_mask(mask, numa_all_cpus_ptr);
 
 		if (strncmp(buffer,"Mems_allowed:",13) == 0) {
-			maxprocnode =
-				read_mask(mask, numa_all_nodes_ptr);
+			numprocnode = read_mask(mask, numa_all_nodes_ptr);
 		}
 	}
 	fclose(f);
@@ -490,26 +493,26 @@ set_task_constraints(void)
 	/*
 	 * Cpus_allowed in the kernel can be defined to all f's
 	 * i.e. it may be a superset of the actual available processors.
-	 * As such let's reduce maxproccpu to the number of actual
-	 * available cpus - 1.
+	 * As such let's reduce numproccpu to the number of actual
+	 * available cpus.
 	 */
-	if (maxproccpu <= 0) {
+	if (numproccpu <= 0) {
 		for (i = 0; i <= hicpu; i++)
 			numa_bitmask_setbit(numa_all_cpus_ptr, i);
-		maxproccpu = hicpu;
+		numproccpu = hicpu+1;
 	}
 
-	if (maxproccpu > hicpu) {
-		maxproccpu = hicpu;
+	if (numproccpu > hicpu+1) {
+		numproccpu = hicpu+1;
 		for (i=hicpu+1; i<numa_all_cpus_ptr->size; i++) {
 			numa_bitmask_clearbit(numa_all_cpus_ptr, i);
 		}
 	}
 
-	if (maxprocnode <= 0) {
+	if (numprocnode <= 0) {
 		for (i = 0; i <= maxconfigurednode; i++)
 			numa_bitmask_setbit(numa_all_nodes_ptr, i);
-		maxprocnode = maxconfigurednode;
+		numprocnode = maxconfigurednode + 1;
 	}
 
 	return;
@@ -632,7 +635,7 @@ numa_num_possible_cpus(void)
 int
 numa_num_task_nodes(void)
 {
-	return maxprocnode+1;
+	return numprocnode;
 }
 
 /*
@@ -647,7 +650,7 @@ numa_num_thread_nodes(void)
 int
 numa_num_task_cpus(void)
 {
-	return maxproccpu+1;
+	return numproccpu;
 }
 
 /*
Index: numactl-dev/numa.3
===================================================================
--- numactl-dev.orig/numa.3
+++ numactl-dev/numa.3
@@ -149,6 +149,8 @@ numa \- NUMA policy library
 .BI "void copy_nodemask_to_bitmask(nodemask_t *" nodemask ", struct bitmask *" bmp )
 .br
 .BI "void copy_bitmask_to_bitmask(struct bitmask *" bmpfrom ", struct bitmask *" bmpto )
+.br
+.BI "unsigned int numa_bitmask_weight(const struct bitmask *bmp )
 .sp
 .BI "int numa_move_pages(int " pid ", unsigned long " count ", void **" pages ", const int *" nodes ", int *" status ", int " flags );
 .br
@@ -860,6 +862,12 @@ pointer to the body of the bitmask struc
 pointer. If the two areas differ in size, the copy is truncated to the size
 of the receiving field or zero-filled.
 
+.BR numa_bitmask_weight()
+returns a count of the bits that are set in the body of the bitmask pointed
+to by the
+.I bmp
+argument.
+
 .br
 .BR numa_move_pages()
 moves a list of pages in the address space of the currently
Index: numactl-dev/versions.ldscript
===================================================================
--- numactl-dev.orig/versions.ldscript
+++ numactl-dev/versions.ldscript
@@ -100,6 +100,7 @@ libnuma_1.2 {
     numa_bitmask_nbytes;
     numa_bitmask_setall;
     numa_bitmask_setbit;
+    numa_bitmask_weight;
     numa_distance;
     numa_error;
     numa_exit_on_error;
--
To unsubscribe from this list: send the line "unsubscribe linux-numa" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]     [Devices]

  Powered by Linux