2017-09-15 2 views
0

Le gcc-intégré opération atomique: http://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.htmlComment mettre en œuvre une opération atomique?

je besoin d'une opération atomique : Un ajouter opration avec CAS. Il est un peu comme la gcc fonction intégrée __atomic_compare_exchange_n, mais différent:

  1. le prototype de fonction comme ceci: bool atomic_compare_add(int &ptr, int &expected, int val)

  2. la fonction exécuter atomicly: if (ptr != expected) { ptr = ptr + val; return true; } else { return false; }

La fonction que je veux est différent de __atomic_compare_exchange_n et __atomic_add_fetch, __atomic_comp are_exchange_n signifie if (*ptr == *expected) { *ptr = desire; return true; } else { return false; } et __atomic_add_fetch signifie *ptr = *ptr + val; return *ptr;.

Comment implémenter cette opération sous Linux gcc/g ++?

+0

La STL pourrait résoudre votre problème indépendant de la compilder: http://en.cppreference.com/w/cpp/atomic/atomic – OutOfBound

+0

Le Le lien que vous avez posté décrit '__atomic_add_fetch' littéralement 10 lignes après' __atomic_compare_exchange_n', ce qui semble faire ce que vous voulez. – Frank

+0

Pensez à changer votre logique pour un 'if (ptr == expected) plus commun {ptr = ptr + value; } else {ne rien faire} 'et utilise [' atomic :: compare_exchange'] (http://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange) – rustyx

Répondre

0

Merci à tous, j'ai une solution:

bool atomic_compare_add(int *ptr, int not_expected, int val) { 
    int old_val; 
    do { 
     old_val = __atomic_load_n(ptr, __ATOMIC_CONSUME); 
     if (old_val == not_expected) { 
      return false; 
     } 
    } while (!__atomic_compare_exchange_n(ptr, &old_val, old_val + val, true, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)); 
    return true; 
}