Я портирую расширение ядра на 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)
).
Итак, мои вопросы:
Достаточно ли объявить переменную volatile для достижения атомарности чтения и записи в смысле видимости и отсутствия чередования?
если ответ на 1 - «нет», как достигается такая атомарность?
что означает "% U0% X0" в атомарной реализации Linux PowerPC?