sched/sched: fix scheduler lock/unlock operation for non-SMP case
Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
This commit is contained in:
parent
770817ba2f
commit
fcd6ec7809
@ -148,13 +148,15 @@ int sched_lock(void)
|
||||
|
||||
if (rtcb != NULL && !up_interrupt_context())
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
/* Catch attempts to increment the lockcount beyond the range of the
|
||||
* integer type.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(rtcb->lockcount < MAX_LOCK_COUNT);
|
||||
|
||||
irqstate_t flags = enter_critical_section();
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* We must hold the lock on this CPU before we increment the lockcount
|
||||
* for the first time. Holding the lock is sufficient to lockout
|
||||
@ -234,12 +236,17 @@ int sched_lock(void)
|
||||
|
||||
if (rtcb != NULL && !up_interrupt_context())
|
||||
{
|
||||
FAR struct tcb_s *ptcb;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Catch attempts to increment the lockcount beyond the range of the
|
||||
* integer type.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(rtcb->lockcount < MAX_LOCK_COUNT);
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* A counter is used to support locking. This allows nested lock
|
||||
* operations on this thread (on any CPU)
|
||||
*/
|
||||
@ -262,6 +269,22 @@ int sched_lock(void)
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Move any tasks in the ready-to-run list to the pending task list
|
||||
* where they will not be available to run until the scheduler is
|
||||
* unlocked and nxsched_merge_pending() is called. So ready-to-run
|
||||
* will consist only from the currently runnig task and the idle task.
|
||||
*/
|
||||
|
||||
for (ptcb = rtcb->flink; ptcb && ptcb->flink; ptcb = rtcb->flink)
|
||||
{
|
||||
dq_rem((FAR dq_entry_t *)ptcb, &g_readytorun);
|
||||
|
||||
nxsched_add_prioritized(ptcb, &g_pendingtasks);
|
||||
ptcb->task_state = TSTATE_TASK_PENDING;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -82,73 +82,79 @@ bool nxsched_merge_pending(void)
|
||||
|
||||
rtcb = this_task();
|
||||
|
||||
/* Process every TCB in the g_pendingtasks list */
|
||||
/* Process every TCB in the g_pendingtasks list
|
||||
*
|
||||
* Do nothing if pre-emption is still disabled
|
||||
*/
|
||||
|
||||
for (ptcb = (FAR struct tcb_s *)g_pendingtasks.head;
|
||||
ptcb;
|
||||
ptcb = pnext)
|
||||
if (rtcb->lockcount == 0)
|
||||
{
|
||||
pnext = ptcb->flink;
|
||||
|
||||
/* REVISIT: Why don't we just remove the ptcb from pending task list
|
||||
* and call nxsched_add_readytorun?
|
||||
*/
|
||||
|
||||
/* Search the ready-to-run list to find the location to insert the
|
||||
* new ptcb. Each is list is maintained in ascending sched_priority
|
||||
* order.
|
||||
*/
|
||||
|
||||
for (;
|
||||
(rtcb && ptcb->sched_priority <= rtcb->sched_priority);
|
||||
rtcb = rtcb->flink)
|
||||
for (ptcb = (FAR struct tcb_s *)g_pendingtasks.head;
|
||||
ptcb;
|
||||
ptcb = pnext)
|
||||
{
|
||||
pnext = ptcb->flink;
|
||||
|
||||
/* REVISIT: Why don't we just remove the ptcb from pending task
|
||||
* list and call nxsched_add_readytorun?
|
||||
*/
|
||||
|
||||
/* Search the ready-to-run list to find the location to insert the
|
||||
* new ptcb. Each is list is maintained in ascending sched_priority
|
||||
* order.
|
||||
*/
|
||||
|
||||
for (;
|
||||
(rtcb && ptcb->sched_priority <= rtcb->sched_priority);
|
||||
rtcb = rtcb->flink)
|
||||
{
|
||||
}
|
||||
|
||||
/* Add the ptcb to the spot found in the list. Check if the
|
||||
* ptcb goes at the ends of the ready-to-run list. This would be
|
||||
* error condition since the idle test must always be at the end of
|
||||
* the ready-to-run list!
|
||||
*/
|
||||
|
||||
DEBUGASSERT(rtcb);
|
||||
|
||||
/* The ptcb goes just before rtcb */
|
||||
|
||||
rprev = rtcb->blink;
|
||||
if (rprev == NULL)
|
||||
{
|
||||
/* Special case: Inserting ptcb at the head of the list */
|
||||
|
||||
ptcb->flink = rtcb;
|
||||
ptcb->blink = NULL;
|
||||
rtcb->blink = ptcb;
|
||||
g_readytorun.head = (FAR dq_entry_t *)ptcb;
|
||||
rtcb->task_state = TSTATE_TASK_READYTORUN;
|
||||
ptcb->task_state = TSTATE_TASK_RUNNING;
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Insert in the middle of the list */
|
||||
|
||||
ptcb->flink = rtcb;
|
||||
ptcb->blink = rprev;
|
||||
rprev->flink = ptcb;
|
||||
rtcb->blink = ptcb;
|
||||
ptcb->task_state = TSTATE_TASK_READYTORUN;
|
||||
}
|
||||
|
||||
/* Set up for the next time through */
|
||||
|
||||
rtcb = ptcb;
|
||||
}
|
||||
|
||||
/* Add the ptcb to the spot found in the list. Check if the
|
||||
* ptcb goes at the ends of the ready-to-run list. This would be
|
||||
* error condition since the idle test must always be at the end of
|
||||
* the ready-to-run list!
|
||||
*/
|
||||
/* Mark the input list empty */
|
||||
|
||||
DEBUGASSERT(rtcb);
|
||||
|
||||
/* The ptcb goes just before rtcb */
|
||||
|
||||
rprev = rtcb->blink;
|
||||
if (rprev == NULL)
|
||||
{
|
||||
/* Special case: Inserting ptcb at the head of the list */
|
||||
|
||||
ptcb->flink = rtcb;
|
||||
ptcb->blink = NULL;
|
||||
rtcb->blink = ptcb;
|
||||
g_readytorun.head = (FAR dq_entry_t *)ptcb;
|
||||
rtcb->task_state = TSTATE_TASK_READYTORUN;
|
||||
ptcb->task_state = TSTATE_TASK_RUNNING;
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Insert in the middle of the list */
|
||||
|
||||
ptcb->flink = rtcb;
|
||||
ptcb->blink = rprev;
|
||||
rprev->flink = ptcb;
|
||||
rtcb->blink = ptcb;
|
||||
ptcb->task_state = TSTATE_TASK_READYTORUN;
|
||||
}
|
||||
|
||||
/* Set up for the next time through */
|
||||
|
||||
rtcb = ptcb;
|
||||
g_pendingtasks.head = NULL;
|
||||
g_pendingtasks.tail = NULL;
|
||||
}
|
||||
|
||||
/* Mark the input list empty */
|
||||
|
||||
g_pendingtasks.head = NULL;
|
||||
g_pendingtasks.tail = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* !CONFIG_SMP */
|
||||
|
Loading…
Reference in New Issue
Block a user