2013-08-23 3 views
2

Я читал газету "Simple, fast, and practical non-blocking and blocking concurrent queue algorithms", и я понял, что они предполагают, что компьютер выполняет следующий псевдокод атомарен:Как реализовать двойное сравнение и обмен в C/Linux?

CAS(Q->Tail,tail,<next.ptr,next.count+1>) 

Где Q-> Хвост и хвост указатель и экземпляр структуры, содержащий указатель и счетчик.

Я знаю, что gcc предоставляет пару встроенных модулей для сравнения и обмена одним словом в c. Однако возможно ли реализовать неблокирующий атомный двойной сопоставление и обмен из одного сравнения и свопинга в c (с использованием Linux)? Является ли это правильным подходом к реализации псевдокода ссылочной бумаги?

+0

Поскольку я не собираюсь покупать бумагу, что такое 'Tail'? Это действительно указатель в сочетании со счетчиком? – jxh

ответ

0

Я не знаю никаких операций CAS, которые работают в двух разных местах памяти. Однако, возможно, бумага использует структуру для указателя и счетчика в качестве обходного пути для обработки обоих полей как более крупного типа и, следовательно, изменения как атомарно.

Предполагая, что у вас есть структура из двух полей, указатель и счетчик: размер указателя 4 байта, размер счетчика 4 байта; правильно выровнен без заполнения до размера структуры 8 байтов. Предполагая, что у вас также есть операция CAS, которая обрабатывает значения 8 байтов (например, указатель на 64-разрядное целое число). Вы можете подготовить значения struct отдельно и использовать операцию CAS для структуры в целом, чтобы сразу изменить два значения.

+0

Примечание: Я не читал газету, просто угадывая. Я мог ошибаться или могли быть другие способы, о которых я не знаю. – Ioan

+1

DCAS работает на двух разных операндах, но довольно редок. DWCAS (doublewide) работает с двумя соседними значениями и эквивалентен тому, что вы делаете с CAS, достаточно широким, чтобы удерживать два меньших значения. – rsaxvc

0

Gcc также предоставляет встроенные модули для двойного слова CAS, вы можете использовать __sync_bool_compare_and_swap, если SizeOf (* Q-> Tail) == SizeOf (хвост) == SizeOf (third_arg) == 8. Так что все работы штраф, если вы можете увеличить «next.count» перед выполнением CAS.