MINOR: config: make MAX_PROCS configurable at build time

For some embedded systems, it's pointless to have 32- or even 64- large
arrays of processes when it's known that much fewer processes will be
used in the worst case. Let's introduce this MAX_PROCS define which
contains the highest number of processes allowed to run at once. It
still defaults to LONGBITS but may be lowered.
diff --git a/src/cfgparse-global.c b/src/cfgparse-global.c
index 820c7b6..e1835e7 100644
--- a/src/cfgparse-global.c
+++ b/src/cfgparse-global.c
@@ -490,9 +490,9 @@
 		}
 		global.nbproc = atol(args[1]);
 		all_proc_mask = nbits(global.nbproc);
-		if (global.nbproc < 1 || global.nbproc > LONGBITS) {
+		if (global.nbproc < 1 || global.nbproc > MAX_PROCS) {
 			ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
-				 file, linenum, args[0], LONGBITS, global.nbproc);
+				 file, linenum, args[0], MAX_PROCS, global.nbproc);
 			err_code |= ERR_ALERT | ERR_FATAL;
 			goto out;
 		}
@@ -942,7 +942,7 @@
 			ha_alert("parsing [%s:%d] : %s expects a process number "
 				 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
 				 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
-				 file, linenum, args[0], LONGBITS, LONGBITS - 1);
+				 file, linenum, args[0], MAX_PROCS, LONGBITS - 1);
 			err_code |= ERR_ALERT | ERR_FATAL;
 			goto out;
 		}
@@ -950,7 +950,7 @@
 		if ((slash = strchr(args[1], '/')) != NULL)
 			*slash = 0;
 
-		if (parse_process_number(args[1], &proc, LONGBITS, &autoinc, &errmsg)) {
+		if (parse_process_number(args[1], &proc, MAX_PROCS, &autoinc, &errmsg)) {
 			ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
 			err_code |= ERR_ALERT | ERR_FATAL;
 			goto out;
@@ -989,7 +989,7 @@
 			goto out;
 		}
 
-		for (i = n = 0; i < LONGBITS; i++) {
+		for (i = n = 0; i < MAX_PROCS; i++) {
 			/* No mapping for this process */
 			if (!(proc & (1UL << i)))
 				continue;
diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c
index 74218b5..5f44cfd 100644
--- a/src/cfgparse-listen.c
+++ b/src/cfgparse-listen.c
@@ -922,7 +922,7 @@
 				set = 0;
 				break;
 			}
-			if (parse_process_number(args[cur_arg], &set, LONGBITS, NULL, &errmsg)) {
+			if (parse_process_number(args[cur_arg], &set, MAX_PROCS, NULL, &errmsg)) {
 				ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
 				err_code |= ERR_ALERT | ERR_FATAL;
 				goto out;
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 1afb49c..d7d18c6 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2296,7 +2296,7 @@
 					mask >>= global.nbthread;
 				}
 
-				for (nbproc = 0; nbproc < LONGBITS; nbproc++) {
+				for (nbproc = 0; nbproc < MAX_PROCS; nbproc++) {
 					if (!bind_conf->bind_proc || (bind_conf->bind_proc & (1UL << nbproc)))
 						bind_conf->bind_thread[nbproc] = new_mask;
 				}
diff --git a/src/cli.c b/src/cli.c
index d1d1e96..3c2a55d 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -359,7 +359,7 @@
 				set = 0;
 				break;
 			}
-			if (parse_process_number(args[cur_arg], &set, LONGBITS, NULL, err)) {
+			if (parse_process_number(args[cur_arg], &set, MAX_PROCS, NULL, err)) {
 				memprintf(err, "'%s %s' : %s", args[0], args[1], *err);
 				return -1;
 			}
diff --git a/src/haproxy.c b/src/haproxy.c
index ce4cde3..7c434b3 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -2739,6 +2739,16 @@
 
 	setvbuf(stdout, NULL, _IONBF, 0);
 
+	/* this can only safely be done here, though it's optimized away by
+	 * the compiler.
+	 */
+	if (MAX_PROCS < 1 || MAX_PROCS > LONGBITS) {
+		ha_alert("MAX_PROCS value must be between 1 and %d inclusive; "
+		         "HAProxy was built with value %d, please fix it and rebuild.\n",
+			 LONGBITS, MAX_PROCS);
+		exit(1);
+	}
+
 	/* process all initcalls in order of potential dependency */
 	RUN_INITCALLS(STG_PREPARE);
 	RUN_INITCALLS(STG_LOCK);
@@ -3059,7 +3069,7 @@
 
 #ifdef USE_CPU_AFFINITY
 		if (proc < global.nbproc &&  /* child */
-		    proc < LONGBITS &&       /* only the first 32/64 processes may be pinned */
+		    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__
 		{
diff --git a/src/listener.c b/src/listener.c
index cb8cbda..e9ace41 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -962,7 +962,7 @@
 	if ((slash = strchr(args[cur_arg + 1], '/')) != NULL)
 		*slash = 0;
 
-	if (parse_process_number(args[cur_arg + 1], &proc, LONGBITS, NULL, err)) {
+	if (parse_process_number(args[cur_arg + 1], &proc, MAX_PROCS, NULL, err)) {
 		memprintf(err, "'%s' : %s", args[cur_arg], *err);
 		return ERR_ALERT | ERR_FATAL;
 	}
@@ -977,7 +977,7 @@
 
 	conf->bind_proc |= proc;
 	if (thread) {
-		for (i = 0; i < LONGBITS; i++)
+		for (i = 0; i < MAX_PROCS; i++)
 			if (!proc || (proc & (1UL << i)))
 				conf->bind_thread[i] |= thread;
 	}