Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags

c

What is atomic_fetch_add in C?

Khizar Hayat Saani

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.

The atomic_fetch_add() function

Parameters and return

The atomic_fetch_add() function takes the following input arguments:

  1. obj: pointer to the atomic object to be updated

  2. arg: value to be added to the old value of obj

The function returns the value previously held by obj.

volatile is a type qualifier which assures that access to the variable is atomic. A represents all atomic object types.Only allow reading and writing of variables in a single instruction. M represents the non-atomic type corresponding to A.

Code

#include <stdio.h>
#include <threads.h>
#include <stdatomic.h>

//Declaring global variables to
//be shared betweeen threads
 
atomic_int atomic_count = 0;	//atomic variable
int non_atomic_count = 0;			//non-atomic variable
 
int 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);
}
atomic_fetch_add() example

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.

RELATED TAGS

c

CONTRIBUTOR

Khizar Hayat Saani
Copyright ©2022 Educative, Inc. All rights reserved
RELATED COURSES

View all Courses

Keep Exploring