OS: Add a RUNNABLE attribute to the tasklists to indicate if the task list includes the currently executing task. Use this additional bit of information to determine if a context switch could really occur when removing a TCB from a task list
This commit is contained in:
parent
76e88c8963
commit
7d7f4e140c
2
arch
2
arch
@ -1 +1 @@
|
|||||||
Subproject commit 717113268b97f16d755a11609a63526dfe71e4cf
|
Subproject commit a6ad88a85c9e4c6ab633fb53f53603539206a57c
|
2
configs
2
configs
@ -1 +1 @@
|
|||||||
Subproject commit 600d77e8b4631a67a6099b35a6959b6099b4a42b
|
Subproject commit f9d09bf8c091cc2d8578ae572ad8f48bb93d062a
|
@ -230,23 +230,27 @@ const struct tasklist_s g_tasklisttable[NUM_TASK_STATES] =
|
|||||||
&g_pendingtasks,
|
&g_pendingtasks,
|
||||||
TLIST_ATTR_PRIORITIZED
|
TLIST_ATTR_PRIORITIZED
|
||||||
},
|
},
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
{ /* TSTATE_TASK_READYTORUN */
|
{ /* TSTATE_TASK_READYTORUN */
|
||||||
&g_readytorun,
|
&g_readytorun,
|
||||||
TLIST_ATTR_PRIORITIZED
|
TLIST_ATTR_PRIORITIZED
|
||||||
},
|
},
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
{ /* TSTATE_TASK_ASSIGNED */
|
{ /* TSTATE_TASK_ASSIGNED */
|
||||||
g_assignedtasks,
|
g_assignedtasks,
|
||||||
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_INDEXED
|
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_INDEXED | TLIST_ATTR_RUNNABLE
|
||||||
},
|
},
|
||||||
{ /* TSTATE_TASK_RUNNING */
|
{ /* TSTATE_TASK_RUNNING */
|
||||||
g_assignedtasks,
|
g_assignedtasks,
|
||||||
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_INDEXED
|
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_INDEXED | TLIST_ATTR_RUNNABLE
|
||||||
},
|
},
|
||||||
#else
|
#else
|
||||||
|
{ /* TSTATE_TASK_READYTORUN */
|
||||||
|
&g_readytorun,
|
||||||
|
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_RUNNABLE
|
||||||
|
},
|
||||||
{ /* TSTATE_TASK_RUNNING */
|
{ /* TSTATE_TASK_RUNNING */
|
||||||
&g_readytorun,
|
&g_readytorun,
|
||||||
TLIST_ATTR_PRIORITIZED
|
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_RUNNABLE
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
{ /* TSTATE_TASK_INACTIVE */
|
{ /* TSTATE_TASK_INACTIVE */
|
||||||
|
@ -82,10 +82,12 @@
|
|||||||
|
|
||||||
#define TLIST_ATTR_PRIORITIZED (1 << 0) /* Bit 0: List is prioritized */
|
#define TLIST_ATTR_PRIORITIZED (1 << 0) /* Bit 0: List is prioritized */
|
||||||
#define TLIST_ATTR_INDEXED (1 << 1) /* Bit 1: List is indexed by CPU */
|
#define TLIST_ATTR_INDEXED (1 << 1) /* Bit 1: List is indexed by CPU */
|
||||||
|
#define TLIST_ATTR_RUNNABLE (1 << 2) /* Bit 2: List includes running tasks */
|
||||||
|
|
||||||
#define __TLIST_ATTR(s) g_tasklisttable[s].attr
|
#define __TLIST_ATTR(s) g_tasklisttable[s].attr
|
||||||
#define TLIST_ISPRIORITIZED(s) ((__TLIST_ATTR(s) & TLIST_ATTR_PRIORITIZED) != 0)
|
#define TLIST_ISPRIORITIZED(s) ((__TLIST_ATTR(s) & TLIST_ATTR_PRIORITIZED) != 0)
|
||||||
#define TLIST_ISINDEXED(s) ((__TLIST_ATTR(s) & TLIST_ATTR_INDEXED) != 0)
|
#define TLIST_ISINDEXED(s) ((__TLIST_ATTR(s) & TLIST_ATTR_INDEXED) != 0)
|
||||||
|
#define TLIST_ISRUNNABLE(s) ((__TLIST_ATTR(s) & TLIST_ATTR_RUNNABLE) != 0)
|
||||||
|
|
||||||
#define __TLIST_HEAD(s) (FAR dq_queue_t *)g_tasklisttable[s].list
|
#define __TLIST_HEAD(s) (FAR dq_queue_t *)g_tasklisttable[s].list
|
||||||
#define __TLIST_HEADINDEXED(s,c) (&(__TLIST_HEAD(s))[c])
|
#define __TLIST_HEADINDEXED(s,c) (&(__TLIST_HEAD(s))[c])
|
||||||
|
@ -76,11 +76,31 @@ bool sched_removereadytorun(FAR struct tcb_s *rtcb)
|
|||||||
FAR dq_queue_t *tasklist;
|
FAR dq_queue_t *tasklist;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
/* Check if the TCB to be removed is at the head of the ready to run list.
|
/* Check if the TCB to be removed is at the head of a ready to run list. */
|
||||||
* In this case, we are removing the currently active task on this CPU.
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
/* For the case of SMP, there are two lists involved: (1) the
|
||||||
|
* g_readytorun list that holds non-running tasks that have not been
|
||||||
|
* assigned to a CPU, and (2) and the g_assignedtasks[] lists which hold
|
||||||
|
* tasks assigned a CPU, including the task that is currently running on
|
||||||
|
* that CPU. Only this latter list contains the currently active task
|
||||||
|
* only only removing the head of that list can result in a context
|
||||||
|
* switch.
|
||||||
|
*
|
||||||
|
* The tasklist RUNNABLE attribute will inform us if the list holds the
|
||||||
|
* currently executing and task and, hence, if a context switch could
|
||||||
|
* occur.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!rtcb->blink || TLIST_ISRUNNABLE(rtcb->task_state))
|
||||||
|
#else
|
||||||
|
/* There is only one list, g_readytorun, and it always contains the
|
||||||
|
* currently running task. If we are removing the head of this list,
|
||||||
|
* then we are removing the currently active task.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!rtcb->blink)
|
if (!rtcb->blink)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* There must always be at least one task in the list (the idle task) */
|
/* There must always be at least one task in the list (the idle task) */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user