Эта страница неправильная . Кажется, утверждается, что атомарные операции без блокировки являются привилегированными для ISA в целом, но это не так. Я никогда не слышал о том, чтобы для атомарного тестирования и установки или любой другой операции без блокировки требовался режим ядра.
Если бы это было так, для компиляции с системными вызовами потребовались бы C ++ 11 не блокируемые атомарные операции чтения-изменения-записи , но они не выполняются на x86, ARM, AArch64, MIPS, PowerPC или любой другой обычный процессор. (попробуйте на https://godbolt.org/).
Это также сделало бы невозможной «легкую» блокировку (которая пытается снять блокировку без системного вызова). (http://preshing.com/20111124/always-use-a-lightweight-mutex/)
Обычные ISA позволяют пользовательскому пространству выполнять элементарные операции RMW, в памяти, разделяемой между потоками или даже между отдельными процессами. Мне не известен механизм отключения атомарного RMW для пользовательского пространства на x86 , Даже если на любой ISA есть такая вещь, это не нормальный режим работы.
Доступ только для чтения или только для записи обычно является атомарным в выровненных местоположениях на всех ISA, вплоть до определенной ширины ( Почему целочисленное присваивание для естественно выровненной переменной атомарно в x86? ), но Atomic RMW нуждается в аппаратной поддержке.
На x86 TAS равен lock bts
, что непривилегировано. ( Документация для префикса lock
). В x86 есть широкий выбор других атомарных операций, таких как lock add [mem], reg/immediate
, lock cmpxchg [mem], reg
и даже lock xadd [mem], reg
, которые реализуют fetch_add
, когда требуется возвращаемое значение. ( Может ли num ++ быть атомарным для 'int num'? )
Большинство RISC имеют LL / SC, включая ARM, MIPS и PowerPC, а также все старые более не распространенные ISA RISC.
futex(2)
- системный вызов. Если вы его называете, все, что он делает, находится в режиме ядра.
Это резервный механизм, используемый легковесной блокировкой в случае, если является конфликтом , который обеспечивает сон / пробуждение с помощью ОС. Таким образом, не futex
сам что-то делает в пользовательском пространстве, а блокировка реализаций, построенных вокруг futex
, может избежать системных вызовов в случае непреднамеренного или низкого уровня конкуренции.
(например, вращаться в пространстве пользователя несколько раз, если блокировка становится доступной.)
Это то, что описывает справочная страница futex(7)
. Но я нахожу немного странным называть это «операцией futex», если вы на самом деле не делаете системный вызов. Я предполагаю, что он работает с памятью, которую код ядра может просматривать от имени других ожидающих потоков, поэтому необходимая семантика для изменения областей памяти в коде пользовательского пространства зависит от futex
.