r6.0.1:lfds601_abstraction_increment

From liblfds.org
Jump to navigation Jump to search

Source Files

/liblfds601/src/lfds601_abstraction/lfds601_abstraction_increment.c
/liblfds601/inc/liblfds601.h

Prototype

LFDS601_INLINE lfds601_atom_t lfds601_abstraction_increment( lfds601_atom_t *value );

Parameters

lfds601_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 lfds601_abstraction_increment() on GCC looks like this;

#if (defined __x86_64__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1 && __GNUC_PATCHLEVEL__ >= 0)

  /* TRD : any OS on x64 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
  */

  LFDS601_INLINE lfds601_atom_t lfds601_abstraction_increment( lfds601_atom_t *value )
  {
    lfds601_atom_t
      rv;

    // TRD : no need for casting here, GCC has a __sync_add_and_fetch() for all native types

    rv = __sync_add_and_fetch( value, 1 );

    return( rv );
  }

#endif

See Also