2vit по поводу "крит секции" с предыдущей страницы Если исходник на плюсах, имеется еще один вариант организации крит секций. Я впервые увидел его в scmRTOS, поэтому ссылаюсь на него как на DXP-метод :-)
class TCritSec
{
public:
TCritSec () : StatusReg(__get_interrupt_state()) { __disable_interrupt(); }
~TCritSec() { __set_interrupt_state(StatusReg); }
private:
istate_t StatusReg;
};
void OS::TProcess::Sleep(word timeout)
{
TCritSec cs;
Kernel::ProcessTable[Kernel::CurProcPriority]->Timeout = timeout;
Kernel::SetProcessUnready(Kernel::CurProcPriority);
Kernel::Scheduler();
}
Использовать очень легко и безопасно - все что внутри скобок - критическая секция
Из положительных моментов - никогда не забудешь выйти из крит секции.
Отрицательных - всего два :)
- StatusReg всегда будет на стеке. Это скорее всего требование стандарта срр
- На максимуме оптимизации иар для мсп 330а в подряд идущих крит секциях допускает ошибку
И уже от себя могу добавить "тюнингованную" пару (юзаю в той же scmRTOS)
INLINE istate_t EnterCritical()
{
register istate_t istate = __get_interrupt_state();
__disable_interrupt();
return istate;
}
INLINE void ExitCritical(istate_t state)
{
__set_interrupt_state(state);
}
void Foo()
{
register istate_t s = EnterCritical();
.......................
ExitCritical(s);
}
Если компилить на мах оптимизации, то получается что то типа
62 register istate_t s = EnterCritical();
\ 000002 4A42 MOV.B SR, R10
\ 000004 32C2 DINT
\ 000006 0343 NOP
67 ExitCritical(s);
\ 000020 424A MOV.B R10, SR
Если в функции есть несколько крит секций, можно сэкономить драхму-другую на обращениях к стеку :)