как реализовать атомарное присваивание в AIX / powerpc?

Я портирую расширение ядра на 32/64 бит AIX на многопроцессорном PowerPC, написанном на C. Мне не нужно ничего, кроме операции атомарного чтения и операций атомарной записи (мне не нужны операции выборки и добавления, сравнение -and-swap и т. д.) Чтобы уточнить: для меня «атомарность» означает не только «отсутствие чередования», но также «видимость по нескольким ядрам». Операции работают с указателями, поэтому операции с переменными int для меня бесполезны.

Если я объявляю переменную «изменчивой», стандарт C говорит, что переменная может быть изменена неизвестными факторами и, следовательно, не подлежит оптимизации.

Из того, что я читал, кажется, что обычные операции чтения и записи не должны чередоваться, а источники ядра Linux, похоже, согласны. он говорит:

__asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i));

stw - это «слово для хранения», которое предположительно является атомарным, но я не знаю, что означает «% U0% X0». Не понимаю, как эта инструкция по сборке навязывает наглядность. Когда я компилирую расширение ядра, 'std' используется для назначения, которое я хочу, но оно также должно быть атомарным для 64-битной машины, судя по тому, что я читал. У меня очень мало понимания специфики PowerPC и его набора команд, однако я не нашел в листинге сборки скомпилированного файла никаких инструкций по ограничению памяти («синхронизация» или «eieio»).

Ядро предоставляет службу fetch_and_addlp (), которую можно использовать для реализации атомарного чтения (например, v = fetch_and_addlp(&x, 0)).

Итак, мои вопросы:

  1. Достаточно ли объявить переменную volatile для достижения атомарности чтения и записи в смысле видимости и отсутствия чередования?

  2. если ответ на 1 - «нет», как достигается такая атомарность?

  3. что означает "% U0% X0" в атомарной реализации Linux PowerPC?


person Idan K    schedule 06.07.2011    source источник
comment
Атомарный смысл не в этом! Если вам нужны гарантии заказа, используйте барьер памяти. (Или просто используйте замок, потому что, очевидно, все неправильно ставят барьеры.)   -  person tc.    schedule 04.10.2011
comment
@tc: К сожалению, в сообществе разработчиков микропроцессоров нет единого мнения о значении слова атомарный. Когда я определял архитектуру упорядочения памяти Intel x86 примерно в 1991 году, я использовал определение, которое использует tc - атомарный, относящийся к тому, что операция выполняется или не выполняется вообще, никогда не выполняется наполовину, а упорядочение памяти - это совсем другое. В ARM, однако, в последнее время атомарность используется для обозначения упорядочения памяти, атомарность с одним расположением - для того, что мы с tc называем просто атомарным, и атомарность с несколькими местоположениями или атомарность записи для обозначения свойств упорядочения памяти в системе.   -  person Krazy Glew    schedule 15.03.2017


Ответы (2)


Синтаксис встроенного ассемблера GCC имеет свои особенности.

в соответствии,

__asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i));

m - это выходной операнд, а r - входной операнд. % 1 и% 0 относятся к порядку аргументов (0-> m, 1-> r)

инструкция сборки stw принимает 2 аргумента, а% U0% X0 являются ограничениями для аргументов. Эти ограничения должны заставить GCC проанализировать аргументы и убедиться, что вы не делаете глупостей. Как оказалось, `U 'зависит от powerpc (я привык к набору ограничений X64 :). Полный список ограничений можно найти в:

http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints

person Foo Bah    schedule 25.08.2011

Мне удалось ответить на вопросы 1 и 2, но не на 3:

  1. Нет, этого мало.
  2. Барьеры памяти по-прежнему необходимы. Я использовал XLC, встроенный в __lwsync (). Это должно предотвратить переупорядочивание процессором и опубликовать изменение для других процессоров.
person Idan K    schedule 27.07.2011