diff --git a/ChangeLog b/ChangeLog index b2241a7590..ff70a64918 100755 --- a/ChangeLog +++ b/ChangeLog @@ -11514,4 +11514,5 @@ and pthread_attr_getaffinity_np() (2016-02-19). * sched/pthread: Add pthread_setaffinity() and pthread_getaffinity() (2016-02-19). + * sched/sched: Add sched_setaffinity() and sched_getaffinity() (2016-02-19). diff --git a/libc/pthread/Make.defs b/libc/pthread/Make.defs index 8070197dd0..44a2d8b2d6 100644 --- a/libc/pthread/Make.defs +++ b/libc/pthread/Make.defs @@ -48,7 +48,6 @@ CSRCS += pthread_attrinit.c pthread_attrdestroy.c \ ifeq ($(CONFIG_SMP),y) CSRCS += pthread_attrgetaffinity.c pthread_attrsetaffinity.c -# CSRCS += pthread_getaffinity.c pthread_setaffinity.c endif ifeq ($(CONFIG_MUTEX_TYPES),y) diff --git a/sched/sched/Make.defs b/sched/sched/Make.defs index 3c521a25d7..aa806b95aa 100644 --- a/sched/sched/Make.defs +++ b/sched/sched/Make.defs @@ -48,7 +48,7 @@ CSRCS += sched_reprioritize.c endif ifeq ($(CONFIG_SMP),y) -CSRCS += sched_cpuselect.c +CSRCS += sched_getaffinity.c sched_setaffinity.c sched_cpuselect.c endif ifeq ($(CONFIG_SCHED_WAITPID),y) diff --git a/sched/sched/sched_getaffinity.c b/sched/sched/sched_getaffinity.c new file mode 100644 index 0000000000..e7d355b50f --- /dev/null +++ b/sched/sched/sched_getaffinity.c @@ -0,0 +1,104 @@ +/**************************************************************************** + * sched/sched/sched_getaffinity.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 +#include +#include +#include + +#include "sched/sched.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sched_getscheduler + * + * Description: + * sched_getaffinity() writes the affinity mask of the thread whose ID + * is pid into the cpu_set_t pointed to by mask. The cpusetsize + * argument specifies the size (in bytes) of mask. If pid is zero, then + * the mask of the calling thread is returned. + * + * Inputs: + * pid - The ID of thread whose affinity set will be retrieved. + * cpusetsize - Size of cpuset. MUST be sizeofcpu_set_t(). + * cpuset - The location to return the thread's new affinity set. + * + * Return Value: + * 0 if successful. Otherwise, ERROR (-1) is returned, and errno is + * set appropriately: + * + * ESRCH The task whose ID is pid could not be found. + * + ****************************************************************************/ + +int sched_getaffinity(pid_t pid, size_t cpusetsize, FAR cpu_set_t *mask) +{ + FAR struct tcb_s *tcb; + + DEBUGASSERT(cpusetsize == sizeof(cpu_set_t) && mask != NULL); + + /* Verify that the PID corresponds to a real task */ + + sched_lock(); + if (!pid) + { + tcb = this_task(); + } + else + { + tcb = sched_gettcb(pid); + } + + if (tcb == NULL) + { + set_errno(ESRCH); + return ERROR; + } + + /* Return the affinity mask from the TCB. */ + + *mask = tcb->affinity; + sched_unlock(); + return OK; +} diff --git a/sched/sched/sched_getparam.c b/sched/sched/sched_getparam.c index 0ab047f984..155049ff1f 100644 --- a/sched/sched/sched_getparam.c +++ b/sched/sched/sched_getparam.c @@ -45,30 +45,6 @@ #include "clock/clock.h" #include "sched/sched.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/sched/sched_getscheduler.c b/sched/sched/sched_getscheduler.c index a1afddf28e..47ba73fa9c 100644 --- a/sched/sched/sched_getscheduler.c +++ b/sched/sched/sched_getscheduler.c @@ -47,30 +47,6 @@ #include "sched/sched.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/sched/sched_gettcb.c b/sched/sched/sched_gettcb.c index 83de9358c7..a5fc20c278 100644 --- a/sched/sched/sched_gettcb.c +++ b/sched/sched/sched_gettcb.c @@ -43,26 +43,6 @@ #include "sched/sched.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/sched/sched_setaffinity.c b/sched/sched/sched_setaffinity.c new file mode 100644 index 0000000000..c2d50af146 --- /dev/null +++ b/sched/sched/sched_setaffinity.c @@ -0,0 +1,163 @@ +/**************************************************************************** + * sched/sched/sched_setaffinity.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 +#include +#include +#include + +#include + +#include "sched/sched.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sched_getscheduler + * + * Description: + * sched_setaffinity() sets the CPU affinity mask of the thread whose ID + * is pid to the value specified by mask. If pid is zero, then the + * calling thread is used. The argument cpusetsize is the length (i + * bytes) of the data pointed to by mask. Normally this argument would + * be specified as sizeof(cpu_set_t). + * + * If the thread specified by pid is not currently running on one of the + * CPUs specified in mask, then that thread is migrated to one of the + * CPUs specified in mask. + * + * Inputs: + * pid - The ID of thread whose affinity set will be modified. + * cpusetsize - Size of cpuset. MUST be sizeofcpu_set_t(). + * cpuset - The location to return the thread's new affinity set. + * + * Return Value: + * 0 if successful. Otherwise, ERROR (-1) is returned, and errno is + * set appropriately: + * + * ESRCH The task whose ID is pid could not be found. + * + ****************************************************************************/ + +int sched_setaffinity(pid_t pid, size_t cpusetsize, FAR const cpu_set_t *mask) +{ + FAR struct tcb_s *tcb; + irqstate_t flags; + int errcode = 0; + int ret; + + DEBUGASSERT(cpusetsize == sizeof(cpu_set_t) && mask != NULL); + + /* Verify that the PID corresponds to a real task */ + + sched_lock(); + if (!pid) + { + tcb = this_task(); + } + else + { + tcb = sched_gettcb(pid); + } + + if (tcb == NULL) + { + errcode = ESRCH; + goto errout_with_lock; + } + + /* Don't permit changing the affinity mask of any task locked to a CPU + * (i.e., an IDLE task) + */ + + flags = enter_critical_section(); + if ((tcb->flags & TCB_FLAG_CPU_LOCKED) != 0) + { + errcode = EINVAL; + goto errout_with_csection; + } + + /* Set the new affinity mask. */ + + tcb->affinity = *mask; + + /* Is the task still executing a a CPU in its affinity mask? Will this + * change cause the task to be removed from its current assigned task + * list? + * + * First... is the task in an assigned task list? + */ + + if (tcb->task_state >= FIRST_ASSIGNED_STATE && + tcb->task_state <= LAST_ASSIGNED_STATE) + { + /* Yes... is the CPU associated with the assigned task in the new + * affinity mask? + */ + + if ((tcb->affinity & (1 << tcb->cpu)) == 0) + { + /* No.. then we will need to move the task from the the assigned + * task list to some other ready to run list. + * + * sched_setpriority() will do just what we want... it will remove + * the task from its current position in the some assigned task list + * and then simply put it back in the right place. This works even + * if the task is this task. + */ + + ret = sched_setpriority(tcb, tcb->sched_priority); + if (ret < 0) + { + errcode = get_errno(); + } + } + } + +errout_with_csection: + leave_critical_section(flags); +errout_with_lock: + sched_unlock(); + set_errno(errcode); + return ERROR; +} diff --git a/sched/sched/sched_verifytcb.c b/sched/sched/sched_verifytcb.c index 31ff091884..5958b28e0c 100644 --- a/sched/sched/sched_verifytcb.c +++ b/sched/sched/sched_verifytcb.c @@ -44,26 +44,6 @@ #include "sched/sched.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/sched/sched_wait.c b/sched/sched/sched_wait.c index 553ec529dd..d1547e07cf 100644 --- a/sched/sched/sched_wait.c +++ b/sched/sched/sched_wait.c @@ -49,10 +49,6 @@ #if defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT) -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/