Golikov 0 2 апреля, 2014 Опубликовано 2 апреля, 2014 · Жалоба 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 и кого вы обманули:)? сами себя, напихав доп действий%)? это мне надо было в гугле найти? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 2 апреля, 2014 Опубликовано 2 апреля, 2014 (изменено) · Жалоба а чем это отличается от запрета прерывания перед входом в критическую секцию, и разрешением его после выхода? Разница есть. Речь о том, кто запрещает прерывание: конкурент (это плохо) или сам обработчик (он в курсе, и это лучше). Запрет прерывания в основной программе (скорее всего, некоем быстром цикле) происходил бы всегда и безусловно, и во время критической секции прерывание вообще бы не сработало. В моем же методе прерывание, как основной поставщик асинхронных данных, имеет приоритет, т.к. не запрещается извне, а само контролирует ситуацию, откладывать себя или нет. Кстати, такой же подход (когда конкурент за ресурс не запрещает, а разрешает прерывание) работает у меня в системе с двумя RF модулями на одной SPI-шине (конечно, каждый с собственным chip select): каждый модуль вырабатывает прерывание, которое должно слизать из него принятые данные. Но и основная программа может инициировать синхронный обмен с модулями. Что будет, если основная программа как раз обменивается с другим модулем, шина SPI занята, а первому модулю срочно приспичило? Нужно отложить прерывание, а конкурент, закончив обмен по SPI, его всегда переразрешает. Если оно было отложено, оно сработает. Такой подход, кстати, исключает также и взаимную блокировку, т.к. конкурент за ресурс ничего не запрещает. P.S. Не Вам, а ТС в Гугле найти. Я никого не собираюсь переубеждать. Я рассказываю, как это работает у меня. Изменено 2 апреля, 2014 пользователем KnightIgor Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 2 апреля, 2014 Опубликовано 2 апреля, 2014 · Жалоба давайте еще раз, я чего то не понимаю моя последовательность действий 1. запрет прерывания 2. обработка 3. разрешение прерывания. в случае прерывания до 1 или после 3 все работает в случае прерывания 1-2, 2-3 обработка прерывания откладывается до после 3, и там обрабатывается ваша последовательность действий 1. ставим флаг 2. обработка 3. снятие флага. 4. разрешение прерывания в случае до 1 и после 4 все работает в случае прерывания 1-2, 2-3, 3-4, прерывание вызывается, запрещает себя, выходит из прерывания, продолжает обработка, а прерывание откладывается до после 4, где повторно вызывается и обрабатывается. результат один, прерывание работает либо до либо после критического куска, прерывание не работает внутри куска, все вызовы внутри откладываются до окончания куска. но при этом в вашем варианте вы делаете лишний вызов прерывания со всеми сохранениями регистров, у вас добавлен лишний флаг, в прерывании сделана лишняя проверка. Почему это лучше? Что разница есть это очевидно, но почему эта разница полезная?! что я упускаю? Разница есть. Речь о том, кто запрещает прерывание: конкурент (это плохо) или сам обработчик (он в курсе, и это лучше). это сильно зависит от обработчика, если он выполняет одно короткое действие, то он вообще не должен быть в курсе чего либо. А если есть два конкурирующие за ресурс устройства, то должен быть арбитр, который как раз решает приоритеты доступа. И я не уверен что назначать арбитром само прерывание (считай нагружать его еще дополнительным функционалом) правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 2 апреля, 2014 Опубликовано 2 апреля, 2014 · Жалоба давайте еще раз, я чего то не понимаю результат один, прерывание работает либо до либо после критического куска, прерывание не работает внутри куска, все вызовы внутри откладываются до окончания куска. Выделенным жирно в цитате - КЛЮЧЕВОЙ МОМЕНТ, в котором и заключается разница методов: - при запрете прерывания перед критической секцией в основной программе (Ваш вариант) ВХОДА в прерывание действительно не будет, как Вы и написали выше. Мне такое поведение алгоритма не нравится, т.к. это есть блокировка со стороны конкурента. - в моем варианте вход в прерывание происходит даже внутри критической секции конкурента, то есть прерывание РАБОТАЕТ внутри куска. И именно прерывание решает, что делать, поняв, что прервало критическую секцию. В простейшем случае - отложить саму себя. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 2 апреля, 2014 Опубликовано 2 апреля, 2014 · Жалоба По-моему, задача обработки фифо решена была несколько раньше, чем я пошёл в школу. А мне уже 47. Стандартно делается 2 указателя на начало и конец. Прерывание работает с указателем на конец, а голова с указателем на начало. Критическим является лишь сравнение указалей для контроля "перехлёста", если это принципиально возможно (например при управлении потоком и т.п.) Это 1 оператор. Его лучше защитить критической секцией. Это самый простой способ. Стиральная доска, надёжнее чем стиральная машина. Усложнение программы не ведёт к увеличению её надёжности в целом. Всегда существует какой-то баланс. Поэтому я разделяю позицию Golikov A.. Усложнение программы должно быть обосновано. Надёжностью, наглядностью, прочими критериями. Рассуждения KnightIgor мне показались неубедительными ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 2 апреля, 2014 Опубликовано 2 апреля, 2014 · Жалоба то есть прерывание РАБОТАЕТ внутри куска. И именно прерывание решает, что делать, поняв, что прервало критическую секцию. В простейшем случае - отложить саму себя. то есть прерывание определяет откуда его вызвали? Не легче ли это определять тому в ком прерывание может быть потенциально вызвано? Хотя в общих чертах я понял чего вы хотели, просто пример неудачный... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 3 апреля, 2014 Опубликовано 3 апреля, 2014 · Жалоба По-моему, задача обработки фифо решена была несколько раньше, чем я пошёл в школу. А мне уже 47. Стандартно делается 2 указателя на начало и конец. Прерывание работает с указателем на конец, а голова с указателем на начало. Критическим является лишь сравнение указалей для контроля "перехлёста", если это принципиально возможно (например при управлении потоком и т.п.) Это 1 оператор. Его лучше защитить критической секцией. Это самый простой способ. Для FIFO вообще не нужны критические секции если есть только один писатель и только один читатель. Это даёт возможность использовать их даже там, где запрет прерываний невозможен в принципе (например: в межпроцессорном обмене). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 3 апреля, 2014 Опубликовано 3 апреля, 2014 · Жалоба Для FIFO вообще не нужны критические секции если есть только один писатель и только один читатель. Именно об этом я и писал. Но, в случае управления потоком, когда контролируешь переполнение буфера, всё же приходится делать одну критическую секцию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 3 апреля, 2014 Опубликовано 3 апреля, 2014 · Жалоба Как так? FIFO не должно переполняться. Что-то у вас не так... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 3 апреля, 2014 Опубликовано 3 апреля, 2014 · Жалоба Рассуждения KnightIgor мне показались неубедительными ...Ну отчего же? Тоже вполне себе решение. Кстати, существенно уменьшающее латентность системы в целом. Когда-то это может быть чуть ли не единственным выходом из ситуации (безотносительно примера с fifo). Правда, практически того же эффекта можно добиться запрещая-разрешая прерывание _конкретного_ источника, а не всех прерываний в фоновой задаче. Избирательность - это хорошо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 3 апреля, 2014 Опубликовано 3 апреля, 2014 · Жалоба Хорошо бы примерчик взаимной блокировки от KnightIgor. Это ведь главное (ключевое) отличие Вашего подхода? Мол, конкурирующий запрет привел к блокировке, а конкурирующее разрешение нет. И еще: кто-нить пользуется SVC? Может, лучше через SVC, раз "лишние" прерывания KnightIgor не напрягают? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 3 апреля, 2014 Опубликовано 3 апреля, 2014 · Жалоба Как так? FIFO не должно переполняться. Что-то у вас не так... Да элементарно. Представим себе модем. Скорость rs232 115200, скорость по линии 33600. И ваш fifo по определению переполняется. Дабы этого не происходило, вам надо при заполнении фифо на 90% управлять потоком. То есть высылать XOFF либо снимать RTS. А при освобождении буфера необходимо опять разрешать подгрузку. В целом так будет происходить в любом случае, когда скорость обработки информации меньше чем скорость заполнения буфера. Так вот в момент определения уровня заполнения буфера, необходимо сравнивать 2 указателя. В общем случае требуется критическая секция. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 3 апреля, 2014 Опубликовано 3 апреля, 2014 · Жалоба И еще: кто-нить пользуется SVC? Может, лучше через SVC, раз "лишние" прерывания KnightIgor не напрягают? начинаю ненавидеть аббревиатуры, впечатление что все в курсе, а ты один дурак не понимаешь о чем речь. SVS - это че?:) Так вот в момент определения уровня заполнения буфера, необходимо сравнивать 2 указателя. В общем случае требуется критическая секция. только на момент выбора этих указателей из памяти, да и то только в том случае если указатель выбирается не за 1 такт. В этом случае пока вы считываете указатель между вашими командами может что-то влезть и вы получите начало указателя верное, а конец нет. В прочих случаях вы максимум получите прошлое значение указателя, и достаточно ввести запас, снимать сигнал готовности на 90% а не на 99.9% и всех делов. Пользуюсь золотым правилом менять переменные только в одном месте, это ограждает от многих проблем прерываний. То есть если есть прерывание которое добавляет данные и есть процесс который данные забирает, многие делают что прерывание добавило данные и счетчик данных увеличило, процесс забрал данные и счетчик уменьшил - это не верное решение, потому что на время процесса всегда надо блокировать прерывание. А если каждый процесс меняет только свою переменную, а другой ее только читает, то при атомарном выборе данных из памяти запретов прерывания не нужно. Поразмыслив над подходом KnightIgor увидел только один бонус, ему не надо думать в коде какие прерывания надо запретить на время критической секции, он просто отмечает вид секции, а все прерывания которые могут повредить этот вид секции выключат сами себя. Однако в конце секции ему все равно приходиться вспоминать все что могло отключится чтобы это включить, или где-то это сохранять. Также есть вероятность при добавлении нового вида критической секции забыть обновить обработчики прерываний на выключения для этого вида. Так что придерживаюсь своего мнения, что лучше перед секцией отключать конкретные прерывания а в конце их включать, потому что так включение и выключение находятся рядом что повышает надежность. Если я чего-то упустил, был бы благодарен примеру, не стеба ради, а чтобы стать лучше чем был вчера... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 3 апреля, 2014 Опубликовано 3 апреля, 2014 · Жалоба начинаю ненавидеть аббревиатуры, впечатление что все в курсе, а ты один дурак не понимаешь о чем речь. SVS - это че?:)SVC - это http://en.wikipedia.org/wiki/Supervisor_Call_instruction ну и для ARM-CM3 конкретно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrewlekar 0 3 апреля, 2014 Опубликовано 3 апреля, 2014 · Жалоба SVS - это че? Это видимо имелось в виду программное прерывание. Правильнее его называть SWI. а чтобы стать лучше чем был вчера... Проще использовать мютексы и не городить сложных систем с критическими секциями и платформозависимой атомарностью. Не разделяю любви с неблокирующим алгоритмам - их очень трудно поддерживать и очень легко сломать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться