реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> неверное использование volatile в OS::TKernel::context_switch_hook()
Timmy
сообщение Feb 24 2017, 08:54
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



Всем привет!
Обратил внимание на следующую вещь:
Код
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 приводит к её двойному чтению, в данном случае без тяжёлых последствий, просто неоптимально по длине кода.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Feb 25 2017, 07:55
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Ну так объявляете переменную в функции, туда читаете то, что надо оптимизировать и работаете с ней.
Go to the top of the page
 
+Quote Post
dxp
сообщение Feb 26 2017, 06:55
Сообщение #3


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



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 приводит к её двойному чтению, в данном случае без тяжёлых последствий, просто неоптимально по длине кода.

Да, тут приходится согласиться - та же дополнительная загрузка.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Timmy
сообщение Feb 27 2017, 06:12
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



Цитата(dxp @ Feb 26 2017, 09:55) *
Переключение контекста при разрешённых прерываниях не кажется хорошей идеей. Это открывает дорогу всяким неочевидным неприятностям, самое простая из которых - повышение требований размеру стека, куда сохраняются регистры.
В случае Cortex-M требуемый размер стека не увеличится, так как его переключатель контекстов использует из стека прерываний только одно слово, и оно и сейчас используется в точке с разрешёнными прерываниями.
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 4 2017, 03:56
Сообщение #5


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



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

Как быть в случае не Cortex-M? И самое главное - что это даёт по большому счёту? Прерывание вызовется на несколько сот нс раньше?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 16th April 2024 - 15:34
Рейтинг@Mail.ru


Страница сгенерированна за 0.01437 секунд с 7
ELECTRONIX ©2004-2016