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

2.1. Установить флаг.

2.2. Выполнить действия.

2.3. Сбросить флаг.

2.4. (Пере)разрешить прерывание от источника данных.

а чем это отличается от запрета прерывания перед входом в критическую секцию, и разрешением его после выхода?

 

2.1. запретить прерывание (не все, а конкретное)

2.2. Выполнить действия.

2.3. Разрешить прерывание (не все, а конкретное)

прерывание вызванное до 2.1 и после 2.3 также как в вашем случае вызванное до 2.1 и после 2.4

прерывание между 2.1 - 2.2 и 2.2 - 2.3 не будет вызвано, его вызов отложиться до после 2.3,

А в вашем случае прерывание между 2.1 - 2.2 и 2.2 - 2.3 будет вызвано, в нем оно себя запретит, выйдет, после чего будет также не вызываться, до окончания 2.4

 

и кого вы обманули:)? сами себя, напихав доп действий%)?

это мне надо было в гугле найти?

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


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

а чем это отличается от запрета прерывания перед входом в критическую секцию, и разрешением его после выхода?

Разница есть. Речь о том, кто запрещает прерывание: конкурент (это плохо) или сам обработчик (он в курсе, и это лучше).

 

Запрет прерывания в основной программе (скорее всего, некоем быстром цикле) происходил бы всегда и безусловно, и во время критической секции прерывание вообще бы не сработало. В моем же методе прерывание, как основной поставщик асинхронных данных, имеет приоритет, т.к. не запрещается извне, а само контролирует ситуацию, откладывать себя или нет. Кстати, такой же подход (когда конкурент за ресурс не запрещает, а разрешает прерывание) работает у меня в системе с двумя RF модулями на одной SPI-шине (конечно, каждый с собственным chip select): каждый модуль вырабатывает прерывание, которое должно слизать из него принятые данные. Но и основная программа может инициировать синхронный обмен с модулями. Что будет, если основная программа как раз обменивается с другим модулем, шина SPI занята, а первому модулю срочно приспичило? Нужно отложить прерывание, а конкурент, закончив обмен по SPI, его всегда переразрешает. Если оно было отложено, оно сработает. Такой подход, кстати, исключает также и взаимную блокировку, т.к. конкурент за ресурс ничего не запрещает.

 

P.S. Не Вам, а ТС в Гугле найти. Я никого не собираюсь переубеждать. Я рассказываю, как это работает у меня.

Изменено пользователем KnightIgor

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


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

давайте еще раз, я чего то не понимаю

 

моя последовательность действий

 

1. запрет прерывания

2. обработка

3. разрешение прерывания.

 

в случае прерывания до 1 или после 3 все работает

в случае прерывания 1-2, 2-3 обработка прерывания откладывается до после 3, и там обрабатывается

 

ваша последовательность действий

1. ставим флаг

2. обработка

3. снятие флага.

4. разрешение прерывания

в случае до 1 и после 4 все работает

в случае прерывания 1-2, 2-3, 3-4, прерывание вызывается, запрещает себя, выходит из прерывания, продолжает обработка, а прерывание откладывается до после 4, где повторно вызывается и обрабатывается.

 

результат один, прерывание работает либо до либо после критического куска, прерывание не работает внутри куска, все вызовы внутри откладываются до окончания куска.

 

но при этом в вашем варианте вы делаете лишний вызов прерывания со всеми сохранениями регистров, у вас добавлен лишний флаг, в прерывании сделана лишняя проверка. Почему это лучше? Что разница есть это очевидно, но почему эта разница полезная?! что я упускаю?

 

 

 

Разница есть. Речь о том, кто запрещает прерывание: конкурент (это плохо) или сам обработчик (он в курсе, и это лучше).

 

это сильно зависит от обработчика, если он выполняет одно короткое действие, то он вообще не должен быть в курсе чего либо. А если есть два конкурирующие за ресурс устройства, то должен быть арбитр, который как раз решает приоритеты доступа. И я не уверен что назначать арбитром само прерывание (считай нагружать его еще дополнительным функционалом) правильно.

 

 

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


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

давайте еще раз, я чего то не понимаю

результат один, прерывание работает либо до либо после критического куска, прерывание не работает внутри куска, все вызовы внутри откладываются до окончания куска.

Выделенным жирно в цитате - КЛЮЧЕВОЙ МОМЕНТ, в котором и заключается разница методов:

- при запрете прерывания перед критической секцией в основной программе (Ваш вариант) ВХОДА в прерывание действительно не будет, как Вы и написали выше. Мне такое поведение алгоритма не нравится, т.к. это есть блокировка со стороны конкурента.

- в моем варианте вход в прерывание происходит даже внутри критической секции конкурента, то есть прерывание РАБОТАЕТ внутри куска. И именно прерывание решает, что делать, поняв, что прервало критическую секцию. В простейшем случае - отложить саму себя.

 

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


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

По-моему, задача обработки фифо решена была несколько раньше, чем я пошёл в школу. А мне уже 47.

Стандартно делается 2 указателя на начало и конец. Прерывание работает с указателем на конец, а голова с указателем на начало.

Критическим является лишь сравнение указалей для контроля "перехлёста", если это принципиально возможно (например при управлении потоком и т.п.)

Это 1 оператор. Его лучше защитить критической секцией. Это самый простой способ.

Стиральная доска, надёжнее чем стиральная машина. Усложнение программы не ведёт к увеличению её надёжности в целом. Всегда существует какой-то баланс.

Поэтому я разделяю позицию Golikov A.. Усложнение программы должно быть обосновано. Надёжностью, наглядностью, прочими критериями.

Рассуждения KnightIgor мне показались неубедительными ...

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


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

то есть прерывание РАБОТАЕТ внутри куска. И именно прерывание решает, что делать, поняв, что прервало критическую секцию. В простейшем случае - отложить саму себя.

то есть прерывание определяет откуда его вызвали? Не легче ли это определять тому в ком прерывание может быть потенциально вызвано? Хотя в общих чертах я понял чего вы хотели, просто пример неудачный...

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


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

По-моему, задача обработки фифо решена была несколько раньше, чем я пошёл в школу. А мне уже 47.

Стандартно делается 2 указателя на начало и конец. Прерывание работает с указателем на конец, а голова с указателем на начало.

Критическим является лишь сравнение указалей для контроля "перехлёста", если это принципиально возможно (например при управлении потоком и т.п.)

Это 1 оператор. Его лучше защитить критической секцией. Это самый простой способ.

Для FIFO вообще не нужны критические секции если есть только один писатель и только один читатель.

Это даёт возможность использовать их даже там, где запрет прерываний невозможен в принципе (например: в межпроцессорном обмене).

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


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

Для FIFO вообще не нужны критические секции если есть только один писатель и только один читатель.

Именно об этом я и писал. Но, в случае управления потоком, когда контролируешь переполнение буфера, всё же приходится делать одну критическую секцию.

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


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

Рассуждения KnightIgor мне показались неубедительными ...
Ну отчего же?

Тоже вполне себе решение. Кстати, существенно уменьшающее латентность системы в целом.

Когда-то это может быть чуть ли не единственным выходом из ситуации (безотносительно примера с fifo).

Правда, практически того же эффекта можно добиться запрещая-разрешая прерывание _конкретного_ источника, а не всех прерываний в фоновой задаче.

Избирательность - это хорошо.

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


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

Хорошо бы примерчик взаимной блокировки от KnightIgor. Это ведь главное (ключевое) отличие Вашего подхода?

Мол, конкурирующий запрет привел к блокировке, а конкурирующее разрешение нет.

 

И еще: кто-нить пользуется SVC? Может, лучше через SVC, раз "лишние" прерывания KnightIgor не напрягают?

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


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

Как так? FIFO не должно переполняться. Что-то у вас не так...

Да элементарно. Представим себе модем. Скорость rs232 115200, скорость по линии 33600. И ваш fifo по определению переполняется. Дабы этого не происходило, вам надо при заполнении фифо на 90% управлять потоком. То есть высылать XOFF либо снимать RTS. А при освобождении буфера необходимо опять разрешать подгрузку. В целом так будет происходить в любом случае, когда скорость обработки информации меньше чем скорость заполнения буфера.

 

Так вот в момент определения уровня заполнения буфера, необходимо сравнивать 2 указателя. В общем случае требуется критическая секция.

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


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

И еще: кто-нить пользуется SVC? Может, лучше через SVC, раз "лишние" прерывания KnightIgor не напрягают?

начинаю ненавидеть аббревиатуры, впечатление что все в курсе, а ты один дурак не понимаешь о чем речь. SVS - это че?:)

 

Так вот в момент определения уровня заполнения буфера, необходимо сравнивать 2 указателя. В общем случае требуется критическая секция.

только на момент выбора этих указателей из памяти, да и то только в том случае если указатель выбирается не за 1 такт. В этом случае пока вы считываете указатель между вашими командами может что-то влезть и вы получите начало указателя верное, а конец нет. В прочих случаях вы максимум получите прошлое значение указателя, и достаточно ввести запас, снимать сигнал готовности на 90% а не на 99.9% и всех делов.

 

 

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

То есть если есть прерывание которое добавляет данные и есть процесс который данные забирает, многие делают что прерывание добавило данные и счетчик данных увеличило, процесс забрал данные и счетчик уменьшил - это не верное решение, потому что на время процесса всегда надо блокировать прерывание.

А если каждый процесс меняет только свою переменную, а другой ее только читает, то при атомарном выборе данных из памяти запретов прерывания не нужно.

 

Поразмыслив над подходом KnightIgor увидел только один бонус, ему не надо думать в коде какие прерывания надо запретить на время критической секции, он просто отмечает вид секции, а все прерывания которые могут повредить этот вид секции выключат сами себя. Однако в конце секции ему все равно приходиться вспоминать все что могло отключится чтобы это включить, или где-то это сохранять.

Также есть вероятность при добавлении нового вида критической секции забыть обновить обработчики прерываний на выключения для этого вида.

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

 

Если я чего-то упустил, был бы благодарен примеру, не стеба ради, а чтобы стать лучше чем был вчера...

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


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

начинаю ненавидеть аббревиатуры, впечатление что все в курсе, а ты один дурак не понимаешь о чем речь. SVS - это че?:)
SVC - это http://en.wikipedia.org/wiki/Supervisor_Call_instruction

ну и для ARM-CM3 конкретно.

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


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

SVS - это че?

Это видимо имелось в виду программное прерывание. Правильнее его называть SWI.

 

а чтобы стать лучше чем был вчера...

Проще использовать мютексы и не городить сложных систем с критическими секциями и платформозависимой атомарностью. Не разделяю любви с неблокирующим алгоритмам - их очень трудно поддерживать и очень легко сломать.

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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