Реентерабельная функция

Здравствуйте, в статье на https://www.embedded.com/design/operating-systems/4008268/2/Back-to-the-Basics--Practical-Embedded-Coding-Tips-Part-1, есть упоминание о как сделать функцию реентерабельной.

long i; 
void do_something(void){ 
    disable_interrupts();
    i+=0x1234; 
    enable_interrupts();
}

Автор говорит: "Это решение не работает. Если do_something() - это общая процедура, которая, возможно, вызывается из многих мест и вызывается с отключенными прерываниями, она возвращается после их повторного включения. Контекст машины изменяется, вероятно, в очень опасная манера."

Я не понимаю, как именно изменился контекст машины опасно? Может ли кто-нибудь привести какой-то пример, где это может привести к вредным последствиям, чтобы прояснить это?

1 ответ

Решение

Обратите внимание, что do_something() может вызываться как из мест, где прерывания включены, так и из мест, где прерывания уже отключены. Включение прерываний во втором случае противоречит ожиданиям вызывающего абонента в очень опасной манере.

Что вам действительно нужно, так это сохранить предыдущее состояние прерываний при их отключении и восстановить его после этого.

Итак, лучшая версия будет:

long i; 
void do_something(void){ 
    irq_state_t prev_int_state = disable_interrupts_save();
    i+=0x1234; 
    restore_interrupts(prev_int_state);
}
Другие вопросы по тегам