Перейти к содержанию
    

неверное использование volatile в OS::TKernel::context_switch_hook()

Всем привет!

Обратил внимание на следующую вещь:

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 запишется другой процесс и всё развалится:). А вот если сделать локальную копию SchedProcPriority, то, например, для Cortex-M прерывания при переключении контекста можно и не запрещать.

И ещё кусочек:

        if(p->Timeout > 0)
        {
            if(--p->Timeout == 0)
            {
                set_process_ready(p->Priority);
            }
        }

Неиспользование локальной копии p->Timeout приводит к её двойному чтению, в данном случае без тяжёлых последствий, просто неоптимально по длине кода.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну так объявляете переменную в функции, туда читаете то, что надо оптимизировать и работаете с ней.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всем привет!

Обратил внимание на следующую вещь:

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 запишется другой процесс и всё развалится:). А вот если сделать локальную копию SchedProcPriority, то, например, для Cortex-M прерывания при переключении контекста можно и не запрещать.

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

 

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

 

И ещё кусочек:
        if(p->Timeout > 0)
        {
            if(--p->Timeout == 0)
            {
                set_process_ready(p->Priority);
            }
        }

Неиспользование локальной копии p->Timeout приводит к её двойному чтению, в данном случае без тяжёлых последствий, просто неоптимально по длине кода.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В случае Cortex-M требуемый размер стека не увеличится, так как его переключатель контекстов использует из стека прерываний только одно слово, и оно и сейчас используется в точке с разрешёнными прерываниями.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...