comparaison atomique (différente) et échange

Je souhaite utiliser la comparaison et l’échange swap, mais au lieu d’être égal à, je ne souhaite permuter que si l’emplacement mémoire n’est pas égal à l’ancienne valeur. Est-ce possible en C?

Que dis-tu de ça:

void compare_and_swap_if_not_equal(word_t const required_non_value, word_t const new_value, word_t* ptr_to_shared_variable) { for (;;) { word_t const snapshot_value = *ptr_to_shared_variable; if (required_non_value == snapshot_value) { break; // or (sleep and) 'continue;', if you want to wait for the stored value to be different // -- but you might of course miss a transient change to a different state and back. } else { if (compare_and_swap_if_equal(ptr_to_shared_variable, snapshot_value, new_value)) { // we know the stored value was different; if this 'theory' still matches reality: swap! done! break; } } } } 

Non testé. Non compilé. Le ‘const’ utilisé parce que j’aime bien ça :). ‘word_t’ est un espace réservé de type, je ne sais pas ce que devrait être le type réel. Et je ne sais pas comment s’appelle ‘compare_and_swap_if_equal’ dans stdatomic.h.

(ajouté) atomic_compare_exchange_weak () est le ticket. Pour une raison quelconque, il faut un pointeur sur l’argument ‘attendu’, vous devrez donc modifier le code ci-dessus pour

if (atomic_compare_exchange_weak (ptr_to_shared_variable, & snapshot_value, new_value)) …

La version “faible” devrait fonctionner dans le code ci-dessus; si vous retournez ‘faux’ de façon fausse, cela ne fera qu’append un autre tour à la boucle. Toujours non compilé, non testé; ne comptez pas sur ce code à la maison.

Cela dépend de votre architecture, mais en général, il n’est pas possible de faire cela en C.

En règle générale, la comparaison et l’échange sont implémentés avec une instruction qui charge de manière atomique à partir d’un emplacement en mémoire et stocke une valeur à cet emplacement si l’emplacement en mémoire correspond à une valeur existante que vous spécifiez.

Au moins sur x86, aucune disposition ne permet de ne faire cette charge que si les valeurs ne correspondent pas. En outre, il n’est pas clair pourquoi vous voudriez faire quelque chose comme ça. Une autre architecture pourrait peut-être prendre en charge quelque chose comme cela, mais cela dépendrait de l’architecture et non de quelque chose qui pourrait être fait en C de manière portable.