sched/sched: Fix some priority inheritance related issues noted during review of logic. Also add some REVISIT comments for some issues noted in the design.

This commit is contained in:
Gregory Nutt 2018-01-20 07:44:35 -06:00
parent e8e8914cab
commit 82cc0ead67

View File

@ -129,7 +129,19 @@ static int sporadic_set_lowpriority(FAR struct tcb_s *tcb)
#ifdef CONFIG_PRIORITY_INHERITANCE #ifdef CONFIG_PRIORITY_INHERITANCE
/* If the priority was boosted above the higher priority, than just /* If the priority was boosted above the higher priority, than just
* reset the base priority. * reset the base priority and continue to run at the boosted priority.
*
* REVISIT: There is a logic flaw here... If the priority was NOT
* boosted above the hi_priority, then it still may still need to
* boosted with respect to the lo_priority. If the highest priority
* thread waiting on a semaphore held by the sporadic thread is greater
* than the low priority (but less than the hi_priority), the new
* sched_priority should be set to that priority, not to the lo_priority
*
* In order to do this we would need a list of all semaphores held by
* the thread. We would need to select the highest priority from among
* all tasks waiting for the semaphores. Unfortunately, at present we
* know nothing about the semaphores held by the sporadic thread.
*/ */
if (tcb->sched_priority > tcb->base_priority) if (tcb->sched_priority > tcb->base_priority)
@ -140,18 +152,20 @@ static int sporadic_set_lowpriority(FAR struct tcb_s *tcb)
tcb->base_priority = tcb->low_priority; tcb->base_priority = tcb->low_priority;
} }
else
#endif #endif
/* Otherwise drop the priority of thread, possible causing a context
* switch.
*/
ret = sched_reprioritize(tcb, sporadic->low_priority);
if (ret < 0)
{ {
int errcode = get_errno(); /* Otherwise drop the priority of thread, possible causing a context
serr("ERROR: sched_reprioritize failed: %d\n", errcode); * switch.
return -errcode; */
ret = sched_reprioritize(tcb, sporadic->low_priority);
if (ret < 0)
{
int errcode = get_errno();
serr("ERROR: sched_reprioritize failed: %d\n", errcode);
return -errcode;
}
} }
return OK; return OK;
@ -188,16 +202,27 @@ static int sporadic_set_hipriority(FAR struct tcb_s *tcb)
#ifdef CONFIG_PRIORITY_INHERITANCE #ifdef CONFIG_PRIORITY_INHERITANCE
/* If the priority was boosted above the higher priority, than just /* If the priority was boosted above the higher priority, than just
* reset the base priority. * reset the base priority.
*
* First, was the priority boosted above the lo_priority which should be
* the same as the base_priority here? (This is an unnecessary test.
* sched_priority > hi_priority would be sufficient).
*/ */
if (tcb->sched_priority > tcb->base_priority) if (tcb->sched_priority > tcb->base_priority)
{ {
/* Boosted... Do we still need to reprioritize? */ /* Boosted... Do we still need to reprioritize? If we were boosted to
* a priority above the hi_priority then we do not need to do anything
* except to adjust the base_priority
*
* REVISIT: This logic is probably okay. But may lead to problems
* when the hi_priority is resumed. See REVISIT comments in
* sporadic_set_lowpriority().
*/
if (sporadic->hi_priority < tcb->base_priority) if (tcb->sched_priority > sporadic->hi_priority)
{ {
/* No.. the current execution priority is lower than the /* No.. the new execution priority is lower than the boosted
* boosted priority. Just reset the base priority. * priority. Just reset the base priority.
*/ */
tcb->base_priority = sporadic->hi_priority; tcb->base_priority = sporadic->hi_priority;