r6.1.0:lfds610_abstraction_increment

From liblfds.org
Jump to navigation Jump to search

Source Files

/liblfds610/src/lfds610_abstraction/lfds610_abstraction_increment.c
/liblfds610/src/liblfds610_internal.h

Prototype

static LFDS610_INLINE lfds610_atom_t lfds610_abstraction_increment( volatile lfds610_atom_t *value );

Parameters

volatile lfds610_atom_t *value

Pointer to value to atomically increment.

Return Value

The post-increment value.

Notes

Some platforms (Windows) offer atomic increment functions. Some platforms (gcc) only offer atomic add functions. On these platforms, this function will be internally implemented as an atomic add of 1.

Examples

Under GCC, there is a function __sync_add_and_fetch, which has the following prototype;

type __sync_fetch_and_add( type *ptr, type value, ... );

Where type is any type natively supported by the compiler. This is a generalised add function, rather than an increment only function, but gcc provides no increment only function, so we use this function with an add of 1. By using the GCC platform independent atomic instruction, we can write a single function which will work for everyone using GCC.

As such, the implementation of lfds610_abstraction_increment() on GCC looks like this;

 #if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1 && __GNUC_PATCHLEVEL__ >= 0)
 
   /* TRD : any OS on any CPU with GCC 4.1.0 or better
 
            GCC 4.1.0 introduced the __sync_*() atomic intrinsics
 
            __GNUC__ / __GNUC_MINOR__ / __GNUC_PATCHLEVEL__  indicates GCC and which version
   */
 
   static LFDS610_INLINE lfds610_atom_t lfds610_abstraction_increment( volatile lfds610_atom_t *value )
   {
     assert( value != NULL );
 
     // TRD : no need for casting here, GCC has a __sync_add_and_fetch() for all native types
 
     return( (lfds610_atom_t) __sync_add_and_fetch(value, 1) );
   }
 
 #endif

See Also