-
- Запрет прерываний не всегда возможен. - fk0(09.11.2017 23:40)
- Здесь ошибка не от атомарности RMW. Здесь ошибка атомарности наблюдения за инкрементами обоих переменных. Если Задача2 получила управление после tail++, когда обе переменные равны, и успев загрузить head, потеряла управление, и в следующий раз, Petrovich(80 знак., 09.11.2017 12:40, )
- Здесь есть проблема переупорядочивания записи в память, ну так она лечится барьером, я ж сказал. И проблема не записи вообще, лечится с помощью volatile. Но обращу внимание, нужен И барьер, И volatile. Ибо компилятор НЕ может переставить обращения fk0(335 знак., 09.11.2017 23:45 - 23:54)
- сорта говна. Если делается неправильный вывод неважно кем, и этот вывод устраняется DI/EI, то зачем эти сущности? - VLLV(09.11.2017 12:54)
- Петрович набросил и устранился. Атомарность нужна редко. Чаще всего можно выкрутиться при помощи volatile. - SciFi(09.11.2017 12:09)
- На 8-битном процессоре чтение и запись не атомарные -- не выкрутишься. Старший байт записал например, обновленный, а младший не успел. А другой поток читать начал. И ошибка. - fk0(09.11.2017 23:41)
- В таких случаях можно читать несколько раз, пока не прочитаешь то, что нужно. - SciFi(10.11.2017 07:31)
- Не всегда в общем случае. Как понять критерий нужности? - fk0(10.11.2017 11:31)
- часто при чтении пару раз подряд совпасть должно - Vit(10.11.2017 11:40)
- Если читаешь достаточно быстрый аппаратный таймер -- он никогда не совпадет. Младшая половина всегда убегает вперед, а старшая за несколько чтений не успевает измениться. См. мой ответ ниже. - fk0(10.11.2017 11:46)
- Таймера считываются проще Petrovich(145 знак., 10.11.2017 12:57, )
- У тебя три загрузки таймера в цикле, а у меня два. И положение байт в структуре -- не гарантировано. - fk0(10.11.2017 13:04)
- У тебя три переменных, что недопустимо! У тебя три присваивания в цикле, а у меня два, а обращение к переменной из XDATA даже дольше чем обращение к порту 8051.:) И (сказал же, что схематично!) забудь про Си, это ассемблерный харкор из 80-х, где Petrovich(149 знак., 10.11.2017 13:20, )
- Я еще помню про keil и C51. Не надо мне рассказывать. - fk0(10.11.2017 13:32)
- Завидую вашей молодости. Я один что ли на перейдя с ассемблера на ПЛ-М считал себя авангардом рабочего класса? - Petrovich(10.11.2017 13:36, )
- Я еще помню про keil и C51. Не надо мне рассказывать. - fk0(10.11.2017 13:32)
- У тебя три переменных, что недопустимо! У тебя три присваивания в цикле, а у меня два, а обращение к переменной из XDATA даже дольше чем обращение к порту 8051.:) И (сказал же, что схематично!) забудь про Си, это ассемблерный харкор из 80-х, где Petrovich(149 знак., 10.11.2017 13:20, )
- Схематично - это вот так: 1) Берём МК с таймером 2) ... 3) Профит! - SciFi(10.11.2017 13:04)
- Таймера у читающих даташиты считываются еще проще - при корректном чтении первой половины таймера (в ДШ написано, какую именно половину следует читать первой) содержимое второй половины аппаратно защелкивается в теневой регистр, из которого MBedder(38 знак., 10.11.2017 13:02)
- Увы, это не всегда помогает. У pic18 есть теневой регистр, но... для нормальной работы пришлось городить такую конструкцию: аппаратный таймер 16 бит, или даже 12, тут не помню, по прерыванию инкрементится ещё слово (16 бит) программной части fk0(1081 знак., 10.11.2017 13:12)
- 8051 просит разъяснить поподробнее о теневом регистре :) - Petrovich(10.11.2017 13:06, )
- Ты написал тему про АВР - я разъяснил про АВР, а про 8051 чЕтай сам - MBedder(10.11.2017 14:26)
- Тяжёлое детство, деревянные игрушки, отсутствие теневого регистра. У меня, кстати, на столе лежит штука, в которой интересный регистр разбит на половинки, и именно вот эта петрушка. Выкинуть на помойку не предлагать. - SciFi(10.11.2017 13:06)
- У тебя три загрузки таймера в цикле, а у меня два. И положение байт в структуре -- не гарантировано. - fk0(10.11.2017 13:04)
- Таймера считываются проще Petrovich(145 знак., 10.11.2017 12:57, )
- Если читаешь достаточно быстрый аппаратный таймер -- он никогда не совпадет. Младшая половина всегда убегает вперед, а старшая за несколько чтений не успевает измениться. См. мой ответ ниже. - fk0(10.11.2017 11:46)
- Нафиг общий случай? Пару раз такое нужно было, всё было просто. Чтение переменной, которая меняется достаточно редко: SciFi(190 знак., 10.11.2017 11:36)
- часто при чтении пару раз подряд совпасть должно - Vit(10.11.2017 11:40)
- Не всегда в общем случае. Как понять критерий нужности? - fk0(10.11.2017 11:31)
- В таких случаях можно читать несколько раз, пока не прочитаешь то, что нужно. - SciFi(10.11.2017 07:31)
- Да я думал неинтересно народу... Надеюсь, вы поняли откуда появляется ошибка. Это, оказывается, всего лишь ошибка наблюдателя. Выход - проверять в обратной поледовательности чем инкремент, т.е. if(tail>head) {out ERROR;} и будет хорошо. Petrovich(866 знак., 09.11.2017 12:33, )
- В выражении tail > head последовательность чтения переменных в общем случае не совсем определена, если они не volatile (для последних порядок сохраняется, но только относительно самих этих переменных, а не других переменных, памяти адресуемой по fk0(437 знак., 09.11.2017 23:53)
- Тогда уж дал бы ссылку на оригинал, а то сам переврал половину и выкинул существенные подробности. Вообще да, товарищ любопытно проиллюстрировал проблему. Это я не про поло, а про пример кода. - SciFi(09.11.2017 12:44, ссылка)
- Где и чего переврато? И какие существенные подробности опущены? Как раз адаптировано под потенциальные проблемы работы с буфером, что мне лично актуально и про что я объявил. - Petrovich(09.11.2017 12:49, )
- Есличо, порядок чтения переменных в выражении "if(tail>head)" не определён. Поэтому и нужны локальные переменные, как в оригинале. - SciFi(09.11.2017 12:59)
- Локальные? А что они дадут кроме надежды, что оптимизатор их не выкинет? - Мутон(10.11.2017 07:58, )
- Читайте мануалы. Они дают гарантированный порядок чтения переменных. Когда они volatile, компилятор не нарушит этот порядок. SciFi(251 знак., 10.11.2017 08:19)
- Перестаньте додумывать про volatile! Где они? У автора это просто переменные. - Мутон(10.11.2017 08:28, )
- Очевидно, автор иллюстрировал концепцию, не слишком погружаясь в детали. Конечно, зануда написал бы вот так: SciFi(423 знак., 10.11.2017 08:31 - 08:35)
- Тогдатк чему все жто? Именно про схематичность постановки и решения указывал и ТС. Для алгоритма не важно волатильность или локальность, важно что эта проблема и для Кортексов и для 8080. - Мутон(10.11.2017 08:37, )
- Ну да. Аффтару нужно было писАть на псевдоезыке, тогда и повода для срача не было бы. - SciFi(10.11.2017 08:44)
- Тогдатк чему все жто? Именно про схематичность постановки и решения указывал и ТС. Для алгоритма не важно волатильность или локальность, важно что эта проблема и для Кортексов и для 8080. - Мутон(10.11.2017 08:37, )
- Очевидно, автор иллюстрировал концепцию, не слишком погружаясь в детали. Конечно, зануда написал бы вот так: SciFi(423 знак., 10.11.2017 08:31 - 08:35)
- Перестаньте додумывать про volatile! Где они? У автора это просто переменные. - Мутон(10.11.2017 08:28, )
- Читайте мануалы. Они дают гарантированный порядок чтения переменных. Когда они volatile, компилятор не нарушит этот порядок. SciFi(251 знак., 10.11.2017 08:19)
- На самом деле определён, слева направо же. Но у него переменные не volatile, поэтому переставляет, видимо. - fk0(09.11.2017 23:56)
- С этого места поподробнее! Где это написано? Правильно, нигде. И даже написано, что не определён. SciFi(224 знак., 10.11.2017 07:30 - 08:27)
- +1 - Vit(09.11.2017 13:38)
- Для понимания потенциальной проблемы сие неважно, это же функциональная схема а не готовая программа. Может, применить две локальные копии, может - одну переменную и геттер... - Petrovich(09.11.2017 13:17, )
- Локальные? А что они дадут кроме надежды, что оптимизатор их не выкинет? - Мутон(10.11.2017 07:58, )
- Есличо, порядок чтения переменных в выражении "if(tail>head)" не определён. Поэтому и нужны локальные переменные, как в оригинале. - SciFi(09.11.2017 12:59)
- Где и чего переврато? И какие существенные подробности опущены? Как раз адаптировано под потенциальные проблемы работы с буфером, что мне лично актуально и про что я объявил. - Petrovich(09.11.2017 12:49, )
- Только как понять, выкрутился или нет? - VLLV(09.11.2017 12:18)
- На 8-битном процессоре чтение и запись не атомарные -- не выкрутишься. Старший байт записал например, обновленный, а младший не успел. А другой поток читать начал. И ошибка. - fk0(09.11.2017 23:41)
- Появились 1. Новые методы запрета прерываний "на время" 2. Атомарные операции инкремента/декремента/и других модификаций ячейки памяти. - AlexBi(09.11.2017 11:51)
- 1. невозможно использовать практически. я тут писал, как для pic24 выкрутился. 2. это обычно только у больших ARM и MIPS. - fk0(10.11.2017 00:02, ссылка)
- Где та грань, за которой это нужно применять? Критичность потери быстродействия за счет лишних EI/DI? - VLLV(09.11.2017 12:20)
- Может возникнуть критичность не быстродействия вообще, а времени реакции на прерывание. - AlexBi(09.11.2017 14:55)