Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: неверное использование volatile в OS::TKernel::context_switch_hook()
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
Timmy
Всем привет!
Обратил внимание на следующую вещь:
Код
stack_item_t* OS::TKernel::context_switch_hook(stack_item_t* sp)
{
    CONTEXT_SWITCH_HOOK_CRIT_SECT();

    ProcessTable[CurProcPriority]->StackPointer = sp;
    sp = ProcessTable[SchedProcPriority]->StackPointer;
    
#if scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE == 1
    context_switch_user_hook();
#endif

    CurProcPriority = SchedProcPriority;
    return sp;
}
SchedProcPriority - volatile, читается дважды без создания локальной копии, что приводит к необходимости обязательно запрещать прерывания перед вызовом context_switch_hook() или в CONTEXT_SWITCH_HOOK_CRIT_SECT(). Иначе в случае прерывания с перепланировкой между двумя чтениями SchedProcPriority может призойти переключение на один просесс, а в CurProcPriority запишется другой процесс и всё развалитсяsm.gif. А вот если сделать локальную копию SchedProcPriority, то, например, для Cortex-M прерывания при переключении контекста можно и не запрещать.
И ещё кусочек:
Код
        if(p->Timeout > 0)
        {
            if(--p->Timeout == 0)
            {
                set_process_ready(p->Priority);
            }
        }
Неиспользование локальной копии p->Timeout приводит к её двойному чтению, в данном случае без тяжёлых последствий, просто неоптимально по длине кода.
Genadi Zawidowski
Ну так объявляете переменную в функции, туда читаете то, что надо оптимизировать и работаете с ней.
dxp
QUOTE (Timmy @ Feb 24 2017, 15:54) *
Всем привет!
Обратил внимание на следующую вещь:
CODE
stack_item_t* OS::TKernel::context_switch_hook(stack_item_t* sp)
{
    CONTEXT_SWITCH_HOOK_CRIT_SECT();

    ProcessTable[CurProcPriority]->StackPointer = sp;
    sp = ProcessTable[SchedProcPriority]->StackPointer;
    
#if scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE == 1
    context_switch_user_hook();
#endif

    CurProcPriority = SchedProcPriority;
    return sp;
}
SchedProcPriority - volatile, читается дважды без создания локальной копии, что приводит к необходимости обязательно запрещать прерывания перед вызовом context_switch_hook() или в CONTEXT_SWITCH_HOOK_CRIT_SECT(). Иначе в случае прерывания с перепланировкой между двумя чтениями SchedProcPriority может призойти переключение на один просесс, а в CurProcPriority запишется другой процесс и всё развалитсяsm.gif. А вот если сделать локальную копию SchedProcPriority, то, например, для Cortex-M прерывания при переключении контекста можно и не запрещать.

Переключение контекста при разрешённых прерываниях не кажется хорошей идеей. Это открывает дорогу всяким неочевидным неприятностям, самое простая из которых - повышение требований размеру стека, куда сохраняются регистры.

Двойное чтение - да, тут есть элемент неэффективности, цена - одна команда загрузки "память-регистр".

QUOTE (Timmy @ Feb 24 2017, 15:54) *
И ещё кусочек:
CODE
        if(p->Timeout > 0)
        {
            if(--p->Timeout == 0)
            {
                set_process_ready(p->Priority);
            }
        }
Неиспользование локальной копии p->Timeout приводит к её двойному чтению, в данном случае без тяжёлых последствий, просто неоптимально по длине кода.

Да, тут приходится согласиться - та же дополнительная загрузка.
Timmy
Цитата(dxp @ Feb 26 2017, 09:55) *
Переключение контекста при разрешённых прерываниях не кажется хорошей идеей. Это открывает дорогу всяким неочевидным неприятностям, самое простая из которых - повышение требований размеру стека, куда сохраняются регистры.
В случае Cortex-M требуемый размер стека не увеличится, так как его переключатель контекстов использует из стека прерываний только одно слово, и оно и сейчас используется в точке с разрешёнными прерываниями.
dxp
QUOTE (Timmy @ Feb 27 2017, 13:12) *
В случае Cortex-M требуемый размер стека не увеличится, так как его переключатель контекстов использует из стека прерываний только одно слово, и оно и сейчас используется в точке с разрешёнными прерываниями.

Как быть в случае не Cortex-M? И самое главное - что это даёт по большому счёту? Прерывание вызовется на несколько сот нс раньше?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.