2009-05-02 1 views
10

Я знаю о встроенных атомных операциях GCC: http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Atomic-Builtins.htmlЛучший способ реализовать общую атомную нагрузку или хранить в GCC?

Но этот список не включает в себя очень простые операции, такие как загрузка и хранение. Я мог бы реализовать их на ограниченных архитектур с инлайн сборки (на самом деле для многих, как x86 они будут в основном только регулярные мов), но не существует лучшего способа, в общем случае, чем-то вроде этого:

// returns the value at ptr 
void *atomic_load_ptr(void **ptr) 
{ 
    return __sync_fetch_and_add(ptr, 0); 
} 

// returns old value int ptr after setting it to newval 
void *atomic_store_ptr(void **ptr, void *newval) 
{ 
    void *oldval = atomic_load_ptr(ptr) 
    void *oldval2; 
    do { 
     oldval2 = oldval; 
    } while ((oldval = __sync_val_compare_and_swap(ptr, oldval, newval)) != oldval2); 
    return oldval; 
} 
+0

Остановите меня, если я ошибаюсь, но ваша функция «магазина» на самом деле не является магазином, так как возвращает старое значение (поэтому оно очень близко к CAS). – claf

+0

Его действительно «обмен» - сохранение нового значения и возврат предыдущего значения, если вы этого хотите. –

+0

Я обнаружил, что эта реализация загрузки имеет проблему: она не может использоваться в постоянной памяти. – Mabus

ответ

2

Вы могли бы реализовать мьютексы низкого уровня с помощью test_and_set. Функция загрузки является хорошим имо, но вы сохраняете функцию следует использовать test_and_set вместо того, чтобы

while ((oldval = __sync_val_compare_and_swap(ptr, oldval, newval)) != oldval2); 

для предотвращения ошибок.

Смежные вопросы