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,
|
||||
TLIST_ATTR_PRIORITIZED
|
||||
},
|
||||
#ifdef CONFIG_SMP
|
||||
{ /* TSTATE_TASK_READYTORUN */
|
||||
&g_readytorun,
|
||||
TLIST_ATTR_PRIORITIZED
|
||||
},
|
||||
#ifdef CONFIG_SMP
|
||||
{ /* TSTATE_TASK_ASSIGNED */
|
||||
g_assignedtasks,
|
||||
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_INDEXED
|
||||
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_INDEXED | TLIST_ATTR_RUNNABLE
|
||||
},
|
||||
{ /* TSTATE_TASK_RUNNING */
|
||||
g_assignedtasks,
|
||||
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_INDEXED
|
||||
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_INDEXED | TLIST_ATTR_RUNNABLE
|
||||
},
|
||||
#else
|
||||
{ /* TSTATE_TASK_READYTORUN */
|
||||
&g_readytorun,
|
||||
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_RUNNABLE
|
||||
},
|
||||
{ /* TSTATE_TASK_RUNNING */
|
||||
&g_readytorun,
|
||||
TLIST_ATTR_PRIORITIZED
|
||||
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_RUNNABLE
|
||||
},
|
||||
#endif
|
||||
{ /* TSTATE_TASK_INACTIVE */
|
||||
|
@ -82,10 +82,12 @@
|
||||
|
||||
#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_RUNNABLE (1 << 2) /* Bit 2: List includes running tasks */
|
||||
|
||||
#define __TLIST_ATTR(s) g_tasklisttable[s].attr
|
||||
#define TLIST_ISPRIORITIZED(s) ((__TLIST_ATTR(s) & TLIST_ATTR_PRIORITIZED) != 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_HEADINDEXED(s,c) (&(__TLIST_HEAD(s))[c])
|
||||
|
@ -76,11 +76,31 @@ bool sched_removereadytorun(FAR struct tcb_s *rtcb)
|
||||
FAR dq_queue_t *tasklist;
|
||||
bool ret = false;
|
||||
|
||||
/* Check if the TCB to be removed is at the head of the ready to run list.
|
||||
* In this case, we are removing the currently active task on this CPU.
|
||||
/* Check if the TCB to be removed is at the head of a ready to run list. */
|
||||
|
||||
#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)
|
||||
#endif
|
||||
{
|
||||
/* There must always be at least one task in the list (the idle task) */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user