diff --git a/ChangeLog b/ChangeLog index b0bb7c11e1..b882a7c254 100755 --- a/ChangeLog +++ b/ChangeLog @@ -11505,3 +11505,11 @@ pthread_attr_setaffinity_np(), pthread_attr_getaffinity_np(), pthread_setaffinity_np(), and pthread_getaffinity_np(). No implementation is yet in place (2016-02-19). + * sched/sched_cpuselect.c, include/nuttx/sched.h, and other files. Add + a CPU affinity set to the TCB if SMP is enabled and use this CPU set as + a mask for determining which CPUs the thread may run on (2016-02-19). + * libc/pthread, sched/pthread/pthread_start.c, and include/pthread.h: + Add an affinity field to the attrributes to permit controlling + which CPUs a pthread may run on. Implements pthread_att_setaffinity_np() + and pthread_attr_getaffinity_np() (2016-02-19). + diff --git a/include/nuttx/pthread.h b/include/nuttx/pthread.h index eff079be74..54d5dc659b 100644 --- a/include/nuttx/pthread.h +++ b/include/nuttx/pthread.h @@ -57,7 +57,24 @@ # define PTHREAD_DEFAULT_POLICY SCHED_RR #endif -#ifdef CONFIG_SCHED_SPORADIC +/* A lot of hassle to use the old-fashioned struct initializers. But this + * gives us backward compatibility with some very old compilers. + */ + +#if defined(CONFIG_SCHED_SPORADIC) && defined(CONFIG_SMP) +# define PTHREAD_ATTR_INITIALIZER \ + { \ + PTHREAD_DEFAULT_PRIORITY, /* priority */ \ + PTHREAD_DEFAULT_POLICY, /* policy */ \ + PTHREAD_EXPLICIT_SCHED, /* inheritsched */ \ + 0, /* low_priority */ \ + 0, /* max_repl */ \ + 0, /* affinity */ \ + PTHREAD_STACK_DEFAULT, /* stacksize */ \ + {0, 0}, /* repl_period */ \ + {0, 0} /* budget */ \ + } +#elif defined(CONFIG_SCHED_SPORADIC) # define PTHREAD_ATTR_INITIALIZER \ { \ PTHREAD_DEFAULT_PRIORITY, /* priority */ \ @@ -69,6 +86,15 @@ {0, 0}, /* repl_period */ \ {0, 0}, /* budget */ \ } +#elif defined(CONFIG_SMP) +# define PTHREAD_ATTR_INITIALIZER \ + { \ + PTHREAD_DEFAULT_PRIORITY, /* priority */ \ + PTHREAD_DEFAULT_POLICY, /* policy */ \ + PTHREAD_EXPLICIT_SCHED, /* inheritsched */ \ + 0, /* affinity */ \ + PTHREAD_STACK_DEFAULT, /* stacksize */ \ + } #else # define PTHREAD_ATTR_INITIALIZER \ { \ diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 65722e23b0..b4f3d055fa 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -148,7 +148,7 @@ # define TCB_FLAG_SCHED_RR (1 << TCB_FLAG_POLICY_SHIFT) /* Round robin scheding policy */ # define TCB_FLAG_SCHED_SPORADIC (2 << TCB_FLAG_POLICY_SHIFT) /* Sporadic scheding policy */ # define TCB_FLAG_SCHED_OTHER (3 << TCB_FLAG_POLICY_SHIFT) /* Other scheding policy */ -#define TCB_FLAG_CPU_ASSIGNED (1 << 6) /* Bit 6: Assigned to a CPU */ +#define TCB_FLAG_CPU_LOCKED (1 << 6) /* Bit 6: Locked to this CPU */ #define TCB_FLAG_EXIT_PROCESSING (1 << 7) /* Bit 7: Exitting */ /* Bits 8-15: Available */ @@ -562,6 +562,7 @@ struct tcb_s uint8_t task_state; /* Current state of the thread */ #ifdef CONFIG_SMP uint8_t cpu; /* CPU index if running or assigned */ + cpu_set_t affinity; /* Bit set of permitted CPUs */ #endif uint16_t flags; /* Misc. general status flags */ int16_t lockcount; /* 0=preemptable (not-locked) */ diff --git a/include/pthread.h b/include/pthread.h index a949cf41f4..438ec2805f 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -178,6 +178,10 @@ struct pthread_attr_s uint8_t max_repl; /* Maximum pending replenishments */ #endif +#ifdef CONFIG_SMP + cpu_set_t affinity; /* Set of permitted CPUs for the thread */ +#endif + size_t stacksize; /* Size of the stack allocated for the pthread */ #ifdef CONFIG_SCHED_SPORADIC diff --git a/libc/pthread/Make.defs b/libc/pthread/Make.defs index a443a69969..8070197dd0 100644 --- a/libc/pthread/Make.defs +++ b/libc/pthread/Make.defs @@ -46,6 +46,11 @@ CSRCS += pthread_attrinit.c pthread_attrdestroy.c \ pthread_mutexattrinit.c pthread_mutexattrdestroy.c \ pthread_mutexattrgetpshared.c pthread_mutexattrsetpshared.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) CSRCS += pthread_mutexattrsettype.c pthread_mutexattrgettype.c endif diff --git a/libc/pthread/pthread_attrdestroy.c b/libc/pthread/pthread_attrdestroy.c index 22a7d8e894..04223f0e04 100644 --- a/libc/pthread/pthread_attrdestroy.c +++ b/libc/pthread/pthread_attrdestroy.c @@ -44,26 +44,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_attrgetinheritsched.c b/libc/pthread/pthread_attrgetinheritsched.c index 5fad0456c2..c4c2838dae 100644 --- a/libc/pthread/pthread_attrgetinheritsched.c +++ b/libc/pthread/pthread_attrgetinheritsched.c @@ -44,26 +44,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_attrgetschedpolicy.c b/libc/pthread/pthread_attrgetschedpolicy.c index ff67f5ad96..52a48a9504 100644 --- a/libc/pthread/pthread_attrgetschedpolicy.c +++ b/libc/pthread/pthread_attrgetschedpolicy.c @@ -43,26 +43,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_attrgetstacksize.c b/libc/pthread/pthread_attrgetstacksize.c index fc65f3d65f..ea95ec7328 100644 --- a/libc/pthread/pthread_attrgetstacksize.c +++ b/libc/pthread/pthread_attrgetstacksize.c @@ -43,26 +43,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_attrinit.c b/libc/pthread/pthread_attrinit.c index e40dfa81f4..e073fcd89f 100644 --- a/libc/pthread/pthread_attrinit.c +++ b/libc/pthread/pthread_attrinit.c @@ -46,14 +46,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - /**************************************************************************** * Public Data ****************************************************************************/ @@ -69,14 +61,6 @@ const pthread_attr_t g_default_pthread_attr = PTHREAD_ATTR_INITIALIZER; #endif -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_attrsetinheritsched.c b/libc/pthread/pthread_attrsetinheritsched.c index 34d8ce277d..07506773ad 100644 --- a/libc/pthread/pthread_attrsetinheritsched.c +++ b/libc/pthread/pthread_attrsetinheritsched.c @@ -45,26 +45,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_attrsetstacksize.c b/libc/pthread/pthread_attrsetstacksize.c index 96379dd0e6..97769acd25 100644 --- a/libc/pthread/pthread_attrsetstacksize.c +++ b/libc/pthread/pthread_attrsetstacksize.c @@ -44,26 +44,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_barrierattrdestroy.c b/libc/pthread/pthread_barrierattrdestroy.c index 55f735a1c2..98342e28c1 100644 --- a/libc/pthread/pthread_barrierattrdestroy.c +++ b/libc/pthread/pthread_barrierattrdestroy.c @@ -43,26 +43,6 @@ #include #include -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Public Data - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Function Prototypes - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/libc/pthread/pthread_barrierattrgetpshared.c b/libc/pthread/pthread_barrierattrgetpshared.c index d64423499e..ce186f230a 100644 --- a/libc/pthread/pthread_barrierattrgetpshared.c +++ b/libc/pthread/pthread_barrierattrgetpshared.c @@ -43,26 +43,6 @@ #include #include -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Public Data - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Function Prototypes - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/libc/pthread/pthread_barrierattrinit.c b/libc/pthread/pthread_barrierattrinit.c index 2deb60ba56..16c31922d7 100644 --- a/libc/pthread/pthread_barrierattrinit.c +++ b/libc/pthread/pthread_barrierattrinit.c @@ -43,26 +43,6 @@ #include #include -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Public Data - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Function Prototypes - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/libc/pthread/pthread_mutexattrdestroy.c b/libc/pthread/pthread_mutexattrdestroy.c index c59478d880..60b50718c1 100644 --- a/libc/pthread/pthread_mutexattrdestroy.c +++ b/libc/pthread/pthread_mutexattrdestroy.c @@ -43,26 +43,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_mutexattrgetpshared.c b/libc/pthread/pthread_mutexattrgetpshared.c index 97f69b0d77..586a1b203e 100644 --- a/libc/pthread/pthread_mutexattrgetpshared.c +++ b/libc/pthread/pthread_mutexattrgetpshared.c @@ -43,26 +43,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_mutexattrgettype.c b/libc/pthread/pthread_mutexattrgettype.c index 240a157055..cc553c8350 100644 --- a/libc/pthread/pthread_mutexattrgettype.c +++ b/libc/pthread/pthread_mutexattrgettype.c @@ -43,26 +43,6 @@ #ifdef CONFIG_MUTEX_TYPES -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_mutexattrinit.c b/libc/pthread/pthread_mutexattrinit.c index 17dbd9e849..b12b8a2994 100644 --- a/libc/pthread/pthread_mutexattrinit.c +++ b/libc/pthread/pthread_mutexattrinit.c @@ -43,26 +43,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_mutexattrsetpshared.c b/libc/pthread/pthread_mutexattrsetpshared.c index 075820df52..82f20092bd 100644 --- a/libc/pthread/pthread_mutexattrsetpshared.c +++ b/libc/pthread/pthread_mutexattrsetpshared.c @@ -43,26 +43,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_mutexattrsettype.c b/libc/pthread/pthread_mutexattrsettype.c index b3f23f4da0..ef8b263686 100644 --- a/libc/pthread/pthread_mutexattrsettype.c +++ b/libc/pthread/pthread_mutexattrsettype.c @@ -43,26 +43,6 @@ #ifdef CONFIG_MUTEX_TYPES -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/init/os_start.c b/sched/init/os_start.c index b968bc8451..8858a58341 100644 --- a/sched/init/os_start.c +++ b/sched/init/os_start.c @@ -73,6 +73,16 @@ #endif #include "init/init.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_SMP +/* This set of all CPUs */ + +# define SCHED_ALL_CPUS ((1 << CONFIG_SMP_NCPUS) - 1) +#endif /* CONFIG_SMP */ + /**************************************************************************** * Public Data ****************************************************************************/ @@ -452,19 +462,31 @@ void os_start(void) } /* Set the task flags to indicate that this is a kernel thread and, if - * configured for SMP, that this task is assigned to the correct CPU. + * configured for SMP, that this task is locked to this CPU. */ #ifdef CONFIG_SMP - g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_CPU_ASSIGNED); + g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_CPU_LOCKED); g_idletcb[cpu].cmn.cpu = cpu; #else g_idletcb[cpu].cmn.flags = TCB_FLAG_TTYPE_KERNEL; #endif - /* Set the IDLE task name */ +#ifdef CONFIG_SMP + /* Set the affinity mask to allow the thread to run on all CPUs. No, + * this IDLE thread can only run on its assigned CPU. That is + * enforced by the TCB_FLAG_CPU_LOCKED which overrides the affinity + * mask. This is essential because all tasks inherit the affinity + * mask from their parent and, ultimately, the parent of all tasks is + * the IDLE task. + */ + + g_idletcb[cpu].cmn.affinity = SCHED_ALL_CPUS; +#endif #if CONFIG_TASK_NAME_SIZE > 0 + /* Set the IDLE task name */ + # ifdef CONFIG_SMP snprintf(g_idletcb[cpu].cmn.name, CONFIG_TASK_NAME_SIZE, "CPU%d IDLE", cpu); # else diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index 3354067c31..52275b8e8d 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_create.c * - * Copyright (C) 2007-2009, 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -404,6 +404,20 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, goto errout_with_join; } +#ifdef CONFIG_SMP + /* pthread_schedsetup() will set the affinity mask by inheriting the + * setting from the parent task. We need to override this setting + * with the value from the pthread attributes unless that value is + * zero: Zero is the default value and simply means to inherit the + * parent thread's affinity mask. + */ + + if ( attr->affinity != 0) + { + ptcb->cmn.affinity = attr->affinity; + } +#endif + /* Configure the TCB for a pthread receiving on parameter * passed by value */ diff --git a/sched/sched/sched.h b/sched/sched/sched.h index 32fe377532..504c949e8c 100644 --- a/sched/sched/sched.h +++ b/sched/sched/sched.h @@ -417,11 +417,11 @@ void sched_sporadic_lowpriority(FAR struct tcb_s *tcb); #endif #ifdef CONFIG_SMP -int sched_cpu_select(void); +int sched_cpu_select(cpu_set_t affinity); # define sched_islocked(tcb) spin_islocked(&g_cpu_schedlock) #else # define sched_islocked(tcb) ((tcb)->lockcount > 0) -# define sched_cpu_select (0) +# define sched_cpu_select(a) (0) #endif diff --git a/sched/sched/sched_addreadytorun.c b/sched/sched/sched_addreadytorun.c index 82b567856d..40017bb47b 100644 --- a/sched/sched/sched_addreadytorun.c +++ b/sched/sched/sched_addreadytorun.c @@ -176,9 +176,9 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb) bool switched; bool doswitch; - /* Check if the blocked TCB is already assigned to a CPU */ + /* Check if the blocked TCB is locked to this CPU */ - if ((btcb->flags & TCB_FLAG_CPU_ASSIGNED) != 0) + if ((btcb->flags & TCB_FLAG_CPU_LOCKED) != 0) { /* Yes.. that that is the CPU we must use */ @@ -190,7 +190,7 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb) * (possibly its IDLE task). */ - cpu = sched_cpu_select(); + cpu = sched_cpu_select(btcb->affinity); } /* Get the task currently running on the CPU (maybe the IDLE task) */ @@ -207,11 +207,11 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb) task_state = TSTATE_TASK_RUNNING; } - /* If it will not be running, but is assigned to a CPU, then it will be in - * the asssigned state. + /* If it will not be running, but is locked to a CPU, then it will be in + * the assigned state. */ - else if ((btcb->flags & TCB_FLAG_CPU_ASSIGNED) != 0) + else if ((btcb->flags & TCB_FLAG_CPU_LOCKED) != 0) { task_state = TSTATE_TASK_ASSIGNED; cpu = btcb->cpu; @@ -328,7 +328,7 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb) &g_cpu_irqlock); } - /* If the following task is not assigned to this CPU, then it must + /* If the following task is not locked to this CPU, then it must * be moved to the g_readytorun list. Since it cannot be at the * head of the list, we can do this without invoking any heavy * lifting machinery. @@ -337,7 +337,7 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb) DEBUGASSERT(btcb->flink != NULL); next = (FAR struct tcb_s *)btcb->flink; - if ((next->flags & TCB_FLAG_CPU_ASSIGNED) != 0) + if ((next->flags & TCB_FLAG_CPU_LOCKED) != 0) { DEBUGASSERT(next->cpu == cpu); next->task_state = TSTATE_TASK_ASSIGNED; diff --git a/sched/sched/sched_cpuselect.c b/sched/sched/sched_cpuselect.c index 7bebc89424..efd5c8417b 100644 --- a/sched/sched/sched_cpuselect.c +++ b/sched/sched/sched_cpuselect.c @@ -48,6 +48,12 @@ #ifdef CONFIG_SMP +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IMPOSSIBLE_CPU 0xff + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -60,7 +66,7 @@ * possbily its IDLE task. * * Inputs: - * None + * affinity - The set of CPUs on which the thread is permitted to run. * * Return Value: * Index of the CPU with the lowest priority running task @@ -70,7 +76,7 @@ * ****************************************************************************/ -int sched_cpu_select(void) +int sched_cpu_select(cpu_set_t affinity) { uint8_t minprio; int cpu; @@ -81,32 +87,38 @@ int sched_cpu_select(void) */ minprio = SCHED_PRIORITY_MAX; - cpu = 0; + cpu = IMPOSSIBLE_CPU; for (i = 0; i < CONFIG_SMP_NCPUS; i++) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_assignedtasks[i].head; + /* If the thread permitted to run on this CPU? */ - /* If this thread is executing its IDLE task, the use it. The IDLE - * task is always the last task in the assigned task list. - */ - - if (rtcb->flink == NULL) + if ((affinity & (1 << i)) != 0) { - /* The IDLE task should always be assigned to this CPU and have - * a priority of zero. + FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_assignedtasks[i].head; + + /* If this thread is executing its IDLE task, the use it. The + * IDLE task is always the last task in the assigned task list. */ - DEBUGASSERT(rtcb->sched_priority == 0); - return i; - } - else if (rtcb->sched_priority < minprio) - { - DEBUGASSERT(rtcb->sched_priority > 0); - cpu = i; + if (rtcb->flink == NULL) + { + /* The IDLE task should always be assigned to this CPU and have + * a priority of zero. + */ + + DEBUGASSERT(rtcb->sched_priority == 0); + return i; + } + else if (rtcb->sched_priority < minprio) + { + DEBUGASSERT(rtcb->sched_priority > 0); + cpu = i; + } } } + DEBUGASSERT(cpu != IMPOSSIBLE_CPU); return cpu; } diff --git a/sched/sched/sched_setpriority.c b/sched/sched/sched_setpriority.c index 2661edcf71..ba969eb13f 100644 --- a/sched/sched/sched_setpriority.c +++ b/sched/sched/sched_setpriority.c @@ -131,7 +131,7 @@ static void sched_readytorun_setpriority(FAR struct tcb_s *tcb, if (tcb->task_state == TSTATE_TASK_READYTORUN) { - cpu = sched_cpu_select(); + cpu = sched_cpu_select(tcb->affinity); } /* CASE 2b. The task is ready to run, and assigned to a CPU. An increase diff --git a/sched/task/task_setup.c b/sched/task/task_setup.c index ee87fd93a9..619a81819d 100644 --- a/sched/task/task_setup.c +++ b/sched/task/task_setup.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/task/task_setup.c * - * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -146,6 +146,38 @@ static int task_assignpid(FAR struct tcb_s *tcb) return ERROR; } +/**************************************************************************** + * Name: task_inherit_affinity + * + * Description: + * exec(), task_create(), and vfork() all inherit the affinity mask from + * the parent thread. This is the default for pthread_create() as well + * but the affinity mask can be specified in the pthread attributes as + * well. pthread_setup() will have to fix up the affinity mask in this + * case. + * + * Parameters: + * tcb - The TCB of the new task. + * + * Returned Value: + * None + * + * Assumptions: + * The parent of the new task is the task at the head of the ready-to-run + * list. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +static inline void task_inherit_affinity(FAR struct tcb_s *tcb) +{ + FAR struct tcb_s *rtcb = this_task(); + tcb->affinity = rtcb->affinity; +} +#else +# define task_inherit_affinity(tcb) +#endif + /**************************************************************************** * Name: task_saveparent * @@ -348,11 +380,22 @@ static int thread_schedsetup(FAR struct tcb_s *tcb, int priority, task_saveparent(tcb, ttype); +#ifdef CONFIG_SMP + /* exec(), task_create(), and vfork() all inherit the affinity mask + * from the parent thread. This is the default for pthread_create() + * as well but the affinity mask can be specified in the pthread + * attributes as well. pthread_create() will have to fix up the + * affinity mask in this case. + */ + + task_inherit_affinity(tcb); +#endif + +#ifndef CONFIG_DISABLE_SIGNALS /* exec(), pthread_create(), task_create(), and vfork() all * inherit the signal mask of the parent thread. */ -#ifndef CONFIG_DISABLE_SIGNALS (void)sigprocmask(SIG_SETMASK, NULL, &tcb->sigprocmask); #endif @@ -628,8 +671,8 @@ int task_schedsetup(FAR struct task_tcb_s *tcb, int priority, start_t start, ****************************************************************************/ #ifndef CONFIG_DISABLE_PTHREAD -int pthread_schedsetup(FAR struct pthread_tcb_s *tcb, int priority, start_t start, - pthread_startroutine_t entry) +int pthread_schedsetup(FAR struct pthread_tcb_s *tcb, int priority, + start_t start, pthread_startroutine_t entry) { /* Perform common thread setup */