What is atomic_fetch_add in C?
atomic_fetch_add() is a built-in function defined in the <stdatomic.h> header. It is included in the C11 version of C.
The following is the function prototype:
C atomic_fetch_add(volatile A* obj, M arg);
Functionality
We use atomic_fetch_add() to atomically replace the value pointed to by obj. The function does this by adding arg to the previous value of obj.
Atomic value types only allow reading and writing of variables in a single instruction. This avoids the possibility of multiple threads accessing shared variables in parallel.
Parameters and return
The atomic_fetch_add() function takes the following input arguments:
-
obj: pointer to the atomic object to be updated -
arg: value to be added to the old value ofobj
The function returns the value previously held by obj.
volatileis a type qualifier which assures that access to the variable is atomic.Arepresents allatomic object types. Only allow reading and writing of variables in a single instruction. Mrepresents the non-atomic type corresponding toA.
Code
#include <stdio.h>#include <threads.h>#include <stdatomic.h>//Declaring global variables to//be shared betweeen threadsatomic_int atomic_count = 0; //atomic variableint non_atomic_count = 0; //non-atomic variableint func(void* input){for(int n = 0; n < 1000; ++n) {atomic_fetch_add(&atomic_count, 1); // atomic updation++non_atomic_count; // non-atomic updation}return 0;}int main(void){thrd_t threads[10];for(int i = 0; i < 10; i++)thrd_create(&threads[i], func, NULL);for(int i = 0; i < 10; i++)thrd_join(threads[i], NULL);printf("The atomic counter is: %d\n", atomic_count);printf("The non-atomic counter is: %d\n", non_atomic_count);}
We begin by declaring two counters, one basic and the other atomic. Both counters are initialized to zero.
In our thread function – func() – we update both counters by 1. We update the atomic counter using atomic_fetch_add().
Finally, we create 10 threads. Each thread should ideally increase the value of the counters by 1000.
Output
The atomic counter is: 10000
The non-atomic counter is: 4875
Next, we set the atomic counter to exactly 10000. This is because each thread accesses the atomic counter in turn and not in parallel.
However, we set the non-atomic variable to an unexpected value due to parallel access by all threads. This causes data to lose its integrity.
Free Resources