Timmy 0 Posted February 24, 2017 · Report post Всем привет! Обратил внимание на следующую вещь: 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 приводит к её двойному чтению, в данном случае без тяжёлых последствий, просто неоптимально по длине кода. Quote Ответить с цитированием Share this post Link to post Share on other sites
GenaSPB 0 Posted February 25, 2017 · Report post Ну так объявляете переменную в функции, туда читаете то, что надо оптимизировать и работаете с ней. Quote Ответить с цитированием Share this post Link to post Share on other sites
dxp 0 Posted February 26, 2017 · Report post Всем привет! Обратил внимание на следующую вещь: 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 приводит к её двойному чтению, в данном случае без тяжёлых последствий, просто неоптимально по длине кода. Да, тут приходится согласиться - та же дополнительная загрузка. Quote Ответить с цитированием Share this post Link to post Share on other sites
Timmy 0 Posted February 27, 2017 · Report post Переключение контекста при разрешённых прерываниях не кажется хорошей идеей. Это открывает дорогу всяким неочевидным неприятностям, самое простая из которых - повышение требований размеру стека, куда сохраняются регистры.В случае Cortex-M требуемый размер стека не увеличится, так как его переключатель контекстов использует из стека прерываний только одно слово, и оно и сейчас используется в точке с разрешёнными прерываниями. Quote Ответить с цитированием Share this post Link to post Share on other sites
dxp 0 Posted March 4, 2017 · Report post В случае Cortex-M требуемый размер стека не увеличится, так как его переключатель контекстов использует из стека прерываний только одно слово, и оно и сейчас используется в точке с разрешёнными прерываниями. Как быть в случае не Cortex-M? И самое главное - что это даёт по большому счёту? Прерывание вызовется на несколько сот нс раньше? Quote Ответить с цитированием Share this post Link to post Share on other sites