2015-08-20 4 views
3

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

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

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

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

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

Я нашел дополнительную документацию о инструкциях cmpxchg и cmpxchg8 (а также tzcnt и lzcnt, которые являются хорошими, но не обязательно) here. Если вы просматриваете в 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

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

ответ

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 */); 
} 
Смежные вопросы