Created
October 11, 2014 12:55
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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