nuttx/sched: remove nxsched_remove_readytorun from up_block_task
It takes about 10 cycles to obtain the task list according to the task status. In most cases, we know the task status, so we can directly add the task from the specified task list to reduce time consuming.
This commit is contained in:
parent
e54b602208
commit
08f7152d9f
52 changed files with 1126 additions and 1721 deletions
|
@ -186,21 +186,17 @@ APIs Exported by Architecture-Specific Logic to NuttX
|
|||
which will be executed.
|
||||
:param rtcb: Refers to the running task which will be blocked.
|
||||
|
||||
.. c:function:: void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state)
|
||||
.. c:function:: void up_block_task(FAR struct tcb_s *rtcb)
|
||||
|
||||
The currently executing task at the head of the
|
||||
ready to run list must be stopped. Save its context and move it to
|
||||
the inactive list specified by task_state. This function is called
|
||||
only from the NuttX scheduling logic. Interrupts will always be
|
||||
disabled when this function is called.
|
||||
The currently executing task has already removed from ready-to-run list.
|
||||
Save its context and switch to the next running task at the head of the
|
||||
ready-to-run list.
|
||||
|
||||
:param tcb: Refers to a task in the ready-to-run list (normally
|
||||
the task at the head of the list). It must be stopped, its
|
||||
context saved and moved into one of the waiting task lists. If
|
||||
it was the task at the head of the ready-to-run list, then a
|
||||
context switch to the new ready to run task must be performed.
|
||||
:param task_state: Specifies which waiting task list should be
|
||||
hold the blocked task TCB.
|
||||
This function is called only from the NuttX scheduling logic.
|
||||
Interrupts will always be disabled when this function is called.
|
||||
|
||||
:param rtcb: Reference to the running task which is different to the
|
||||
task (next running task) at the head of the list.
|
||||
|
||||
.. c:function:: void up_release_pending(void)
|
||||
|
||||
|
|
|
@ -44,108 +44,69 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
|
||||
arm_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
arm_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
if (switch_needed)
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
||||
arm_savestate(rtcb->xcp.regs);
|
||||
arm_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
arm_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
||||
arm_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* arm_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
/* arm_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -44,110 +44,69 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb;
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
rtcb = this_task();
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
|
||||
arm64_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
arm64_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
if (switch_needed)
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
||||
arm64_savestate(rtcb->xcp.regs);
|
||||
arm64_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
arm64_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
||||
arm64_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* arm_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
/* arm_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -43,106 +43,67 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (g_current_regs)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
if (switch_needed)
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
if (g_current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
||||
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* up_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
/* up_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -44,120 +44,81 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (g_current_regs)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any new address environment needed by
|
||||
* the new thread will be instantiated before the return from
|
||||
* interrupt.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
if (switch_needed)
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
/* Get the context of the task at the head of the ready to
|
||||
* run list.
|
||||
*/
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (g_current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any new address environment needed by
|
||||
* the new thread will be instantiated before the return from
|
||||
* interrupt.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
/* Get the context of the task at the head of the ready to
|
||||
* run list.
|
||||
*/
|
||||
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(nexttcb);
|
||||
group_addrenv(nexttcb);
|
||||
#endif
|
||||
/* Reset scheduler parameters */
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
/* Then switch contexts */
|
||||
|
||||
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* up_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
/* up_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -36,108 +36,67 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of
|
||||
* the ready to run list must be stopped. Save its context
|
||||
* and move it to the inactive list specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Inputs:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally
|
||||
* the task at the head of the list). It most be
|
||||
* stopped, its context saved and moved into one of the
|
||||
* waiting task lists. It it was the task at the head
|
||||
* of the ready-to-run list, then a context to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should be
|
||||
* hold the blocked task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
sched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we
|
||||
* are blocking the task at the head of the task list (the
|
||||
* most likely case), then a context switch to the next
|
||||
* ready-to-run task is needed. In this case, it should
|
||||
* also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = sched_removereadytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
sched_addblocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
switch_needed |= sched_mergepending();
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
|
||||
rtcb->xcp.regs = CURRENT_REGS;
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
sched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
CURRENT_REGS = rtcb->xcp.regs;
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
if (switch_needed)
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
sched_suspend_scheduler(rtcb);
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
sched_resume_scheduler(nexttcb);
|
||||
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
||||
rtcb->xcp.regs = CURRENT_REGS;
|
||||
up_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
sched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
CURRENT_REGS = rtcb->xcp.regs;
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
sched_resume_scheduler(nexttcb);
|
||||
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
||||
up_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* up_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
/* up_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,116 +44,77 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (g_current_regs)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (g_current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
rtcb = this_task();
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(rtcb);
|
||||
group_addrenv(rtcb);
|
||||
#endif
|
||||
/* Reset scheduler parameters */
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
/* Then switch contexts */
|
||||
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -45,110 +45,71 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
if (switch_needed)
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
/* Get the context of the task at the head of the ready to
|
||||
* run list.
|
||||
*/
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
/* Then switch contexts */
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
/* Get the context of the task at the head of the ready to
|
||||
* run list.
|
||||
*/
|
||||
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* up_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
/* up_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -45,110 +45,71 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (g_current_regs)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
if (switch_needed)
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
/* Get the context of the task at the head of the ready to
|
||||
* run list.
|
||||
*/
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
if (g_current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
/* Then switch contexts */
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
/* Get the context of the task at the head of the ready to
|
||||
* run list.
|
||||
*/
|
||||
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* up_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
/* up_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -45,110 +45,71 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t) task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run task
|
||||
* list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (g_current_regs)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
/* Yes, then we have to do things differently. Just copy the
|
||||
* g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head of
|
||||
* the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment changes
|
||||
* will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
if (switch_needed)
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
/* Get the context of the task at the head of the ready to run
|
||||
* list.
|
||||
*/
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
if (g_current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently. Just copy the
|
||||
* g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
/* Then switch contexts */
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head of
|
||||
* the ready-to-run task list.
|
||||
*/
|
||||
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment changes
|
||||
* will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
/* Get the context of the task at the head of the ready to run
|
||||
* list.
|
||||
*/
|
||||
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* up_switchcontext forces a context switch to the task at the head
|
||||
* of the ready-to-run list. It does not 'return' in the normal
|
||||
* sense. When it does return, it is because the blocked task is
|
||||
* again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
/* up_switchcontext forces a context switch to the task at the head
|
||||
* of the ready-to-run list. It does not 'return' in the normal
|
||||
* sense. When it does return, it is because the blocked task is
|
||||
* again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -44,116 +44,77 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
rtcb = this_task();
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(rtcb);
|
||||
group_addrenv(rtcb);
|
||||
#endif
|
||||
/* Reset scheduler parameters */
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
/* Then switch contexts */
|
||||
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -43,117 +43,78 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (g_current_regs)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (g_current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
g_current_regs = rtcb->xcp.regs;
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task
|
||||
* restarting!
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
rtcb = this_task();
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
g_current_regs = rtcb->xcp.regs;
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task
|
||||
* restarting!
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(rtcb);
|
||||
group_addrenv(rtcb);
|
||||
#endif
|
||||
/* Reset scheduler parameters */
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
/* Then switch contexts */
|
||||
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -45,110 +45,71 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
|
||||
riscv_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
riscv_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
if (switch_needed)
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
/* Get the context of the task at the head of the ready to
|
||||
* run list.
|
||||
*/
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
riscv_savestate(rtcb->xcp.regs);
|
||||
/* Then switch contexts */
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
riscv_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
riscv_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
/* Get the context of the task at the head of the ready to
|
||||
* run list.
|
||||
*/
|
||||
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
riscv_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* riscv_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
/* riscv_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -43,103 +43,62 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* TODO */
|
||||
|
||||
/* sinfo("Blocking TCB=%p\n", tcb); */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* Copy the exception context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if setjmp returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
*/
|
||||
|
||||
if (switch_needed)
|
||||
else if (!setjmp(rtcb->xcp.regs))
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* TODO */
|
||||
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
/* Copy the exception context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if setjmp returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
else if (!setjmp(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
rtcb = this_task();
|
||||
sinfo("New Active Task TCB=%p\n", rtcb);
|
||||
|
||||
rtcb = this_task();
|
||||
sinfo("New Active Task TCB=%p\n", rtcb);
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
/* Restore the cpu lock */
|
||||
|
||||
/* Restore the cpu lock */
|
||||
restore_critical_section();
|
||||
|
||||
restore_critical_section();
|
||||
/* Then switch contexts */
|
||||
|
||||
/* Then switch contexts */
|
||||
longjmp(rtcb->xcp.regs, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The way that we handle signals in the simulation is kind of
|
||||
* a kludge. This would be unsafe in a truly multi-threaded,
|
||||
* interrupt driven environment.
|
||||
*/
|
||||
|
||||
longjmp(rtcb->xcp.regs, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The way that we handle signals in the simulation is kind of
|
||||
* a kludge. This would be unsafe in a truly multi-threaded,
|
||||
* interrupt driven environment.
|
||||
*/
|
||||
|
||||
sim_sigdeliver();
|
||||
}
|
||||
sim_sigdeliver();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -45,112 +45,71 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of
|
||||
* the ready to run list must be stopped. Save its context
|
||||
* and move it to the inactive list specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally
|
||||
* the task at the head of the list). It most be
|
||||
* stopped, its context saved and moved into one of the
|
||||
* waiting task lists. It it was the task at the head
|
||||
* of the ready-to-run list, then a context to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should be
|
||||
* hold the blocked task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we
|
||||
* are blocking the task at the head of the task list (the
|
||||
* most likely case), then a context switch to the next
|
||||
* ready-to-run task is needed. In this case, it should
|
||||
* also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
if (switch_needed)
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
/* Get the context of the task at the head of the ready to
|
||||
* run list.
|
||||
*/
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
/* Then switch contexts */
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
/* Get the context of the task at the head of the ready to
|
||||
* run list.
|
||||
*/
|
||||
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* up_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
/* up_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -44,117 +44,78 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (g_current_regs)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (g_current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task
|
||||
* restarting!
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new)
|
||||
* head of the ready-to-run task list.
|
||||
*/
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
rtcb = this_task();
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task
|
||||
* restarting!
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new)
|
||||
* head of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(rtcb);
|
||||
group_addrenv(rtcb);
|
||||
#endif
|
||||
/* Reset scheduler parameters */
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
/* Then switch contexts */
|
||||
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -44,118 +44,79 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (g_current_regs)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (g_current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
up_restore_auxstate(rtcb);
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
rtcb = this_task();
|
||||
up_restore_auxstate(rtcb);
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
up_restore_auxstate(rtcb);
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
up_restore_auxstate(rtcb);
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(rtcb);
|
||||
group_addrenv(rtcb);
|
||||
#endif
|
||||
/* Reset scheduler parameters */
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
/* Then switch contexts */
|
||||
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -45,108 +45,69 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(struct tcb_s *rtcb)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
|
||||
xtensa_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
xtensa_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
if (switch_needed)
|
||||
else
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
if (CURRENT_REGS)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the CURRENT_REGS into the OLD rtcb.
|
||||
*/
|
||||
/* Then switch contexts */
|
||||
|
||||
xtensa_savestate(rtcb->xcp.regs);
|
||||
xtensa_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
xtensa_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
{
|
||||
struct tcb_s *nexttcb = this_task();
|
||||
|
||||
/* Switch context to the context of the task at the head of the
|
||||
* ready to run list.
|
||||
*/
|
||||
|
||||
nxsched_resume_scheduler(nexttcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
xtensa_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* xtensa_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
/* xtensa_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -43,109 +43,68 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(FAR struct tcb_s *rtcb)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* sinfo("Blocking TCB=%p\n", tcb); */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (IN_INTERRUPT)
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (IN_INTERRUPT)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the current registers into the OLD rtcb.
|
||||
*/
|
||||
|
||||
SAVE_IRQCONTEXT(rtcb);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then setup so that the context will be performed on exit
|
||||
* from the interrupt.
|
||||
*/
|
||||
|
||||
SET_IRQCONTEXT(rtcb);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if SAVE_USERCONTEXT returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the current registers into the OLD rtcb.
|
||||
*/
|
||||
|
||||
else if (!SAVE_USERCONTEXT(rtcb))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
SAVE_IRQCONTEXT(rtcb);
|
||||
|
||||
rtcb = this_task();
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
rtcb = this_task();
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
/* Then switch contexts */
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
RESTORE_USERCONTEXT(rtcb);
|
||||
}
|
||||
/* Then setup so that the context will be performed on exit
|
||||
* from the interrupt.
|
||||
*/
|
||||
|
||||
SET_IRQCONTEXT(rtcb);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if SAVE_USERCONTEXT returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
*/
|
||||
|
||||
else if (!SAVE_USERCONTEXT(rtcb))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
RESTORE_USERCONTEXT(rtcb);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ void up_reprioritize_rtr(FAR struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -45,119 +45,78 @@
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should hold the blocked
|
||||
* task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state)
|
||||
void up_block_task(FAR struct tcb_s *rtcb)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
bool switch_needed;
|
||||
/* Update scheduler parameters */
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
/* _info("Blocking TCB=%p\n", tcb); */
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we are blocking the
|
||||
* task at the head of the task list (the most likely case), then a
|
||||
* context switch to the next ready-to-run task is needed. In this case,
|
||||
* it should also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
nxsched_add_blocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
if (IN_INTERRUPT())
|
||||
{
|
||||
switch_needed |= nxsched_merge_pending();
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
nxsched_suspend_scheduler(rtcb);
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (IN_INTERRUPT())
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the current registers into the OLD rtcb.
|
||||
*/
|
||||
|
||||
SAVE_IRQCONTEXT(rtcb);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then setup so that the context will be performed on exit
|
||||
* from the interrupt. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
SET_IRQCONTEXT(rtcb);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if SAVE_USERCONTEXT returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the current registers into the OLD rtcb.
|
||||
*/
|
||||
|
||||
else if (!SAVE_USERCONTEXT(rtcb))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
SAVE_IRQCONTEXT(rtcb);
|
||||
|
||||
rtcb = this_task();
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then setup so that the context will be performed on exit
|
||||
* from the interrupt. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
SET_IRQCONTEXT(rtcb);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* ready-to-run Task list. if SAVE_USERCONTEXT returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
*/
|
||||
|
||||
else if (!SAVE_USERCONTEXT(rtcb))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
* thread at the head of the ready-to-run list.
|
||||
*/
|
||||
|
||||
group_addrenv(rtcb);
|
||||
group_addrenv(rtcb);
|
||||
#endif
|
||||
/* Reset scheduler parameters */
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
nxsched_resume_scheduler(rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
/* Then switch contexts */
|
||||
|
||||
RESTORE_USERCONTEXT(rtcb);
|
||||
}
|
||||
RESTORE_USERCONTEXT(rtcb);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ void up_reprioritize_rtr(FAR struct tcb_s *tcb, uint8_t priority)
|
|||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb);
|
||||
switch_needed = nxsched_remove_readytorun(tcb, false);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
|
|
|
@ -407,25 +407,20 @@ void up_unblock_task(FAR struct tcb_s *tcb, FAR struct tcb_s *rtcb);
|
|||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of the ready to run list must
|
||||
* be stopped. Save its context and move it to the inactive list
|
||||
* specified by task_state.
|
||||
* The currently executing task has already removed from ready-to-run list.
|
||||
* Save its context and switch to the next running task at the head of the
|
||||
* ready-to-run list.
|
||||
*
|
||||
* This function is called only from the NuttX scheduling logic.
|
||||
* Interrupts will always be disabled when this function is called.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally the task at
|
||||
* the head of the list). It must be stopped, its context saved and
|
||||
* moved into one of the waiting task lists. If it was the task at the
|
||||
* head of the ready-to-run list, then a context switch to the new ready
|
||||
* to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should be
|
||||
* hold the blocked task TCB.
|
||||
* rtcb: Reference to the running task which is different to the
|
||||
* task (next running task) at the head of the list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state);
|
||||
void up_block_task(FAR struct tcb_s *rtcb);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_release_pending
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
@ -135,6 +136,7 @@ int nxmq_wait_receive(FAR struct mqueue_inode_s *msgq,
|
|||
{
|
||||
FAR struct mqueue_msg_s *newmsg;
|
||||
FAR struct tcb_s *rtcb;
|
||||
bool switch_needed;
|
||||
|
||||
DEBUGASSERT(rcvmsg != NULL);
|
||||
|
||||
|
@ -181,7 +183,22 @@ int nxmq_wait_receive(FAR struct mqueue_inode_s *msgq,
|
|||
*/
|
||||
|
||||
DEBUGASSERT(!is_idle_task(rtcb));
|
||||
up_block_task(rtcb, TSTATE_WAIT_MQNOTEMPTY);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. */
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(rtcb, true);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
rtcb->task_state = TSTATE_WAIT_MQNOTEMPTY;
|
||||
nxsched_add_prioritized(rtcb, MQ_WNELIST(msgq->cmn));
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
up_block_task(rtcb);
|
||||
}
|
||||
|
||||
/* When we resume at this point, either (1) the message queue
|
||||
* is no longer empty, or (2) the wait has been interrupted by
|
||||
|
|
|
@ -213,6 +213,7 @@ FAR struct mqueue_msg_s *nxmq_alloc_msg(void)
|
|||
int nxmq_wait_send(FAR struct mqueue_inode_s *msgq, int oflags)
|
||||
{
|
||||
FAR struct tcb_s *rtcb;
|
||||
bool switch_needed;
|
||||
|
||||
#ifdef CONFIG_CANCELLATION_POINTS
|
||||
/* nxmq_wait_send() is not a cancellation point, but may be called via
|
||||
|
@ -267,7 +268,22 @@ int nxmq_wait_send(FAR struct mqueue_inode_s *msgq, int oflags)
|
|||
*/
|
||||
|
||||
DEBUGASSERT(!is_idle_task(rtcb));
|
||||
up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. */
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(rtcb, true);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
rtcb->task_state = TSTATE_WAIT_MQNOTFULL;
|
||||
nxsched_add_prioritized(rtcb, MQ_WNFLIST(msgq->cmn));
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
up_block_task(rtcb);
|
||||
}
|
||||
|
||||
/* When we resume at this point, either (1) the message queue
|
||||
* is no longer empty, or (2) the wait has been interrupted by
|
||||
|
|
|
@ -43,6 +43,7 @@ static int msgrcv_wait(FAR struct msgq_s *msgq, FAR struct msgbuf_s **rcvmsg,
|
|||
FAR struct msgbuf_s *newmsg = NULL;
|
||||
FAR struct msgbuf_s *tmp;
|
||||
FAR struct tcb_s *rtcb;
|
||||
bool switch_needed;
|
||||
|
||||
#ifdef CONFIG_CANCELLATION_POINTS
|
||||
/* msgrcv_wait() is not a cancellation point, but it may be called
|
||||
|
@ -125,7 +126,22 @@ static int msgrcv_wait(FAR struct msgq_s *msgq, FAR struct msgbuf_s **rcvmsg,
|
|||
*/
|
||||
|
||||
DEBUGASSERT(NULL != rtcb->flink);
|
||||
up_block_task(rtcb, TSTATE_WAIT_MQNOTEMPTY);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. */
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(rtcb, true);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
rtcb->task_state = TSTATE_WAIT_MQNOTEMPTY;
|
||||
nxsched_add_prioritized(rtcb, MQ_WNELIST(msgq->cmn));
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
up_block_task(rtcb);
|
||||
}
|
||||
|
||||
/* When we resume at this point, either (1) the message queue
|
||||
* is no longer empty, or (2) the wait has been interrupted by
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
static int msgsnd_wait(FAR struct msgq_s *msgq, int msgflg)
|
||||
{
|
||||
FAR struct tcb_s *rtcb;
|
||||
bool switch_needed;
|
||||
|
||||
#ifdef CONFIG_CANCELLATION_POINTS
|
||||
/* msgsnd_wait() is not a cancellation point, but may be called via
|
||||
|
@ -91,7 +92,22 @@ static int msgsnd_wait(FAR struct msgq_s *msgq, int msgflg)
|
|||
*/
|
||||
|
||||
DEBUGASSERT(NULL != rtcb->flink);
|
||||
up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. */
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(rtcb, true);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
rtcb->task_state = TSTATE_WAIT_MQNOTFULL;
|
||||
nxsched_add_prioritized(rtcb, MQ_WNFLIST(msgq->cmn));
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
up_block_task(rtcb);
|
||||
}
|
||||
|
||||
/* When we resume at this point, either (1) the message queue
|
||||
* is no longer empty, or (2) the wait has been interrupted by
|
||||
|
|
|
@ -110,6 +110,7 @@ void pg_miss(void)
|
|||
{
|
||||
FAR struct tcb_s *ftcb = this_task();
|
||||
FAR struct tcb_s *wtcb;
|
||||
bool switch_needed;
|
||||
|
||||
/* Sanity checking
|
||||
*
|
||||
|
@ -134,7 +135,22 @@ void pg_miss(void)
|
|||
*/
|
||||
|
||||
DEBUGASSERT(!is_idle_task(ftcb));
|
||||
up_block_task(ftcb, TSTATE_WAIT_PAGEFILL);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. */
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(ftcb, true);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
ftcb->task_state = TSTATE_WAIT_PAGEFILL;
|
||||
nxsched_add_prioritized(ftcb, &g_waitingforfill);
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
up_block_task(ftcb);
|
||||
}
|
||||
|
||||
/* Boost the page fill worker thread priority.
|
||||
* - Check the priority of the task at the head of the g_waitingforfill
|
||||
|
|
|
@ -314,7 +314,7 @@ int nxthread_create(FAR const char *name, uint8_t ttype, int priority,
|
|||
/* Task list manipulation functions */
|
||||
|
||||
bool nxsched_add_readytorun(FAR struct tcb_s *rtrtcb);
|
||||
bool nxsched_remove_readytorun(FAR struct tcb_s *rtrtcb);
|
||||
bool nxsched_remove_readytorun(FAR struct tcb_s *rtrtcb, bool merge);
|
||||
bool nxsched_add_prioritized(FAR struct tcb_s *tcb, DSEG dq_queue_t *list);
|
||||
void nxsched_merge_prioritized(FAR dq_queue_t *list1, FAR dq_queue_t *list2,
|
||||
uint8_t task_state);
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
*
|
||||
* Input Parameters:
|
||||
* rtcb - Points to the TCB that is ready-to-run
|
||||
* merge - Merge pending list or not
|
||||
*
|
||||
* Returned Value:
|
||||
* true if the currently active task (the head of the ready-to-run list)
|
||||
|
@ -60,7 +61,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb)
|
||||
bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb, bool merge)
|
||||
{
|
||||
bool doswitch = false;
|
||||
|
||||
|
@ -92,6 +93,12 @@ bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb)
|
|||
/* Since the TCB is not in any list, it is now invalid */
|
||||
|
||||
rtcb->task_state = TSTATE_TASK_INVALID;
|
||||
|
||||
if (g_pendingtasks.head && merge)
|
||||
{
|
||||
doswitch |= nxsched_merge_pending();
|
||||
}
|
||||
|
||||
return doswitch;
|
||||
}
|
||||
#endif /* !CONFIG_SMP */
|
||||
|
@ -104,6 +111,7 @@ bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb)
|
|||
*
|
||||
* Input Parameters:
|
||||
* rtcb - Points to the TCB that is ready-to-run
|
||||
* merge - Merge pending list or not
|
||||
*
|
||||
* Returned Value:
|
||||
* true if the currently active task (the head of the ready-to-run list)
|
||||
|
@ -119,7 +127,7 @@ bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb)
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb)
|
||||
bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb, bool merge)
|
||||
{
|
||||
FAR dq_queue_t *tasklist;
|
||||
bool doswitch = false;
|
||||
|
@ -276,6 +284,11 @@ bool nxsched_remove_readytorun(FAR struct tcb_s *rtcb)
|
|||
|
||||
rtcb->task_state = TSTATE_TASK_INVALID;
|
||||
|
||||
if (g_pendingtasks.head && merge)
|
||||
{
|
||||
doswitch |= nxsched_merge_pending();
|
||||
}
|
||||
|
||||
return doswitch;
|
||||
}
|
||||
#endif /* CONFIG_SMP */
|
||||
|
|
|
@ -236,7 +236,7 @@ static void nxsched_readytorun_setpriority(FAR struct tcb_s *tcb,
|
|||
* It should not be at the head of the list.
|
||||
*/
|
||||
|
||||
bool check = nxsched_remove_readytorun(tcb);
|
||||
bool check = nxsched_remove_readytorun(tcb, false);
|
||||
DEBUGASSERT(check == false);
|
||||
UNUSED(check);
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
void nxsched_suspend(FAR struct tcb_s *tcb)
|
||||
{
|
||||
irqstate_t flags;
|
||||
bool switch_needed;
|
||||
|
||||
DEBUGASSERT(tcb != NULL);
|
||||
|
||||
|
@ -73,10 +74,13 @@ void nxsched_suspend(FAR struct tcb_s *tcb)
|
|||
|
||||
/* Move the TCB to the g_stoppedtasks list. */
|
||||
|
||||
nxsched_add_blocked(tcb, TSTATE_TASK_STOPPED);
|
||||
tcb->task_state = TSTATE_TASK_STOPPED;
|
||||
dq_addlast((FAR dq_entry_t *)tcb, &g_stoppedtasks);
|
||||
}
|
||||
else
|
||||
{
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
|
||||
/* The task was running or runnable before being stopped. Simply
|
||||
* block it in the stopped state. If tcb refers to this task, then
|
||||
* this action will block this task.
|
||||
|
@ -85,7 +89,22 @@ void nxsched_suspend(FAR struct tcb_s *tcb)
|
|||
*/
|
||||
|
||||
DEBUGASSERT(!is_idle_task(tcb));
|
||||
up_block_task(tcb, TSTATE_TASK_STOPPED);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. */
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(tcb, true);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
tcb->task_state = TSTATE_TASK_STOPPED;
|
||||
dq_addlast((FAR dq_entry_t *)tcb, &g_stoppedtasks);
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
up_block_task(rtcb);
|
||||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
|
|
@ -72,6 +72,7 @@ int nxsem_wait(FAR sem_t *sem)
|
|||
{
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
irqstate_t flags;
|
||||
bool switch_needed;
|
||||
int ret;
|
||||
|
||||
/* This API should not be called from interrupt handlers & idleloop */
|
||||
|
@ -150,7 +151,22 @@ int nxsem_wait(FAR sem_t *sem)
|
|||
*/
|
||||
|
||||
DEBUGASSERT(!is_idle_task(rtcb));
|
||||
up_block_task(rtcb, TSTATE_WAIT_SEM);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. */
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(rtcb, true);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
rtcb->task_state = TSTATE_WAIT_SEM;
|
||||
nxsched_add_prioritized(rtcb, SEM_WAITLIST(sem));
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
up_block_task(rtcb);
|
||||
}
|
||||
|
||||
/* When we resume at this point, either (1) the semaphore has been
|
||||
* assigned to this thread of execution, or (2) the semaphore wait
|
||||
|
|
|
@ -80,6 +80,7 @@ int sigsuspend(FAR const sigset_t *set)
|
|||
FAR struct tcb_s *rtcb = this_task();
|
||||
sigset_t saved_sigprocmask;
|
||||
irqstate_t flags;
|
||||
bool switch_needed;
|
||||
|
||||
/* sigsuspend() is a cancellation point */
|
||||
|
||||
|
@ -123,7 +124,22 @@ int sigsuspend(FAR const sigset_t *set)
|
|||
*/
|
||||
|
||||
DEBUGASSERT(!is_idle_task(rtcb));
|
||||
up_block_task(rtcb, TSTATE_WAIT_SIG);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. */
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(rtcb, true);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
rtcb->task_state = TSTATE_WAIT_SIG;
|
||||
dq_addlast((FAR dq_entry_t *)rtcb, &g_waitingforsignal);
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
up_block_task(rtcb);
|
||||
}
|
||||
|
||||
/* We are running again, restore the original sigprocmask */
|
||||
|
||||
|
|
|
@ -243,6 +243,7 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
|
|||
FAR sigpendq_t *sigpend;
|
||||
irqstate_t flags;
|
||||
int32_t waitticks;
|
||||
bool switch_needed;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(set != NULL);
|
||||
|
@ -351,7 +352,22 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
|
|||
*/
|
||||
|
||||
DEBUGASSERT(!is_idle_task(rtcb));
|
||||
up_block_task(rtcb, TSTATE_WAIT_SIG);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. */
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(rtcb, true);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
rtcb->task_state = TSTATE_WAIT_SIG;
|
||||
dq_addlast((FAR dq_entry_t *)rtcb, &g_waitingforsignal);
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
up_block_task(rtcb);
|
||||
}
|
||||
|
||||
/* We no longer need the watchdog */
|
||||
|
||||
|
@ -378,7 +394,22 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
|
|||
*/
|
||||
|
||||
DEBUGASSERT(!is_idle_task(rtcb));
|
||||
up_block_task(rtcb, TSTATE_WAIT_SIG);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. */
|
||||
|
||||
switch_needed = nxsched_remove_readytorun(rtcb, true);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
rtcb->task_state = TSTATE_WAIT_SIG;
|
||||
dq_addlast((FAR dq_entry_t *)rtcb, &g_waitingforsignal);
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
up_block_task(rtcb);
|
||||
}
|
||||
}
|
||||
|
||||
/* We are running again, clear the sigwaitmask */
|
||||
|
|
|
@ -100,16 +100,7 @@ int nxtask_exit(void)
|
|||
* ready-to-run with state == TSTATE_TASK_RUNNING
|
||||
*/
|
||||
|
||||
nxsched_remove_readytorun(dtcb);
|
||||
|
||||
/* If there are any pending tasks, then add them to the ready-to-run
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head != NULL)
|
||||
{
|
||||
nxsched_merge_pending();
|
||||
}
|
||||
nxsched_remove_readytorun(dtcb, true);
|
||||
|
||||
/* Get the new task at the head of the ready to run list */
|
||||
|
||||
|
|
Loading…
Reference in a new issue