add doxygen comments for epicsAtomic.h

This commit is contained in:
Elaine Chandler
2022-05-12 16:43:45 -05:00
committed by Andrew Johnson
parent 00183fcd4b
commit ccdd2808d9
+334 -26
View File
@@ -8,6 +8,25 @@
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/**
* \file epicsAtomic.h
*
* \brief OS independent interface to perform atomic operations
*
* This is an operating system and compiler independent interface to an operating system and or compiler
* dependent implementation of several atomic primitives.
*
* These primitives can be safely used in a multithreaded programs on symmetric multiprocessing (SMP)
* systems. Where possible the primitives are implemented with compiler intrinsic wrappers for architecture
* specific instructions. Otherwise they are implemeted with OS specific functions and otherwise, when lacking
* a sufficently capable OS specific interface, then in some rare situations a mutual exclusion primitive is
* used for synchronization.
*
* In operating systems environments which allow C code to run at interrupt level the implementation must
* use interrupt level invokable CPU instruction primitives.
*
* All C++ functions are implemented in the namespace atomics which is nested inside of namespace epics.
*/
/*
* Author Jeffrey O. Hill
* johill@lanl.gov
@@ -26,67 +45,217 @@
extern "C" {
#endif
/** Argument type for atomic operations on pointers*/
typedef void * EpicsAtomicPtrT;
/* load target into cache */
/** \brief load target into cache
*
* load target into cache
**/
EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void);
/* push cache version of target into target */
/** \brief push cache version of target into target
*
* push cache version of target into target
*/
EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void);
/*
* lock out other smp processors from accessing the target,
/** \brief atomic increment on size_t value
*
* Lock out other smp processors from accessing the target,
* load target into cache, add one to target, flush cache
* to target, allow other smp processors to access the target,
* return new value of target as modified by this operation
*
* \param pTarget pointer to target
*
* \return New value of target
*/
EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget );
/** \brief atomic increment on int value
*
* Lock out other smp processors from accessing the target,
* load target into cache, add one to target, flush cache
* to target, allow other smp processors to access the target,
* return new value of target as modified by this operation
*
* \param pTarget pointer to target
*
* \return New value of target
*/
EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget );
/*
* lock out other smp processors from accessing the target,
/** \brief atomic decrement on size_t value
*
* Lock out other smp processors from accessing the target,
* load target into cache, subtract one from target, flush cache
* to target, allow out other smp processors to access the target,
* return new value of target as modified by this operation
*
* \param pTarget pointer to target
*
* \return New value of target
*/
EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget );
/** \brief atomic decrement on int value
*
* Lock out other smp processors from accessing the target,
* load target into cache, subtract one from target, flush cache
* to target, allow out other smp processors to access the target,
* return new value of target as modified by this operation
*
* \param pTarget pointer to target
*
* \return New value of target
*/
EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget );
/*
* lock out other smp processors from accessing the target,
* load target into cache, add/sub delta to/from target, flush cache
/** \brief atomic addition on size_t value
*
* Lock out other smp processors from accessing the target,
* load target into cache, add \p delta to target, flush cache
* to target, allow other smp processors to access the target,
* return new value of target as modified by this operation
*
* \param pTarget pointer to target
* \param delta value to add to target
*
* \return New value of target
*/
EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta );
/** \brief atomic subtraction on size_t value
*
* Lock out other smp processors from accessing the target,
* load target into cache, subtract \p delta from target, flush cache
* to target, allow other smp processors to access the target,
* return new value of target as modified by this operation
*
* \param pTarget pointer to target
* \param delta value to subtract from target
*
* \return New value of target
*/
EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta );
EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta );
/** \brief atomic addition on int value
*
* Lock out other smp processors from accessing the target,
* load target into cache, add \p delta to target, flush cache
* to target, allow other smp processors to access the target,
* return new value of target as modified by this operation
*
* \param pTarget pointer to target
* \param delta value to add to target
*
* \return New value of target
*/
EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta );
/*
* set cache version of target, flush cache to target
*/
/** \brief atomically assign size_t value to variable
*
* set cache version of target to new value, flush cache to target
*
* \param pTarget pointer to target
* \param newValue desired value of target
*/
EPICS_ATOMIC_INLINE void epicsAtomicSetSizeT ( size_t * pTarget, size_t newValue );
/** \brief atomically assign int value to variable
*
* set cache version of target to new value, flush cache to target
*
* \param pTarget pointer to target
* \param newValue desired value of target
*/
EPICS_ATOMIC_INLINE void epicsAtomicSetIntT ( int * pTarget, int newValue );
/** \brief atomically assign pointer value to variable
*
* set cache version of target to new value, flush cache to target
*
* \param pTarget pointer to target
* \param newValue desired value of target
*/
EPICS_ATOMIC_INLINE void epicsAtomicSetPtrT ( EpicsAtomicPtrT * pTarget, EpicsAtomicPtrT newValue );
/*
/** \brief atomically load and return size_t value
*
* fetch target into cache, return new value of target
*
* \param pTarget pointer to target
*
* \return value of target
*/
EPICS_ATOMIC_INLINE size_t epicsAtomicGetSizeT ( const size_t * pTarget );
/** \brief atomically load and return int value
*
* fetch target into cache, return new value of target
*
* \param pTarget pointer to target
*
* \return value of target
*/
EPICS_ATOMIC_INLINE int epicsAtomicGetIntT ( const int * pTarget );
/** \brief atomically load and return pointer value
*
* fetch target into cache, return new value of target
*
* \param pTarget pointer to target
*
* \return value of target
*/
EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicGetPtrT ( const EpicsAtomicPtrT * pTarget );
/*
/** \brief atomically compare size_t value with expected and if equal swap with new value
*
* lock out other smp processors from accessing the target,
* load target into cache, if target is equal to oldVal set target
* to newVal, flush cache to target, allow other smp processors
* to access the target, return the original value stored in the
* target
* load target into cache. If target is equal to \p oldVal, set target
* to \p newVal, flush cache to target, allow other smp processors
* to access the target
*
* \param pTarget pointer to target
* \param oldVal value that will be compared with target
* \param newVal value that will be set to target if oldVal == target
*
* \return the original value stored in the target
*/
EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget,
size_t oldVal, size_t newVal );
/** \brief atomically compare int value with expected and if equal swap with new value
*
* lock out other smp processors from accessing the target,
* load target into cache. If target is equal to \p oldVal, set target
* to \p newVal, flush cache to target, allow other smp processors
* to access the target
*
* \param pTarget pointer to target
* \param oldVal value that will be compared with target
* \param newVal value that will be set to target if oldVal == target
*
* \return the original value stored in the target
*/
EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget,
int oldVal, int newVal );
/** \brief atomically compare int value with expected and if equal swap with new value
*
* lock out other smp processors from accessing the target,
* load target into cache. If target is equal to \p oldVal, set target
* to \p newVal, flush cache to target, allow other smp processors
* to access the target
*
* \param pTarget pointer to target
* \param oldVal value that will be compared with target
* \param newVal value that will be set to target if oldVal == target
*
* \return the original value stored in the target
*/
EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT (
EpicsAtomicPtrT * pTarget,
EpicsAtomicPtrT oldVal,
@@ -115,94 +284,233 @@ namespace atomic {
* overloaded c++ interface
*/
/************* incr ***************/
/** \brief C++ API for atomic size_t increment
*
* C++ API for atomic size_t increment.
*
* \param v variable to increment
*
* \return new value
*/
EPICS_ATOMIC_INLINE size_t increment ( size_t & v )
{
return epicsAtomicIncrSizeT ( & v );
}
/** \brief C++ API for atomic int increment
*
* C++ API for atomic int increment.
*
* \param v variable to increment
*
* \return new value
*/
EPICS_ATOMIC_INLINE int increment ( int & v )
{
return epicsAtomicIncrIntT ( & v );
}
/************* decr ***************/
/** \brief C++ API for atomic size_t decrement
*
* C++ API for atomic size_t decrement
*
* \param v variable to decrement
*
* \return new value
*/
EPICS_ATOMIC_INLINE size_t decrement ( size_t & v )
{
return epicsAtomicDecrSizeT ( & v );
}
/** \brief C++ API for atomic int decrement
*
* C++ API for atomic int decrement
*
* \param v variable to decrement
*
* \return new value
*/
EPICS_ATOMIC_INLINE int decrement ( int & v )
{
return epicsAtomicDecrIntT ( & v );
}
/************* add ***************/
/** \brief C++ API for atomic size_t addition
*
* C++ API for atomic size_t addition
*
* \param v variable to add to
* \param delta value to add to \p v
*
* \return new value
*/
EPICS_ATOMIC_INLINE size_t add ( size_t & v, size_t delta )
{
return epicsAtomicAddSizeT ( & v, delta );
}
/** \brief C++ API for atomic int addition
*
* C++ API for atomic int addition
*
* \param v variable to add to
* \param delta value to add to \p v
*
* \return new value
*/
EPICS_ATOMIC_INLINE int add ( int & v, int delta )
{
return epicsAtomicAddIntT ( & v, delta );
}
/************* sub ***************/
/** \brief C++ API for atomic size_t subtraction
*
* C++ API for atomic size_t subtraction
*
* \param v variable to subtract from
* \param delta value to subtract from \p v
*
* \return new value
*/
EPICS_ATOMIC_INLINE size_t subtract ( size_t & v, size_t delta )
{
return epicsAtomicSubSizeT ( & v, delta );
}
/** \brief C++ API for atomic int subtraction
*
* C++ API for atomic int subtraction
*
* \param v variable to subtract from
* \param delta value to subtract from \p v
*
* \return new value
*/
EPICS_ATOMIC_INLINE int subtract ( int & v, int delta )
{
return epicsAtomicAddIntT ( & v, -delta );
}
/************* set ***************/
/** \brief C++ API for atomic size_t assignment
*
* C++ API for atomic size_t assignment
*
* \param v variable to assign to
* \param newValue new value for \p v
*/
EPICS_ATOMIC_INLINE void set ( size_t & v , size_t newValue )
{
epicsAtomicSetSizeT ( & v, newValue );
}
/** \brief C++ API for atomic int assignment
*
* C++ API for atomic int assignment
*
* \param v variable to assign to
* \param newValue new value for \p v
*/
EPICS_ATOMIC_INLINE void set ( int & v, int newValue )
{
epicsAtomicSetIntT ( & v, newValue );
}
/** \brief C++ API for atomic pointer assignment
*
* C++ API for atomic pointer assignment
*
* \param v variable to assign to
* \param newValue new value for \p v
*/
EPICS_ATOMIC_INLINE void set ( EpicsAtomicPtrT & v, EpicsAtomicPtrT newValue )
{
epicsAtomicSetPtrT ( & v, newValue );
}
/************* get ***************/
/** \brief C++ API for atomic size_t load value
*
* C++ API for atomic size_t load value
*
* \param v variable to load
*
* \return value of \p v
*/
EPICS_ATOMIC_INLINE size_t get ( const size_t & v )
{
return epicsAtomicGetSizeT ( & v );
}
/** \brief C++ API for atomic int load value
*
* C++ API for atomic int load value
*
* \param v variable to load
*
* \return value of \p v
*/
EPICS_ATOMIC_INLINE int get ( const int & v )
{
return epicsAtomicGetIntT ( & v );
}
/** \brief C++ API for atomic pointer load value
*
* C++ API for atomic pointer load value
*
* \param v variable to load
*
* \return value of \p v
*/
EPICS_ATOMIC_INLINE EpicsAtomicPtrT get ( const EpicsAtomicPtrT & v )
{
return epicsAtomicGetPtrT ( & v );
}
/************* cas ***************/
/** \brief C++ API for atomic size_t compare-and-swap
*
* C++ API for atomic size_t compare-and-swap. Atomic operation that compares \p v with \p oldVal
* and if \p v == \v oldVal, sets \p v to \v newVal
*
* \param v variable to compare and swap
* \param oldVal value to compare to \p \v
* \param newVal value to set to \p v
*
* \return original value stored in \p v
*/
EPICS_ATOMIC_INLINE size_t compareAndSwap ( size_t & v,
size_t oldVal, size_t newVal )
{
return epicsAtomicCmpAndSwapSizeT ( & v, oldVal, newVal );
}
/** \brief C++ API for atomic int compare-and-swap
*
* C++ API for atomic size_t compare-and-swap. Atomic operation that compares \p v with \p oldVal
* and if \p v == \v oldVal, sets \p v to \v newVal
*
* \param v variable to compare and swap
* \param oldVal value to compare to \p \v
* \param newVal value to set to \p v
*
* \return original value stored in \p v
*/
EPICS_ATOMIC_INLINE int compareAndSwap ( int & v, int oldVal, int newVal )
{
return epicsAtomicCmpAndSwapIntT ( & v, oldVal, newVal );
}
/** \brief C++ API for atomic pointer compare-and-swap
*
* C++ API for atomic size_t compare-and-swap. Atomic operation that compares \p v with \p oldVal
* and if \p v == \v oldVal, sets \p v to \v newVal
*
* \param v variable to compare and swap
* \param oldVal value to compare to \p \v
* \param newVal value to set to \p v
*
* \return original value stored in \p v
*/
EPICS_ATOMIC_INLINE EpicsAtomicPtrT compareAndSwap ( EpicsAtomicPtrT & v,
EpicsAtomicPtrT oldVal,
EpicsAtomicPtrT newVal )