Signed-off-by: Robbie King <[email protected]>
---
 helper/include/odph_linux.h                       |  28 ++--
 platform/linux-generic/Makefile.am                |   4 +-
 platform/linux-generic/include/api/odp.h          |   2 +-
 platform/linux-generic/include/api/odp_coremask.h | 186 ---------------------
 platform/linux-generic/include/api/odp_cpumask.h  | 167 ++++++++++++++++++
 platform/linux-generic/include/api/odp_queue.h    |   6 +-
 platform/linux-generic/odp_coremask.c             | 109 ------------
 platform/linux-generic/odp_cpumask.c              | 195 ++++++++++++++++++++++
 platform/linux-generic/odp_linux.c                | 107 +++++++++---
 9 files changed, 467 insertions(+), 337 deletions(-)
 delete mode 100644 platform/linux-generic/include/api/odp_coremask.h
 create mode 100644 platform/linux-generic/include/api/odp_cpumask.h
 delete mode 100644 platform/linux-generic/odp_coremask.c
 create mode 100644 platform/linux-generic/odp_cpumask.c

diff --git a/helper/include/odph_linux.h b/helper/include/odph_linux.h
index 4ed8bbe..15e2dbf 100644
--- a/helper/include/odph_linux.h
+++ b/helper/include/odph_linux.h
@@ -26,6 +26,8 @@ extern "C" {
 #include <pthread.h>
 #include <sys/types.h>
 
+#include <odp.h>
+
 /** Linux pthread state information */
 typedef struct {
        pthread_t      thread; /**< Pthread ID */
@@ -41,23 +43,30 @@ typedef struct {
        int   status;   /**< Process state change status */
 } odph_linux_process_t;
 
+/**
+ * Creates default pthread/process cpumask
+ *
+ * Creates cpumask based on starting count, actual value returned
+ *
+ * @param mask          CPU mask to initialize
+ * @param num           Number of threads to create, zero for all available
+ * @return Actual values of CPUs used to create mask
+ */
+int odph_linux_cpumask_default(odp_cpumask_t *mask, int num);
 
 /**
  * Creates and launches pthreads
  *
- * Creates, pins and launches num threads to separate CPU's starting from
- * first_cpu.
+ * Creates, pins and launches threads to separate CPU's based on the cpumask.
  *
  * @param thread_tbl    Thread table
- * @param num           Number of threads to create
- * @param first_cpu     First physical CPU
+ * @param mask          CPU mask
  * @param start_routine Thread start function
  * @param arg           Thread argument
  */
 void odph_linux_pthread_create(odph_linux_pthread_t *thread_tbl,
-                             int num, int first_cpu,
-                             void *(*start_routine) (void *), void *arg);
-
+                               odp_cpumask_t *mask,
+                               void *(*start_routine) (void *), void *arg);
 
 /**
  * Waits pthreads to exit
@@ -91,14 +100,13 @@ int odph_linux_process_fork(odph_linux_process_t *proc, 
int cpu);
  * Forks and sets CPU affinity for child processes
  *
  * @param proc_tbl      Process state info table (for output)
- * @param num           Number of processes to create
- * @param first_cpu     Destination CPU for the first process
+ * @param mask          CPU mask of processes to create
  *
  * @return On success: 1 for the parent, 0 for the child
  *         On failure: -1 for the parent, -2 for the child
  */
 int odph_linux_process_fork_n(odph_linux_process_t *proc_tbl,
-                             int num, int first_cpu);
+                             odp_cpumask_t *mask);
 
 
 /**
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 4535c57..a699ea6 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -16,7 +16,7 @@ include_HEADERS = \
                  
$(top_srcdir)/platform/linux-generic/include/api/odp_classification.h \
                  
$(top_srcdir)/platform/linux-generic/include/api/odp_compiler.h \
                  $(top_srcdir)/platform/linux-generic/include/api/odp_config.h 
\
-                 
$(top_srcdir)/platform/linux-generic/include/api/odp_coremask.h \
+                 
$(top_srcdir)/platform/linux-generic/include/api/odp_cpumask.h \
                  $(top_srcdir)/platform/linux-generic/include/api/odp_crypto.h 
\
                  $(top_srcdir)/platform/linux-generic/include/api/odp_debug.h \
                  $(top_srcdir)/platform/linux-generic/include/api/odp_hints.h \
@@ -78,7 +78,7 @@ __LIB__libodp_la_SOURCES = \
                           odp_buffer.c \
                           odp_buffer_pool.c \
                           odp_classification.c \
-                          odp_coremask.c \
+                          odp_cpumask.c \
                           odp_crypto.c \
                           odp_init.c \
                           odp_impl.c \
diff --git a/platform/linux-generic/include/api/odp.h 
b/platform/linux-generic/include/api/odp.h
index b7b1ca9..1cc7ce0 100644
--- a/platform/linux-generic/include/api/odp.h
+++ b/platform/linux-generic/include/api/odp.h
@@ -27,7 +27,7 @@ extern "C" {
 #include <odp_hints.h>
 #include <odp_debug.h>
 #include <odp_byteorder.h>
-#include <odp_coremask.h>
+#include <odp_cpumask.h>
 #include <odp_barrier.h>
 #include <odp_spinlock.h>
 #include <odp_atomic.h>
diff --git a/platform/linux-generic/include/api/odp_coremask.h 
b/platform/linux-generic/include/api/odp_coremask.h
deleted file mode 100644
index d4172fa..0000000
--- a/platform/linux-generic/include/api/odp_coremask.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier:     BSD-3-Clause
- */
-
-
-/**
- * @file
- *
- * ODP core masks and enumeration
- */
-
-#ifndef ODP_COREMASK_H_
-#define ODP_COREMASK_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-#include <odp_std_types.h>
-
-/** @addtogroup odp_scheduler
- *  Core mask operations.
- *  @{
- */
-
-/** @internal */
-#define ODP_COREMASK_SIZE_U64  1
-
-/**
- * Core mask
- *
- * Don't access directly, use access functions.
- */
-typedef struct odp_coremask_t {
-       uint64_t _u64[ODP_COREMASK_SIZE_U64]; /**< @private Mask*/
-
-} odp_coremask_t;
-
-
-
-/**
- * Add core mask bits from a string
- *
- * @param str    Hexadecimal digits in a string. Core #0 is located
- *               at the least significant bit (0x1).
- * @param mask   Core mask to modify
- *
- * @note Supports currently only core indexes upto 63
- */
-void odp_coremask_from_str(const char *str, odp_coremask_t *mask);
-
-/**
- * Write core mask as a string of hexadecimal digits
- *
- * @param str    String for output
- * @param len    Size of string length (incl. ending zero)
- * @param mask   Core mask
- *
- * @note Supports currently only core indexes upto 63
- */
-void odp_coremask_to_str(char *str, int len, const odp_coremask_t *mask);
-
-
-/**
- * Add core mask bits from a u64 array
- *
- * In the array core #0 is located at the least significant bit
- * of the first word (u64[0] = 0x1).
- *
- * Examples
- * core 0:  u64[0] = 0x1
- * core 1:  u64[0] = 0x2
- * ...
- * core 63: u64[0] = 0x8000 0000 0000 0000
- * core 64: u64[0] = 0x0, u64[1] = 0x1
- * core 65: u64[0] = 0x0, u64[1] = 0x2
- *
- * @param u64    An array of u64 bit words
- * @param num    Number of u64 words in the array
- * @param mask   Core mask to modify
- *
- * @note Supports currently only core indexes upto 63
- */
-void odp_coremask_from_u64(const uint64_t *u64, int num, odp_coremask_t *mask);
-
-/**
- * Clear entire mask
- * @param mask Core mask to flush with zero value
- */
-static inline void odp_coremask_zero(odp_coremask_t *mask)
-{
-       mask->_u64[0] = 0;
-}
-
-/**
- * Add core to mask
- * @param core  Core number
- * @param mask  add core number in core mask
- */
-void odp_coremask_set(int core, odp_coremask_t *mask);
-
-/**
- * Remove core from mask
- * @param core  Core number
- * @param mask  clear core number from core mask
- */
-void odp_coremask_clr(int core, odp_coremask_t *mask);
-
-/**
- * Test if core is a member of mask
- * @param core  Core number
- * @param mask  Core mask to check if core num set or not
- * @return      non-zero if set otherwise 0
- */
-int odp_coremask_isset(int core, const odp_coremask_t *mask);
-
-/**
- * Count number of cores in mask
- * @param mask  Core mask
- * @return coremask count
- */
-int odp_coremask_count(const odp_coremask_t *mask);
-
-
-
-/**
- * Logical AND over two source masks.
- *
- * @param dest    Destination mask, can be one of the source masks
- * @param src1    Source mask 1
- * @param src2    Source mask 2
- */
-static inline void odp_coremask_and(odp_coremask_t *dest, odp_coremask_t *src1,
-                                   odp_coremask_t *src2)
-{
-       dest->_u64[0] = src1->_u64[0] & src2->_u64[0];
-}
-
-/**
- * Logical OR over two source masks.
- *
- * @param dest    Destination mask, can be one of the source masks
- * @param src1    Source mask 1
- * @param src2    Source mask 2
- */
-static inline void odp_coremask_or(odp_coremask_t *dest, odp_coremask_t *src1,
-                                  odp_coremask_t *src2)
-{
-       dest->_u64[0] = src1->_u64[0] | src2->_u64[0];
-}
-
-/**
- * Logical XOR over two source masks.
- *
- * @param dest    Destination mask, can be one of the source masks
- * @param src1    Source mask 1
- * @param src2    Source mask 2
- */
-static inline void odp_coremask_xor(odp_coremask_t *dest, odp_coremask_t *src1,
-                                   odp_coremask_t *src2)
-{
-       dest->_u64[0] = src1->_u64[0] ^ src2->_u64[0];
-}
-
-/**
- * Test if two masks contain the same cores
- */
-static inline int odp_coremask_equal(odp_coremask_t *mask1,
-                                    odp_coremask_t *mask2)
-{
-       return (mask1->_u64[0] == mask2->_u64[0]);
-}
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/platform/linux-generic/include/api/odp_cpumask.h 
b/platform/linux-generic/include/api/odp_cpumask.h
new file mode 100644
index 0000000..9744589
--- /dev/null
+++ b/platform/linux-generic/include/api/odp_cpumask.h
@@ -0,0 +1,167 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+
+/**
+ * @file
+ *
+ * ODP CPU masks and enumeration
+ */
+
+#ifndef ODP_CPUMASK_H_
+#define ODP_CPUMASK_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+#include <sched.h>
+
+#include <odp_std_types.h>
+
+/** @addtogroup odp_scheduler
+ *  CPU mask operations.
+ *  @{
+ */
+
+/**
+ * CPU mask
+ *
+ * Don't access directly, use access functions.
+ */
+typedef struct odp_cpumask_t {
+       cpu_set_t set; /**< @private Mask*/
+} odp_cpumask_t;
+
+/**
+ * Add CPU mask bits from a string
+ *
+ * @param str    Hexadecimal digits in a string. CPU #0 is located
+ *               at the least significant bit (0x1).
+ * @param mask   CPU mask to modify
+ */
+void odp_cpumask_from_str(const char *str, odp_cpumask_t *mask);
+
+/**
+ * Write CPU mask as a string of hexadecimal digits
+ *
+ * @param str    String for output
+ * @param len    Size of string length (incl. ending zero)
+ * @param mask   CPU mask
+ */
+void odp_cpumask_to_str(char *str, int len, const odp_cpumask_t *mask);
+
+/**
+ * Clear entire mask
+ * @param mask CPU mask to flush with zero value
+ */
+void odp_cpumask_zero(odp_cpumask_t *mask);
+
+/**
+ * Add cpu to mask
+ * @param mask  add cpu number in CPU mask
+ * @param cpu   CPU number
+ */
+void odp_cpumask_set(odp_cpumask_t *mask, int cpu);
+
+/**
+ * Remove cpu from mask
+ * @param mask  clear cpu number from CPU mask
+ * @param cpu   CPU number
+ */
+void odp_cpumask_clr(odp_cpumask_t *mask, int cpu);
+
+/**
+ * Test if cpu is a member of mask
+ * @param mask  CPU mask to check if cpu num set or not
+ * @param cpu   CPU number
+ * @return      non-zero if set otherwise 0
+ */
+int odp_cpumask_isset(const odp_cpumask_t *mask, int cpu);
+
+/**
+ * Count number of cpus in mask
+ * @param mask  CPU mask
+ * @return cpumask count
+ */
+int odp_cpumask_count(const odp_cpumask_t *mask);
+
+/**
+ * Logical AND over two source masks.
+ *
+ * @param dest    Destination mask, can be one of the source masks
+ * @param src1    Source mask 1
+ * @param src2    Source mask 2
+ */
+void odp_cpumask_and(odp_cpumask_t *dest, odp_cpumask_t *src1,
+                    odp_cpumask_t *src2);
+
+/**
+ * Logical OR over two source masks.
+ *
+ * @param dest    Destination mask, can be one of the source masks
+ * @param src1    Source mask 1
+ * @param src2    Source mask 2
+ */
+void odp_cpumask_or(odp_cpumask_t *dest, odp_cpumask_t *src1,
+                   odp_cpumask_t *src2);
+
+/**
+ * Logical XOR over two source masks.
+ *
+ * @param dest    Destination mask, can be one of the source masks
+ * @param src1    Source mask 1
+ * @param src2    Source mask 2
+ */
+void odp_cpumask_xor(odp_cpumask_t *dest, odp_cpumask_t *src1,
+                    odp_cpumask_t *src2);
+
+/**
+ * Test if two masks contain the same cpus
+ */
+int odp_cpumask_equal(odp_cpumask_t *mask1,
+                     odp_cpumask_t *mask2);
+
+/**
+ * Copy a CPU mask
+ */
+void odp_cpumask_copy(odp_cpumask_t *dest, odp_cpumask_t *src);
+
+/**
+ * Find first bit set in mask
+ *
+ * @return cpu else -1 if no bits set in cpumask
+ */
+int odp_cpumask_first(const odp_cpumask_t *mask);
+
+/**
+ * Find last bit set in mask
+ *
+ * @return cpu else -1 if no bits set in cpumask
+ */
+int odp_cpumask_last(const odp_cpumask_t *mask);
+
+/**
+ * Find next cpu in mask
+ *
+ * Finds the next cpu in the CPU mask, starting at the cpu passed.
+ *
+ * @param mask        CPU mask to find next cpu in
+ * @param cpu         CPU to start from
+ * @return cpu found else -1
+ */
+int odp_cpumask_next(const odp_cpumask_t *mask, int cpu);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/api/odp_queue.h 
b/platform/linux-generic/include/api/odp_queue.h
index af4379f..b0f7185 100644
--- a/platform/linux-generic/include/api/odp_queue.h
+++ b/platform/linux-generic/include/api/odp_queue.h
@@ -85,14 +85,14 @@ typedef int odp_schedule_sync_t;
 #define ODP_SCHED_SYNC_DEFAULT  ODP_SCHED_SYNC_ATOMIC
 
 /**
- * ODP schedule core group
+ * ODP schedule CPU group
  */
 typedef int odp_schedule_group_t;
 
-/** Group of all cores */
+/** Group of all CPUs */
 #define ODP_SCHED_GROUP_ALL     0
 
-/** Default core group */
+/** Default CPU group */
 #define ODP_SCHED_GROUP_DEFAULT ODP_SCHED_GROUP_ALL
 
 
diff --git a/platform/linux-generic/odp_coremask.c 
b/platform/linux-generic/odp_coremask.c
deleted file mode 100644
index 54cd333..0000000
--- a/platform/linux-generic/odp_coremask.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier:     BSD-3-Clause
- */
-
-#include <odp_coremask.h>
-#include <odp_debug_internal.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#define MAX_CORE_NUM   64
-
-
-void odp_coremask_from_str(const char *str, odp_coremask_t *mask)
-{
-       uint64_t mask_u64;
-
-       if (strlen(str) > 18) {
-               /* more than 64 bits */
-               return;
-       }
-
-       mask_u64 = strtoull(str, NULL, 16);
-
-       odp_coremask_from_u64(&mask_u64, 1, mask);
-}
-
-
-void odp_coremask_to_str(char *str, int len, const odp_coremask_t *mask)
-{
-       int ret;
-
-       ret = snprintf(str, len, "0x%"PRIx64"", mask->_u64[0]);
-
-       if (ret >= 0 && ret < len) {
-               /* force trailing zero */
-               str[len-1] = '\0';
-       }
-}
-
-
-void odp_coremask_from_u64(const uint64_t *u64, int num, odp_coremask_t *mask)
-{
-       int i;
-
-       if (num > ODP_COREMASK_SIZE_U64) {
-               /* force max size */
-               num = ODP_COREMASK_SIZE_U64;
-       }
-
-       for (i = 0; i < num; i++)
-               mask->_u64[0] |= u64[i];
-}
-
-void odp_coremask_set(int core, odp_coremask_t *mask)
-{
-       /* should not be more than 63
-        * core no. should be from 0..63= 64bit
-        */
-       if (core >= MAX_CORE_NUM) {
-               ODP_ERR("invalid core count\n");
-               return;
-       }
-
-       mask->_u64[0] |=  (1ULL << core);
-}
-
-void odp_coremask_clr(int core, odp_coremask_t *mask)
-{
-       /* should not be more than 63
-        * core no. should be from 0..63= 64bit
-        */
-       if (core >= MAX_CORE_NUM) {
-               ODP_ERR("invalid core count\n");
-               return;
-       }
-
-       mask->_u64[0] &= ~(1ULL << core);
-}
-
-
-int odp_coremask_isset(int core, const odp_coremask_t *mask)
-{
-       /* should not be more than 63
-        * core no. should be from 0..63= 64bit
-        */
-       if (core >= MAX_CORE_NUM) {
-               ODP_ERR("invalid core count\n");
-               return -1;
-       }
-
-       return (mask->_u64[0] >> core) & 1;
-}
-
-int odp_coremask_count(const odp_coremask_t *mask)
-{
-       uint64_t coremask = mask->_u64[0];
-       int cnt = 0;
-
-       while (coremask != 0) {
-               coremask >>= 1;
-               if (coremask & 1)
-                       cnt++;
-       }
-
-       return cnt;
-}
diff --git a/platform/linux-generic/odp_cpumask.c 
b/platform/linux-generic/odp_cpumask.c
new file mode 100644
index 0000000..5ba07b9
--- /dev/null
+++ b/platform/linux-generic/odp_cpumask.c
@@ -0,0 +1,195 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <sched.h>
+
+#include <odp_cpumask.h>
+#include <odp_debug_internal.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+void odp_cpumask_from_str(const char *str_in, odp_cpumask_t *mask)
+{
+       cpu_set_t cpuset;
+       const char *str = str_in;
+       const char *p;
+       int cpu = 0;
+       int len = strlen(str);
+
+       CPU_ZERO(&cpuset);
+       odp_cpumask_zero(mask);
+
+       /* Strip leading "0x"/"0X" if present and verify length */
+       if ((len >= 2) && ((str[1] == 'x') || (str[1] == 'X'))) {
+               str += 2;
+               len -= 2;
+       }
+       if (!len)
+               return;
+
+       /* Walk string from LSB setting cpu bits */
+       for (p = str + len - 1; (len > 0) && (cpu < CPU_SETSIZE); p--, len--) {
+               char c = *p;
+               int value;
+               int idx;
+
+               /* Convert hex nibble, abort when invalid value found */
+               if ((c >= '0') && (c <= '9'))
+                       value = c - '0';
+               else if ((c >= 'A') && (c <= 'F'))
+                       value = c - 'A' + 10;
+               else if ((c >= 'a') && (c <= 'f'))
+                       value = c - 'a' + 10;
+               else
+                       return;
+
+               /* Walk converted nibble and set bits in mask */
+               for (idx = 0; idx < 4; idx++, cpu++)
+                       if (value & (1 << idx))
+                               CPU_SET(cpu, &cpuset);
+       }
+
+       /* Copy the computed mask */
+       memcpy(&mask->set, &cpuset, sizeof(cpuset));
+}
+
+void odp_cpumask_to_str(char *str, int len, const odp_cpumask_t *mask)
+{
+       char *p = str;
+       int cpu = odp_cpumask_last(mask);
+       int nibbles;
+       int value;
+
+       /* Quickly handle bad string length or empty mask */
+       if (len <= 0)
+               return;
+       *str = 0;
+       if (cpu < 0) {
+               if (len >= 4)
+                       strcpy(str, "0x0");
+               return;
+       }
+
+       /* Compute number nibbles in cpumask that have bits set */
+       nibbles = (cpu / 4) + 1;
+
+       /* Verify minimum space (account for "0x" and termination) */
+       if (len < (3 + nibbles))
+               return;
+
+       /* Prefix */
+       *p++ = '0';
+       *p++ = 'x';
+
+       /*
+        * Now we can scan the cpus down to zero and
+        * build the string one nibble at a time
+        */
+       value = 0;
+       do {
+               /* Set bit to go into the current nibble */
+               if (CPU_ISSET(cpu, &mask->set))
+                       value |= 1 << (cpu % 4);
+
+               /* If we are on a nibble boundary flush value to string */
+               if (0 == (cpu % 4)) {
+                       if (value < 0xA)
+                               *p++ = '0' + value;
+                       else
+                               *p++ = 'A' + value - 0xA;
+                       value = 0;
+               }
+       } while (cpu--);
+
+       /* Terminate the string */
+       *p++ = 0;
+}
+
+void odp_cpumask_zero(odp_cpumask_t *mask)
+{
+       CPU_ZERO(&mask->set);
+}
+
+void odp_cpumask_set(odp_cpumask_t *mask, int cpu)
+{
+       CPU_SET(cpu, &mask->set);
+}
+
+void odp_cpumask_clr(odp_cpumask_t *mask, int cpu)
+{
+       CPU_CLR(cpu, &mask->set);
+}
+
+int odp_cpumask_isset(const odp_cpumask_t *mask, int cpu)
+{
+       return CPU_ISSET(cpu, &mask->set);
+}
+
+int odp_cpumask_count(const odp_cpumask_t *mask)
+{
+       return CPU_COUNT(&mask->set);
+}
+
+void odp_cpumask_and(odp_cpumask_t *dest, odp_cpumask_t *src1,
+                    odp_cpumask_t *src2)
+{
+       CPU_AND(&dest->set, &src1->set, &src2->set);
+}
+
+void odp_cpumask_or(odp_cpumask_t *dest, odp_cpumask_t *src1,
+                   odp_cpumask_t *src2)
+{
+       CPU_OR(&dest->set, &src1->set, &src2->set);
+}
+
+void odp_cpumask_xor(odp_cpumask_t *dest, odp_cpumask_t *src1,
+                    odp_cpumask_t *src2)
+{
+       CPU_XOR(&dest->set, &src1->set, &src2->set);
+}
+
+int odp_cpumask_equal(odp_cpumask_t *mask1,
+                     odp_cpumask_t *mask2)
+{
+       return CPU_EQUAL(&mask1->set, &mask2->set);
+}
+
+void odp_cpumask_copy(odp_cpumask_t *dest, odp_cpumask_t *src)
+{
+       memcpy(&dest->set, &src->set, sizeof(src->set));
+}
+
+int odp_cpumask_first(const odp_cpumask_t *mask)
+{
+       int cpu;
+
+       for (cpu = 0; cpu < CPU_SETSIZE; cpu++)
+               if (odp_cpumask_isset(mask, cpu))
+                       return cpu;
+       return -1;
+}
+
+int odp_cpumask_last(const odp_cpumask_t *mask)
+{
+       int cpu;
+
+       for (cpu = CPU_SETSIZE - 1; cpu >= 0; cpu--)
+               if (odp_cpumask_isset(mask, cpu))
+                       return cpu;
+       return -1;
+}
+
+int odp_cpumask_next(const odp_cpumask_t *mask, int cpu)
+{
+       for (cpu += 1; cpu < CPU_SETSIZE; cpu++)
+               if (odp_cpumask_isset(mask, cpu))
+                       return cpu;
+       return -1;
+}
diff --git a/platform/linux-generic/odp_linux.c 
b/platform/linux-generic/odp_linux.c
index 79192cf..d419bd8 100644
--- a/platform/linux-generic/odp_linux.c
+++ b/platform/linux-generic/odp_linux.c
@@ -25,6 +25,7 @@
 #include <odp_system_info.h>
 #include <odp_debug_internal.h>
 
+#define MAX_WORKERS 32
 
 typedef struct {
        void *(*start_routine) (void *);
@@ -33,6 +34,42 @@ typedef struct {
 } odp_start_args_t;
 
 
+int odph_linux_cpumask_default(odp_cpumask_t *mask, int num_in)
+{
+       int i;
+       int first_cpu = 1;
+       int num = num_in;
+       int cpu_count;
+
+       cpu_count = odp_sys_cpu_count();
+
+       /*
+        * If no user supplied number or it's too large, then attempt
+        * to use all CPUs
+        */
+       if (0 == num)
+               num = cpu_count;
+       if (cpu_count < num)
+               num = cpu_count;
+
+       /*
+        * Always force "first_cpu" to a valid CPU
+        */
+       if (first_cpu >= cpu_count)
+               first_cpu = cpu_count - 1;
+
+       /* Build the mask */
+       odp_cpumask_zero(mask);
+       for (i = 0; i < num; i++) {
+               int cpu;
+
+               cpu = (first_cpu + i) % cpu_count;
+               odp_cpumask_set(mask, cpu);
+       }
+
+       return num;
+}
+
 static void *odp_run_start_routine(void *arg)
 {
        odp_start_args_t *start_args = arg;
@@ -55,33 +92,42 @@ static void *odp_run_start_routine(void *arg)
 }
 
 
-void odph_linux_pthread_create(odph_linux_pthread_t *thread_tbl, int num,
-                              int first_cpu,
+void odph_linux_pthread_create(odph_linux_pthread_t *thread_tbl,
+                              odp_cpumask_t *mask_in,
                               void *(*start_routine) (void *), void *arg)
 {
        int i;
-       cpu_set_t cpu_set;
+       int num;
+       odp_cpumask_t mask;
        odp_start_args_t *start_args;
        int cpu_count;
        int cpu;
 
-       cpu_count = odp_sys_cpu_count();
-
-       assert((first_cpu >= 0) && (first_cpu < cpu_count));
-       assert((num >= 0) && (num <= cpu_count));
+       odp_cpumask_copy(&mask, mask_in);
+       num = odp_cpumask_count(&mask);
 
        memset(thread_tbl, 0, num * sizeof(odph_linux_pthread_t));
 
+       cpu_count = odp_sys_cpu_count();
+
+       if (num < 1 || num > cpu_count) {
+               ODP_ERR("Bad num\n");
+               return;
+       }
+
+       cpu = odp_cpumask_first(&mask);
        for (i = 0; i < num; i++) {
+               odp_cpumask_t thd_mask;
+
+               odp_cpumask_zero(&thd_mask);
+               odp_cpumask_set(&thd_mask, cpu);
+
                pthread_attr_init(&thread_tbl[i].attr);
 
-               cpu = (first_cpu + i) % cpu_count;
                thread_tbl[i].cpu = cpu;
-               CPU_ZERO(&cpu_set);
-               CPU_SET(cpu, &cpu_set);
 
                pthread_attr_setaffinity_np(&thread_tbl[i].attr,
-                                           sizeof(cpu_set_t), &cpu_set);
+                                           sizeof(cpu_set_t), &thd_mask.set);
 
                start_args = malloc(sizeof(odp_start_args_t));
                if (start_args == NULL)
@@ -93,6 +139,8 @@ void odph_linux_pthread_create(odph_linux_pthread_t 
*thread_tbl, int num,
 
                pthread_create(&thread_tbl[i].thread, &thread_tbl[i].attr,
                               odp_run_start_routine, start_args);
+
+               cpu = odp_cpumask_next(&mask, cpu);
        }
 }
 
@@ -109,30 +157,34 @@ void odph_linux_pthread_join(odph_linux_pthread_t 
*thread_tbl, int num)
 
 
 int odph_linux_process_fork_n(odph_linux_process_t *proc_tbl,
-                             int num, int first_cpu)
+                             odp_cpumask_t *mask_in)
 {
-       cpu_set_t cpu_set;
+       odp_cpumask_t mask;
        pid_t pid;
+       int num;
        int cpu_count;
        int cpu;
        int i;
 
-       memset(proc_tbl, 0, num*sizeof(odph_linux_process_t));
+       odp_cpumask_copy(&mask, mask_in);
+       num = odp_cpumask_count(&mask);
 
-       cpu_count = odp_sys_cpu_count();
+       memset(proc_tbl, 0, num * sizeof(odph_linux_process_t));
 
-       if (first_cpu < 0 || first_cpu >= cpu_count) {
-               ODP_ERR("Bad first_cpu\n");
-               return -1;
-       }
+       cpu_count = odp_sys_cpu_count();
 
-       if (num < 0 || num > cpu_count) {
+       if (num < 1 || num > cpu_count) {
                ODP_ERR("Bad num\n");
                return -1;
        }
 
+       cpu = odp_cpumask_first(&mask);
        for (i = 0; i < num; i++) {
-               cpu = (first_cpu + i) % cpu_count;
+               odp_cpumask_t proc_mask;
+
+               odp_cpumask_zero(&proc_mask);
+               odp_cpumask_set(&proc_mask, cpu);
+
                pid = fork();
 
                if (pid < 0) {
@@ -144,14 +196,13 @@ int odph_linux_process_fork_n(odph_linux_process_t 
*proc_tbl,
                if (pid > 0) {
                        proc_tbl[i].pid  = pid;
                        proc_tbl[i].cpu = cpu;
+
+                       cpu = odp_cpumask_next(&mask, cpu);
                        continue;
                }
 
                /* Child process */
-               CPU_ZERO(&cpu_set);
-               CPU_SET(cpu, &cpu_set);
-
-               if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set)) {
+               if (sched_setaffinity(0, sizeof(cpu_set_t), &proc_mask.set)) {
                        ODP_ERR("sched_setaffinity() failed\n");
                        return -2;
                }
@@ -170,7 +221,11 @@ int odph_linux_process_fork_n(odph_linux_process_t 
*proc_tbl,
 
 int odph_linux_process_fork(odph_linux_process_t *proc, int cpu)
 {
-       return odph_linux_process_fork_n(proc, 1, cpu);
+       odp_cpumask_t mask;
+
+       odp_cpumask_zero(&mask);
+       odp_cpumask_set(&mask, cpu);
+       return odph_linux_process_fork_n(proc, &mask);
 }
 
 
-- 
1.9.1


_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to