Skip to content

Instantly share code, notes, and snippets.

@aperezdc
Created October 11, 2014 12:55
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save aperezdc/b0000f8ef5920bba0d56 to your computer and use it in GitHub Desktop.
Save aperezdc/b0000f8ef5920bba0d56 to your computer and use it in GitHub Desktop.
Replacement for the Linux kernel asm/atomic.h header using GCC built-ins
#ifndef _ATOMIC_H
#define _ATOMIC_H
/* Check GCC version, just to be safe */
#if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC_MINOR__ < 1)
# error atomic.h works only with GCC newer than version 4.1
#endif /* GNUC >= 4.1 */
/**
* Atomic type.
*/
typedef struct {
volatile int counter;
} atomic_t;
#define ATOMIC_INIT(i) { (i) }
/**
* Read atomic variable
* @param v pointer of type atomic_t
*
* Atomically reads the value of @v.
*/
#define atomic_read(v) ((v)->counter)
/**
* Set atomic variable
* @param v pointer of type atomic_t
* @param i required value
*/
#define atomic_set(v,i) (((v)->counter) = (i))
/**
* Add to the atomic variable
* @param i integer value to add
* @param v pointer of type atomic_t
*/
static inline void atomic_add( int i, atomic_t *v )
{
(void)__sync_add_and_fetch(&v->counter, i);
}
/**
* Subtract the atomic variable
* @param i integer value to subtract
* @param v pointer of type atomic_t
*
* Atomically subtracts @i from @v.
*/
static inline void atomic_sub( int i, atomic_t *v )
{
(void)__sync_sub_and_fetch(&v->counter, i);
}
/**
* Subtract value from variable and test result
* @param i integer value to subtract
* @param v pointer of type atomic_t
*
* Atomically subtracts @i from @v and returns
* true if the result is zero, or false for all
* other cases.
*/
static inline int atomic_sub_and_test( int i, atomic_t *v )
{
return !(__sync_sub_and_fetch(&v->counter, i));
}
/**
* Increment atomic variable
* @param v pointer of type atomic_t
*
* Atomically increments @v by 1.
*/
static inline void atomic_inc( atomic_t *v )
{
(void)__sync_fetch_and_add(&v->counter, 1);
}
/**
* @brief decrement atomic variable
* @param v: pointer of type atomic_t
*
* Atomically decrements @v by 1. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
static inline void atomic_dec( atomic_t *v )
{
(void)__sync_fetch_and_sub(&v->counter, 1);
}
/**
* @brief Decrement and test
* @param v pointer of type atomic_t
*
* Atomically decrements @v by 1 and
* returns true if the result is 0, or false for all other
* cases.
*/
static inline int atomic_dec_and_test( atomic_t *v )
{
return !(__sync_sub_and_fetch(&v->counter, 1));
}
/**
* @brief Increment and test
* @param v pointer of type atomic_t
*
* Atomically increments @v by 1
* and returns true if the result is zero, or false for all
* other cases.
*/
static inline int atomic_inc_and_test( atomic_t *v )
{
return !(__sync_add_and_fetch(&v->counter, 1));
}
/**
* @brief add and test if negative
* @param v pointer of type atomic_t
* @param i integer value to add
*
* Atomically adds @i to @v and returns true
* if the result is negative, or false when
* result is greater than or equal to zero.
*/
static inline int atomic_add_negative( int i, atomic_t *v )
{
return (__sync_add_and_fetch(&v->counter, i) < 0);
}
#endif
@aperezdc
Copy link
Author

@raminfp
Copy link

raminfp commented Mar 19, 2017

//Author : Ramin Farajpour Cami
// atomic example


#include "atomic.h"
#include <stdio.h>


int main(){

	atomic_t v;                  
	atomic_t u = ATOMIC_INIT(0);     

	printf("%d\n",atomic_set(&v, 4));    

	atomic_add(2, &v);     
	atomic_inc(&v);        

	printf("%d\n",v);

	return 0;
}

Thanks @aperezdc,

@nathasion
Copy link

Hi
I am running MISRA rules on my code and it is complaining about __sync_add_and_fetch having implicit declaration.
Did not figure out what prototypes I need to add.
I tried
int __sync_add_and_fetch (volatile int *ptr, int value);
but it gives me following error: conflicting types for built-in function ‘__sync_add_and_fetch’

thank you for help
Nath

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment