Atomic variables in Linux

Consider the following program below, try to guess why the output is not 1,00,000

Code:


Output:



The reason behind it is giving different values each time is SMP Machine. In a multi processor system, global++ will be converted to global = global + 1.

Steps to increment the value of global by 1:

1. Processor reads the value of global
2. Processor increments the value in memory
3. Processor writes the new value to global

Let's take the example of global value is 5, and there are two processors in system , Processor 1 and Processor 2.

  • Processor 1 reads the value of global and it is 5.
  • Processor 1 increments the value in memory and make it 6
  • Processor 2 acquires the bus and reads the value of global and it will be 5
  • Processor 2 increments the value in memory and make it 6
  • Processor 1 comes and then writes 6 to global variable
  • Processor 2 comes and then writes 6 to global variable.
How to solve this problem?

The simultaneous access problem can be avoided by using synchronization techniques such as semaphores and spinlocks. But using spinlocks/semaphores for a single instruction is over kill.

Linux provides another solution to this problem: Atomic variables.

Read Modify operation on atomic variables will be performed as one instruction without any interruption. 

Kernel provides atomic_t data type for atomic operations. 

E.g. atomic_t *lock;

To modify and read the values, we need to use the below functions defined in <asm/atomic.h>


atomic_set(val,i) :  Sets *val to i
atomic_read(val): Returns the value of *val
atomic_inc(val) : Adds 1 to *val
atomic_dec(val) :  Subtracts 1 from *val
atomic_add(i,val):    adds i to *val
atomic_sub(i,val):  Subtracts i from *val
atomic_sub_and_test(i, val) : Subtracts i from *val and returns 1 if the result is zero
atomic_dec_and_test(val): Subtracts 1 from *val and returns 1 if the result is zero, otherwise it returns 0
atomic_inc_and_test(val): Adds 1 to *v and returns 1 if the result is zero; 0 otherwise

Example Module:




Output:




Comments

Popular posts from this blog

bb.utils.contains yocto

Difference between RDEPENDS and DEPENDS in Yocto

make config vs oldconfig vs defconfig vs menuconfig vs savedefconfig