
This patch improves on the previously added virAtomicInt operations by testing for the compiler and if GCC >= 4.1 (not found in docs prior to that) is used on Linux and has the appropriate processor (that I have access to) then use the implementation based on the gcc-builtins. I also did not look at other systems (cygwin, win32) that do not need access to virAtomic right now. --- src/util/viratomic.h | 88 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 16 deletions(-) Index: libvirt-acl/src/util/viratomic.h =================================================================== --- libvirt-acl.orig/src/util/viratomic.h +++ libvirt-acl/src/util/viratomic.h @@ -30,6 +30,22 @@ typedef struct _virAtomicInt virAtomicInt; typedef virAtomicInt *virAtomicIntPtr; +# define __VIR_ATOMIC_USES_LOCK + +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4) +# if defined(__linux__) +# if defined(__i386__) || defined(__x86_64__) || \ + defined(__powerpc64__) || defined(__powerpc__) +# undef __VIR_ATOMIC_USES_LOCK +# endif +# endif +# endif +# endif + + +# ifdef __VIR_ATOMIC_USES_LOCK + struct _virAtomicInt { virMutex lock; int value; @@ -42,22 +58,6 @@ virAtomicIntInit(virAtomicIntPtr vaip) return virMutexInit(&vaip->lock); } -static inline void -virAtomicIntSet(virAtomicIntPtr vaip, int value) -{ - virMutexLock(&vaip->lock); - - vaip->value = value; - - virMutexUnlock(&vaip->lock); -} - -static inline int -virAtomicIntRead(virAtomicIntPtr vaip) -{ - return vaip->value; -} - static inline int virAtomicIntAdd(virAtomicIntPtr vaip, int add) { @@ -88,4 +88,60 @@ virAtomicIntSub(virAtomicIntPtr vaip, in return ret; } +# else /* __VIR_ATOMIC_USES_LOCK */ + +struct _virAtomicInt { + int value; +}; + +static inline int +virAtomicIntInit(virAtomicIntPtr vaip) +{ + vaip->value = 0; + return 0; +} + +static inline int +virAtomicIntAdd(virAtomicIntPtr vaip, int add) +{ + return __sync_add_and_fetch(&vaip->value, add); +} + +static inline int +virAtomicIntSub(virAtomicIntPtr vaip, int sub) +{ + return __sync_sub_and_fetch(&vaip->value, sub); +} + +# endif /* __VIR_ATOMIC_USES_LOCK */ + + + +/* common operations that need no locking or build on others */ + + +static inline void +virAtomicIntSet(virAtomicIntPtr vaip, int value) +{ + vaip->value = value; +} + +static inline int +virAtomicIntRead(virAtomicIntPtr vaip) +{ + return *(volatile int *)&vaip->value; +} + +static inline int +virAtomicIntInc(virAtomicIntPtr vaip) +{ + return virAtomicIntAdd(vaip, 1); +} + +static inline int +virAtomicIntDec(virAtomicIntPtr vaip) +{ + return virAtomicIntSub(vaip, 1); +} + #endif /* __VIR_ATOMIC_H */