diff options
author | Maxim Uvarov <maxim.uvarov@linaro.org> | 2015-07-29 19:04:20 +0100 |
---|---|---|
committer | Zoltan Kiss <zoltan.kiss@linaro.org> | 2015-07-29 19:04:20 +0100 |
commit | 2d7405baf12745bb83b0480e6b0086884ae86d80 (patch) | |
tree | 61495db96aa6116587beb19a50d7488d6745c932 /platform/linux-dpdk/odp_cpumask.c | |
parent | 97e47beb623c263b750d8dd1751cebd372b3d01d (diff) |
dpdk: use a local copy of odp_cpumask.c
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform/linux-dpdk/odp_cpumask.c')
-rw-r--r-- | platform/linux-dpdk/odp_cpumask.c | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/platform/linux-dpdk/odp_cpumask.c b/platform/linux-dpdk/odp_cpumask.c new file mode 100644 index 000000000..c28153bb6 --- /dev/null +++ b/platform/linux-dpdk/odp_cpumask.c @@ -0,0 +1,245 @@ +/* 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 <pthread.h> + +#include <odp/cpumask.h> +#include <odp_debug_internal.h> + +#include <stdlib.h> +#include <string.h> + +void odp_cpumask_from_str(odp_cpumask_t *mask, const char *str_in) +{ + 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)); +} + +int32_t odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, int32_t len) +{ + char *p = str; + int cpu = odp_cpumask_last(mask); + int nibbles; + int value; + + /* Handle bad string length, need at least 4 chars for "0x0" and + * terminating null char */ + if (len < 4) + return -1; /* Failure */ + + /* Handle no CPU found */ + if (cpu < 0) { + strcpy(str, "0x0"); + return strlen(str) + 1; /* Success */ + } + /* CPU was found and cpu >= 0 */ + + /* Compute number of nibbles in cpumask that have bits set */ + nibbles = (cpu / 4) + 1; + + /* Verify minimum space (account for "0x" and termination) */ + if (len < (3 + nibbles)) + return -1; /* Failure */ + + /* 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; + return p - str; /* Success */ +} + +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_setall(odp_cpumask_t *mask) +{ + int cpu; + + for (cpu = 0; cpu < CPU_SETSIZE; 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, const odp_cpumask_t *src1, + const odp_cpumask_t *src2) +{ + CPU_AND(&dest->set, &src1->set, &src2->set); +} + +void odp_cpumask_or(odp_cpumask_t *dest, const odp_cpumask_t *src1, + const odp_cpumask_t *src2) +{ + CPU_OR(&dest->set, &src1->set, &src2->set); +} + +void odp_cpumask_xor(odp_cpumask_t *dest, const odp_cpumask_t *src1, + const odp_cpumask_t *src2) +{ + CPU_XOR(&dest->set, &src1->set, &src2->set); +} + +int odp_cpumask_equal(const odp_cpumask_t *mask1, + const odp_cpumask_t *mask2) +{ + return CPU_EQUAL(&mask1->set, &mask2->set); +} + +void odp_cpumask_copy(odp_cpumask_t *dest, const 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; +} + +int odp_cpumask_def_worker(odp_cpumask_t *mask, int num) +{ + int ret, cpu, i; + cpu_set_t cpuset; + + ret = pthread_getaffinity_np(pthread_self(), + sizeof(cpu_set_t), &cpuset); + if (ret != 0) + ODP_ABORT("failed to read CPU affinity value\n"); + + odp_cpumask_zero(mask); + + /* + * If no user supplied number or it's too large, then attempt + * to use all CPUs + */ + if (0 == num || CPU_SETSIZE < num) + num = CPU_COUNT(&cpuset); + + /* build the mask, allocating down from highest numbered CPU */ + for (cpu = 0, i = CPU_SETSIZE - 1; i >= 0 && cpu < num; --i) { + if (CPU_ISSET(i, &cpuset)) { + odp_cpumask_set(mask, i); + cpu++; + } + } + + return cpu; +} + +int odp_cpumask_def_control(odp_cpumask_t *mask, int num ODP_UNUSED) +{ + odp_cpumask_zero(mask); + /* By default all control threads on CPU 0 */ + odp_cpumask_set(mask, 0); + return 1; +} |