Мой опыт (не в ядре Linux) показывает, что два шаблона покрывают подавляющее большинство потребностей в ограждении.
Шаблон «Отправка / получение»: поток 1 отправляет данные потоку 2, и есть место в памяти, которое каким-то образом указывает, что «данные готовы». Потоку 1 необходимо, по крайней мере, зазор между хранилищем данных и хранилищем «данные готовы». Поток 2 нуждается в разнице между загрузкой данных, в которых говорится, что «данные готовы», и загрузкой данных.
Если в передаче участвуют только обычные (НЕ вневременные, устройства DMA и т. Д.) Загрузка / сохранение, тогда необходимы только ограждения компилятора. Кроме того, инструкции с префиксом LOCK подразумевают ограждения. Например, иногда место «данные готовы» - это не просто флаг, а атомарный счетчик, и приращение / декремент с префиксом LOCK, используемое для управления им, может служить в качестве ограждения.
Этот шаблон также распространяется на спиновые замки. Снятие блокировки - это «отправка». Получение блокировки - это «получить.
Шаблон «Консенсус»: две темы должны прийти к согласию по поводу чего-либо. Должна быть граница (или подразумеваемая инструкцией с префиксом LOCK). Ограждение должно быть между фразами «Я опубликовал свой голос» и «Я прочитал голосование в другой ветке». Примером может служить протокол Деккера. Сложнее всего определить эту закономерность. Однажды мы упустили один из моментов во внутреннем устройстве TBB, где проблема консенсуса заключалась в том, "было ли создано исключение?" В конце концов мы поняли, что это проблема консенсуса и, следовательно, нужна защита.
Два приведенных выше шаблона - это практические правила, которые не охватывают все случаи, но я считаю, что они охватывают 99% случаев.
person
Arch D. Robison
schedule
09.12.2013