MEDIUM: config: use platform independent type hap_cpuset for cpu-map

Use the platform independent type hap_cpuset for the cpu-map statement
parsing. This allow to address CPU index greater than LONGBITS.

Update the documentation to reflect the removal of this limit except for
platforms without cpu_set_t type or equivalent.
diff --git a/src/cfgparse-global.c b/src/cfgparse-global.c
index 40f3018..694cd70 100644
--- a/src/cfgparse-global.c
+++ b/src/cfgparse-global.c
@@ -1,4 +1,3 @@
-#define _GNU_SOURCE  /* for CPU_* from cpuset.h */
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -1028,9 +1027,9 @@
 		/* map a process list to a CPU set */
 #ifdef USE_CPU_AFFINITY
 		char *slash;
-		unsigned long proc = 0, thread = 0, cpus;
-		int i, j, n, k, autoinc;
-		struct hap_cpuset cpuset;
+		unsigned long proc = 0, thread = 0;
+		int i, j, n, autoinc;
+		struct hap_cpuset cpus, cpus_copy;
 
 		if (!*args[1] || !*args[2]) {
 			ha_alert("parsing [%s:%d] : %s expects a process number "
@@ -1071,26 +1070,15 @@
 			}
 		}
 
-		if (parse_cpu_set((const char **)args+2, &cpuset, &errmsg)) {
+		if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
 			ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
 			err_code |= ERR_ALERT | ERR_FATAL;
 			goto out;
 		}
-#if defined(CPUSET_USE_CPUSET)
-		k = 0;
-		while (CPU_COUNT(&cpuset.cpuset)) {
-			while (!CPU_ISSET(k, &cpuset.cpuset))
-				++k;
-			cpus |= 1 << k;
-			CPU_CLR(k, &cpuset.cpuset);
-			++k;
-		}
-#elif defined(CPUSET_USE_ULONG)
-		cpus = cpuset.cpuset;
-#endif
+
 		if (autoinc &&
-		    my_popcountl(proc)  != my_popcountl(cpus) &&
-		    my_popcountl(thread) != my_popcountl(cpus)) {
+		    my_popcountl(proc) != ha_cpuset_count(&cpus) &&
+		    my_popcountl(thread) != ha_cpuset_count(&cpus)) {
 			ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
 				 "must have the same size to be automatically bound\n",
 				 file, linenum, args[0]);
@@ -1111,16 +1099,19 @@
 		 */
 		if (!thread) {
 			/* mapping for whole processes. E.g. cpu-map 1-4 0-3 */
+			ha_cpuset_assign(&cpus_copy, &cpus);
 			for (i = n = 0; i < MAX_PROCS; i++) {
 				/* No mapping for this process */
 				if (!(proc & (1UL << i)))
 					continue;
 
 				if (!autoinc)
-					global.cpu_map.proc[i] = cpus;
+					ha_cpuset_assign(&global.cpu_map.proc[i], &cpus);
 				else {
-					n += my_ffsl(cpus >> n);
-					global.cpu_map.proc[i] = (1UL << (n-1));
+					ha_cpuset_zero(&global.cpu_map.proc[i]);
+					n = ha_cpuset_ffs(&cpus_copy) - 1;
+					ha_cpuset_clr(&cpus_copy, n);
+					ha_cpuset_set(&global.cpu_map.proc[i], n);
 				}
 			}
 		} else {
@@ -1129,44 +1120,48 @@
 			 * other combinations are silently ignored.
 			 */
 			if (thread == 0x1) {
-				int val;
-
 				/* first thread, iterate on processes. E.g. cpu-map 1-4/1 0-3 */
+				struct hap_cpuset *dst;
+
+				ha_cpuset_assign(&cpus_copy, &cpus);
 				for (i = n = 0; i < MAX_PROCS; i++) {
 					/* No mapping for this process */
 					if (!(proc & (1UL << i)))
 						continue;
 
+					/* For first process, thread[0] is used.
+					 * Use proc_t1[N] for all others
+					 */
+					dst = i ? &global.cpu_map.proc_t1[i] :
+					          &global.cpu_map.thread[0];
+
 					if (!autoinc) {
-						val = cpus;
+						ha_cpuset_assign(dst, &cpus);
 					}
 					else {
-						n += my_ffsl(cpus >> n);
-						val = 1UL << (n - 1);
+						ha_cpuset_zero(dst);
+						n = ha_cpuset_ffs(&cpus_copy) - 1;
+						ha_cpuset_clr(&cpus_copy, n);
+						ha_cpuset_set(dst, n);
 					}
-
-					/* For first process, thread[0] is used.
-					 * Use proc_t1[N] for all others
-					 */
-					if (!i)
-						global.cpu_map.thread[0] = val;
-					else
-						global.cpu_map.proc_t1[i] = val;
 				}
 			}
 
 			if (proc == 0x1) {
 				/* first process, iterate on threads. E.g. cpu-map 1/1-4 0-3 */
+				ha_cpuset_assign(&cpus_copy, &cpus);
 				for (j = n = 0; j < MAX_THREADS; j++) {
 					/* No mapping for this thread */
 					if (!(thread & (1UL << j)))
 						continue;
 
 					if (!autoinc)
-						global.cpu_map.thread[j] = cpus;
+						ha_cpuset_assign(&global.cpu_map.thread[j], &cpus);
 					else {
-						n += my_ffsl(cpus >> n);
-						global.cpu_map.thread[j] = (1UL << (n-1));
+						ha_cpuset_zero(&global.cpu_map.thread[j]);
+						n = ha_cpuset_ffs(&cpus_copy) - 1;
+						ha_cpuset_clr(&cpus_copy, n);
+						ha_cpuset_set(&global.cpu_map.thread[j], n);
 					}
 				}
 			}
diff --git a/src/haproxy.c b/src/haproxy.c
index ecc5f21..58e9e62 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -92,6 +92,7 @@
 #include <haproxy/chunk.h>
 #include <haproxy/cli.h>
 #include <haproxy/connection.h>
+#include <haproxy/cpuset.h>
 #include <haproxy/dns.h>
 #include <haproxy/dynbuf.h>
 #include <haproxy/errors.h>
@@ -1268,6 +1269,7 @@
 	struct proxy *px;
 	struct post_check_fct *pcf;
 	int ideal_maxconn;
+	int i;
 
 	global.mode = MODE_STARTING;
 	old_argv = copy_argv(argc, argv);
@@ -1576,6 +1578,12 @@
 
 	global.maxsock = 10; /* reserve 10 fds ; will be incremented by socket eaters */
 
+	for (i = 0; i < MAX_PROCS; ++i) {
+		ha_cpuset_zero(&global.cpu_map.proc[i]);
+		ha_cpuset_zero(&global.cpu_map.proc_t1[i]);
+		ha_cpuset_zero(&global.cpu_map.thread[i]);
+	}
+
 	/* in wait mode, we don't try to read the configuration files */
 	if (!(global.mode & MODE_MWORKER_WAIT)) {
 		char *env_cfgfiles = NULL;
@@ -2925,23 +2933,15 @@
 #ifdef USE_CPU_AFFINITY
 		if (proc < global.nbproc &&  /* child */
 		    proc < MAX_PROCS &&       /* only the first 32/64 processes may be pinned */
-		    global.cpu_map.proc[proc])    /* only do this if the process has a CPU map */
-#ifdef __FreeBSD__
-		{
-			cpuset_t cpuset;
-			int i;
-			unsigned long cpu_map = global.cpu_map.proc[proc];
+		    ha_cpuset_count(&global.cpu_map.proc[proc])) {   /* only do this if the process has a CPU map */
 
-			CPU_ZERO(&cpuset);
-			while ((i = ffsl(cpu_map)) > 0) {
-				CPU_SET(i - 1, &cpuset);
-				cpu_map &= ~(1UL << (i - 1));
-			}
-			ret = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(cpuset), &cpuset);
-		}
+			struct hap_cpuset *set = &global.cpu_map.proc[proc];
+#ifdef __FreeBSD__
+			ret = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(set->cpuset), &set->cpuset);
 #elif defined(__linux__) || defined(__DragonFly__)
-			sched_setaffinity(0, sizeof(unsigned long), (void *)&global.cpu_map.proc[proc]);
+			sched_setaffinity(0, sizeof(set->cpuset), &set->cpuset);
 #endif
+		}
 #endif
 		/* close the pidfile both in children and father */
 		if (pidfd >= 0) {
@@ -3179,14 +3179,14 @@
 			global.cpu_map.thread[0] = global.cpu_map.proc_t1[relative_pid-1];
 
 		for (i = 0; i < global.nbthread; i++) {
-			if (global.cpu_map.proc[relative_pid-1])
-				global.cpu_map.thread[i] &= global.cpu_map.proc[relative_pid-1];
+			if (ha_cpuset_count(&global.cpu_map.proc[relative_pid-1]))
+				ha_cpuset_and(&global.cpu_map.thread[i], &global.cpu_map.proc[relative_pid-1]);
 
 			if (i < MAX_THREADS &&       /* only the first 32/64 threads may be pinned */
-			    global.cpu_map.thread[i]) {/* only do this if the thread has a THREAD map */
+			    ha_cpuset_count(&global.cpu_map.thread[i])) {/* only do this if the thread has a THREAD map */
 #if defined(__APPLE__)
 				int j;
-				unsigned long cpu_map = global.cpu_map.thread[i];
+				unsigned long cpu_map = global.cpu_map.thread[i].cpuset;
 
 				while ((j = ffsl(cpu_map)) > 0) {
 					thread_affinity_policy_data_t cpu_set = { j - 1 };
@@ -3195,22 +3195,9 @@
 					cpu_map &= ~(1UL << (j - 1));
 				}
 #else
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-				cpuset_t cpuset;
-#else
-				cpu_set_t cpuset;
-#endif
-				int j;
-				unsigned long cpu_map = global.cpu_map.thread[i];
-
-				CPU_ZERO(&cpuset);
-
-				while ((j = ffsl(cpu_map)) > 0) {
-					CPU_SET(j - 1, &cpuset);
-					cpu_map &= ~(1UL << (j - 1));
-				}
+				struct hap_cpuset *set = &global.cpu_map.thread[i];
 				pthread_setaffinity_np(ha_thread_info[i].pthread,
-						       sizeof(cpuset), &cpuset);
+				                       sizeof(set->cpuset), &set->cpuset);
 #endif
 			}
 		}