Защитить критическую секцию кода в обработчике прерывания
#include <sys/neutrino.h>void InterruptLock( intrspin_t *spinlock );
Если spinlock не является статической переменной, необходимо инициализировать её, вызвав:
перед использованием с InterruptLock(). |
libc
Функция InterruptLock() защищает критическую секцию кода, захватывая spinlock и отключая прерывания. Может вызваться из потока или из обработчика прерывания. Перед вызовом этой функции поток должен запросить привилегии ввода-вывода, вызвав:
ThreadCtl( _NTO_TCTL_IO, 0 );
Если поток этого не сделает, он может получить SIGSEGV
при вызове InterruptLock().
Эта функция захватывает spinlock (переменная, совместно используемая обработчиком прерываний и потоком) пока прерывания выключены. Функция использует короткий цикл с опросом при ожидании захвата блокировки. Необходимо снять блокировку как можно быстрее. Как правило, это несколько строк кода без каких-либо циклов:
InterruptLock( &spinner );/* ... критическая секция кода */InterruptUnlock( &spinner );
InterruptLock() решает распространённую в системах реального времени проблему защиты доступа к общим данным, используемым совместно в обработчике прерывания и потоке, подключившем этот обработчик. Традиционные примитивы POSIX для потоков недоступны для использования в обработчике прерывания.
Функции InterruptLock() и InterruptUnlock() работают и на однопроцессорных/одноядерных, и на многоядерных/многопроцессорных системах.
Любой системный вызов приводит к включению прерываний, многие библиотечные функции используют системные вызовы. Замаскированные прерывания это не затрагивает. |
ЗОСРВ «Нейтрино»
InterruptDisable(), InterruptEnable(), InterruptMask(), InterruptUnlock(), InterruptUnmask(), ThreadCtl()
Предыдущий раздел: Описание API системной библиотеки