Сравнение и замена 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. Я догадываюсь о значении параметров, учитывая, что документация очень тусклая.


person Maria    schedule 20.08.2015    source источник


Ответы (1)


В итоге я нашел решение самостоятельно, используя вариант 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 */);
}
person Maria    schedule 20.08.2015