atomic_fetch_add, atomic_fetch_add_explicit
|
Défini dans l'en-tête
<stdatomic.h>
|
||
|
C atomic_fetch_add
(
volatile
A
*
obj, M arg
)
;
|
(1) | (depuis C11) |
|
C atomic_fetch_add_explicit
(
volatile
A
*
obj, M arg,
memory_order
order
)
;
|
(2) | (depuis C11) |
Remplace atomiquement la valeur pointée par
obj
par le résultat de l'addition de
arg
à l'ancienne valeur de
obj
, et retourne la valeur que
obj
contenait précédemment. L'opération est une opération de lecture-modification-écriture. La première version ordonne les accès mémoire selon
memory_order_seq_cst
, la deuxième version ordonne les accès mémoire selon
order
.
Ceci est une
fonction générique
définie pour tous les
types d'objets atomiques
A
. L'argument est un pointeur vers un type atomique volatile pour accepter les adresses des objets atomiques non volatiles et
volatiles
(par exemple les E/S mappées en mémoire), et la sémantique volatile est préservée lors de l'application de cette opération aux objets atomiques volatiles.
M
est soit le type non atomique correspondant à
A
si
A
est un type entier atomique, soit
ptrdiff_t
si
A
est un type pointeur atomique.
Il n'est pas spécifié si le nom d'une fonction générique est une macro ou un identifiant déclaré avec liaison externe. Si une définition de macro est supprimée pour accéder à une fonction réelle (par exemple mise entre parenthèses comme ( atomic_fetch_add ) ( ... ) ), ou si un programme définit un identifiant externe portant le nom d'une fonction générique, le comportement est indéfini.
Pour les types entiers signés, l'arithmétique est définie pour utiliser la représentation en complément à deux. Il n'y a pas de résultats non définis. Pour les types pointeurs, le résultat peut être une adresse non définie, mais les opérations n'ont par ailleurs aucun comportement non défini.
Table des matières |
Paramètres
| obj | - | pointeur vers l'objet atomique à modifier |
| arg | - | valeur à ajouter à la valeur stockée dans l'objet atomique |
| order | - | ordonnancement de synchronisation mémoire pour cette opération : toutes les valeurs sont autorisées |
Valeur de retour
La valeur précédemment détenue par l'objet atomique pointé par
obj
.
Exemple
#include <stdio.h> #include <threads.h> #include <stdatomic.h> atomic_int acnt; int cnt; int f(void* thr_data) { for(int n = 0; n < 1000; ++n) { atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed); // atomique ++cnt; // comportement indéfini, en pratique certaines mises à jour sont perdues } return 0; } int main(void) { thrd_t thr[10]; for(int n = 0; n < 10; ++n) thrd_create(&thr[n], f, NULL); for(int n = 0; n < 10; ++n) thrd_join(thr[n], NULL); printf("The atomic counter is %u\n", acnt); printf("The non-atomic counter is %u\n", cnt); }
Sortie possible :
The atomic counter is 10000 The non-atomic counter is 9511
Références
- Norme C17 (ISO/CEI 9899:2018) :
-
- 7.17.7.5 Les fonctions génériques atomic_fetch et modify (p: 208)
- Norme C11 (ISO/CEI 9899:2011) :
-
- 7.17.7.5 Les fonctions génériques atomic_fetch et modify (p: 284-285)
Voir aussi
|
soustraction atomique
(fonction) |
|
|
Documentation C++
pour
atomic_fetch_add
,
atomic_fetch_add_explicit
|
|