diff --git a/include/sched.h b/include/sched.h index 6f3a8115c45..8733b8f46ce 100644 --- a/include/sched.h +++ b/include/sched.h @@ -66,6 +66,113 @@ #define PTHREAD_KEYS_MAX CONFIG_NPTHREAD_KEYS +/* CPU affinity mask helpers ***************************************************/ + +#ifdef CONFIG_SMP + +/* void CPU_ZERO(FAR cpu_set_t *set); */ + +# define CPU_ZERO(s) do { *(s) = 0; } while (0) + +/* void CPU_SET(int cpu, FAR cpu_set_t *set); */ + +# define CPU_SET(c,s) do { *(s) |= (1 << (c)); } while (0) + +/* void CPU_CLR(int cpu, FAR cpu_set_t *set); */ + +# define CPU_CLR(c,s) do { *(s) &= ~(1 << (c)); } while (0) + +/* int CPU_ISSET(int cpu, FAR const cpu_set_t *set); */ + +# define CPU_ISSET(c,s) ((*(s) & (1 << (c))) != 0) + +/* int CPU_COUNT(FAR const cpu_set_t *set); */ + +#define CPU_COUNT(s) sched_cpu_count(s) + +/* void CPU_AND(FAR cpu_set_t *destset, FAR const cpu_set_t *srcset1, + * FAR const cpu_set_t *srcset2); + */ + +# define CPU_AND(d,s1,s2) do { *(d) = *(s1) & *(s2); } while (0) + +/* void CPU_OR(FAR cpu_set_t *destset, FAR const cpu_set_t *srcset1, + * FAR const cpu_set_t *srcset2); + */ + +# define CPU_OR(d,s1,s2) do { *(d) = *(s1) | *(s2); } while (0) + +/* void CPU_XOR(FAR cpu_set_t *destset, FAR const cpu_set_t *srcset1, + * FAR const cpu_set_t *srcset2); + */ + +# define CPU_XOR(d,s1,s2) do { *(d) = *(s1) ^ *(s2); } while (0) + +/* int CPU_EQUAL(FAR const cpu_set_t *set1, FAR const cpu_set_t *set2); */ + +# define CPU_EQUAL(s1,s2) (*(s2) == *(s2)) + +/* FAR cpu_set_t *CPU_ALLOC(int num_cpus); */ + +# define CPU_ALLOC(n) (FAR cpu_set_t *)malloc(sizeof(cpu_set_t)); + +/* void CPU_FREE(cpu_set_t *set); */ + +# define CPU_ALLOC(s) free(s) + +/* size_t CPU_ALLOC_SIZE(int num_cpus); */ + +# define CPU_ALLOC_SIZE(n) sizeof(cpu_set_t) + +/* void CPU_ZERO_S(size_t setsize, FAR cpu_set_t *set); */ + +# define CPU_ZERO_S(n,s) CPU_ZERO_S(s) + +/* void CPU_SET_S(int cpu, size_t setsize, FAR cpu_set_t *set); */ + +# define CPU_SET_S(c,n,s) CPU_SET(c,s) + +/* void CPU_CLR_S(int cpu, size_t setsize, FAR cpu_set_t *set); */ + +# define CPU_CLR_S(c,n,s) CPU_CLR(c,s) + +/* int CPU_ISSET_S(int cpu, size_t setsize, FAR const cpu_set_t *set); */ + +# define CPU_ISSET_S(c,n,s) CPU_ISSET(c,s) + +/* int CPU_COUNT_S(size_t setsize, FAR const cpu_set_t *set); */ + +# define CPU_COUNT_S(n,s) CPU_COUNT(s) + +/* void CPU_AND_S(size_t setsize, FAR cpu_set_t *destset, + * FAR const cpu_set_t *srcset1, + * FAR const cpu_set_t *srcset2); + */ + +# define CPU_AND_S(n,d,s1,s2) CPU_AND(d,s1,s2) + +/* void CPU_OR_S(size_t setsize, FAR cpu_set_t *destset, + * FAR const cpu_set_t *srcset1, + * FAR const cpu_set_t *srcset2); + */ + +# define CPU_OR_S(n,d,s1,s2) CPU_OR(d,s1,s2) + +/* void CPU_XOR_S(size_t setsize, FAR cpu_set_t *destset, + * FAR const cpu_set_t *srcset1, + * FAR const cpu_set_t *srcset2); + */ + +# define CPU_XOR_S(n,d,s1,s2) CPU_XOR(d,s1,s2) + +/* int CPU_EQUAL_S(size_t setsize, FAR const cpu_set_t *set1, + * FAR const cpu_set_t *set2); + */ + +# define CPU_EQUAL_S(n,s1,s2) CPU_EQUAL(s1,s2) + +#endif /* CONFIG_SMP */ + /******************************************************************************** * Public Type Definitions ********************************************************************************/ @@ -137,7 +244,8 @@ int sched_rr_get_interval(pid_t pid, FAR struct timespec *interval); int sched_setaffinity(pid_t pid, size_t cpusetsize, FAR const cpu_set_t *mask); int sched_getaffinity(pid_t pid, size_t cpusetsize, FAR cpu_set_t *mask); -#endif +int sched_cpu_count(FAR const cpu_set_t *set); +#endif /* CONFIG_SMP */ /* Task Switching Interfaces (non-standard) */ diff --git a/libc/sched/Make.defs b/libc/sched/Make.defs index f1e69aff8ba..eeb4be1c1bb 100644 --- a/libc/sched/Make.defs +++ b/libc/sched/Make.defs @@ -37,6 +37,10 @@ CSRCS += sched_getprioritymax.c sched_getprioritymin.c +ifeq ($(CONFIG_SMP),y) +CSRCS += sched_cpucount.c +endif + ifeq ($(CONFIG_BUILD_PROTECTED),y) CSRCS += task_startup.c endif diff --git a/libc/sched/sched_cpucount.c b/libc/sched/sched_cpucount.c new file mode 100644 index 00000000000..3a2be5b3cb8 --- /dev/null +++ b/libc/sched/sched_cpucount.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * libc/sched/sched_cpucount.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sched_cpu_count + * + * Description: + * Return the number of bits set in the 'set'. This could be improved by + * using CPU-specific bit counting instructions. + * + * Inputs: + * set - The set of CPUs to be counted. + * + * Return Value: + * The number of CPUs in 'set' + * + ****************************************************************************/ + +int sched_cpu_count(FAR const cpu_set_t *set); +{ + int count; + int cpu; + + for (cpu = 0, count = 0; cpu < CONFIG_SMP_NCPUS; cpu++) + { + if ((*set & (1 << cpu)) != 0) + { + count++; + } + } + + return count; +} + +#endif /* CONFIG_SMP */