Module: xenomai-3
Branch: next
Commit: 3397f94bdd7d38edbccf9e96789db04cc81800a7
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=3397f94bdd7d38edbccf9e96789db04cc81800a7

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu May 25 10:33:40 2017 +0200

boilerplate/setup: accept CPU ranges in --cpu-affinity

e.g. --cpu-affinity=0-2 selects CPU0, CPU1 and CPU2.
     --cpu-affinity=3-4,7 selects CPU3, CPU4 and CPU7.
     --cpu-affinity=1- selects a range from CPU1 to the last CPU configured.

NOTE: if a selected CPU is configured but not online, the setup may
fail with -EINVAL.

---

 lib/boilerplate/setup.c |   69 ++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 56 insertions(+), 13 deletions(-)

diff --git a/lib/boilerplate/setup.c b/lib/boilerplate/setup.c
index e534e66..eb9b7e1 100644
--- a/lib/boilerplate/setup.c
+++ b/lib/boilerplate/setup.c
@@ -23,6 +23,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <ctype.h>
 #include <memory.h>
 #include <malloc.h>
 #include <stdarg.h>
@@ -150,20 +151,56 @@ static inline void dump_configuration(void)
        printf("AUTOMATIC_BOOTSTRAP=%d\n", xenomai_auto_bootstrap);
 }
 
+static inline int resolve_cpuid(const char *s)
+{
+       return isdigit(*s) ? atoi(s) : -1;
+}
+
 static int collect_cpu_affinity(const char *cpu_list)
 {
-       char *s = strdup(cpu_list), *p, *n;
-       int ret, cpu;
-
-       n = s;
-       while ((p = strtok(n, ",")) != NULL) {
-               cpu = atoi(p);
-               if (cpu >= CPU_SETSIZE) {
-                       free(s);
-                       early_warning("invalid CPU number '%d'", cpu);
-                       return -EINVAL;
+       char *s, *n, *range, *range_p = NULL, *id, *id_r;
+       int start, end, cpu, nr_cpus, ret;
+
+       /*
+        * We don't know which CPUs are online yet, but we may know
+        * which CPU identifier range is valid. Ask for the number of
+        * processors configured to find out.
+        */
+       nr_cpus = (int)sysconf(_SC_NPROCESSORS_CONF);
+       if (nr_cpus < 0) {
+               ret = -errno;
+               warning("sysconf(_SC_NPROCESSORS_CONF) failed [%s]", 
symerror(ret));
+               return ret;
+       }
+
+       s = n = strdup(cpu_list);
+       while ((range = strtok_r(n, ",", &range_p)) != NULL) {
+               if (*range == '\0')
+                       continue;
+               end = -1;
+               if (range[strlen(range)-1] == '-')
+                       end = nr_cpus - 1;
+               id = strtok_r(range, "-", &id_r);
+               if (id) {
+                       start = resolve_cpuid(id);
+                       if (*range == '-') {
+                               end = start;
+                               start = 0;
+                       }
+                       id = strtok_r(NULL, "-", &id_r);
+                       if (id)
+                               end = resolve_cpuid(id);
+                       else if (end < 0)
+                               end = start;
+                       if (start < 0 || start >= nr_cpus ||
+                           end < 0 || end >= nr_cpus)
+                               goto fail;
+               } else {
+                       start = 0;
+                       end = nr_cpus - 1;
                }
-               CPU_SET(cpu, &__base_setup_data.cpu_affinity);
+               for (cpu = start; cpu <= end; cpu++)
+                       CPU_SET(cpu, &__base_setup_data.cpu_affinity);
                n = NULL;
        }
 
@@ -182,11 +219,17 @@ static int collect_cpu_affinity(const char *cpu_list)
        ret = sched_setaffinity(0, sizeof(__base_setup_data.cpu_affinity),
                                &__base_setup_data.cpu_affinity);
        if (ret) {
-               early_warning("invalid CPU in affinity list '%s'", cpu_list);
-               return -errno;
+               ret = -errno;
+               early_warning("invalid CPU in '%s'", cpu_list);
+               return ret;
        }
 
        return 0;
+fail:
+       warning("invalid CPU number/range in '%s'", cpu_list);
+       free(s);
+
+       return -EINVAL;
 }
 
 static inline char **prep_args(int argc, char *const argv[], int *largcp)


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to