HP-UX Itanium для сравнения и замены

Я занимаюсь разработкой кроссплатформенного кода на C / C ++, и последняя платформа — HP-UX на базе Itanium. Соответствующая машина с информацией о процессоре может быть найдена в конце вопроса.

Мне нужно реализовать или найти атомарное сравнение и обмен для спецификаций машины и компилятора, приведенных ниже.

Я нашел несколько возможностей для решения, но не смог найти, как их использовать.

Первое возможное решение заключается в использовании _Asm_cmpxchg (документация здесь). Я не могу найти заголовок для этого или как его скомпилировать.

Второе возможное решение — написать собственную встроенную сборку с непосредственным использованием команд cmpxchg и cmpxchg8b, но я также не смог найти, как правильно это сделать. Я нашел различные ресурсы, большинство из которых пишут непосредственно на ассемблере, а не для архитектуры процессора, которая мне нужна, или не показывают достаточно конкретного примера.

Я нашел больше документации об инструкциях cmpxchg и cmpxchg8 (а также о tzcnt и lzcnt, которые приятно иметь, но не нужно) Вот. Если вы просматриваете в Google Chrome, значения страницы abosulte составляют 234 для cmpxchg и 236 для cmpxchg8.

Ограничения: Я не могу использовать стороннюю библиотеку из-за не зависящих от меня ограничений.

Результат uname -smr: HP-UX B.11.31 ia64

Модель процессора: Процессор Intel (R) Itanium (R) 9340

Компилятор -v: aCC: HP C / aC ++ B3910B A.06.28

Обновить: Мне удалось получить _Asm_cmpxchg для компиляции, но это не похоже на работу (значение остается неизменным). Для параметров я передал _SZ_W для _Asm_sz, _SEM_ACQ для _Asm_sem, _LDHINT_NONE для _Asm_ldhint, указатель на исходное 32-разрядное целочисленное значение для r3 и требуемое новое значение для r2. Я предполагаю значение параметров, учитывая, что документация очень тусклая.

3

Решение

В итоге я нашел решение самостоятельно, используя опцию 1. Ниже приведен пример кода, чтобы заставить его работать:

bool compare_and_swap(unsigned int* var, unsigned int oldval, unsigned int newval)
{
// Move the old value into register _AREG_CCV because this is the register
// that var will be compared against
_Asm_mov_to_ar(_AREG_CCV, oldval);
// Do the compare and swap
return oldval == _Asm_cmpxchg(
_SZ_W /* 4 byte word */,
_SEM_ACQ /* acquire the semaphore */,
var,
newval,
_LDHINT_NONE /* locality hint */);
}
1

Другие решения


По вопросам рекламы [email protected]