diff options
Diffstat (limited to 'intern/atomic')
-rw-r--r-- | intern/atomic/atomic_ops.h | 3 | ||||
-rw-r--r-- | intern/atomic/intern/atomic_ops_ext.h | 23 | ||||
-rw-r--r-- | intern/atomic/intern/atomic_ops_utils.h | 11 |
3 files changed, 29 insertions, 8 deletions
diff --git a/intern/atomic/atomic_ops.h b/intern/atomic/atomic_ops.h index 1e9528f9ed9..38670be56fd 100644 --- a/intern/atomic/atomic_ops.h +++ b/intern/atomic/atomic_ops.h @@ -100,6 +100,7 @@ ATOMIC_INLINE size_t atomic_sub_and_fetch_z(size_t *p, size_t x); ATOMIC_INLINE size_t atomic_fetch_and_add_z(size_t *p, size_t x); ATOMIC_INLINE size_t atomic_fetch_and_sub_z(size_t *p, size_t x); ATOMIC_INLINE size_t atomic_cas_z(size_t *v, size_t old, size_t _new); +ATOMIC_INLINE size_t atomic_fetch_and_update_max_z(size_t *p, size_t x); /* Uses CAS loop, see warning below. */ ATOMIC_INLINE unsigned int atomic_add_and_fetch_u(unsigned int *p, unsigned int x); ATOMIC_INLINE unsigned int atomic_sub_and_fetch_u(unsigned int *p, unsigned int x); @@ -107,6 +108,8 @@ ATOMIC_INLINE unsigned int atomic_fetch_and_add_u(unsigned int *p, unsigned int ATOMIC_INLINE unsigned int atomic_fetch_and_sub_u(unsigned int *p, unsigned int x); ATOMIC_INLINE unsigned int atomic_cas_u(unsigned int *v, unsigned int old, unsigned int _new); +ATOMIC_INLINE void *atomic_cas_ptr(void **v, void *old, void *_new); + /* WARNING! Float 'atomics' are really faked ones, those are actually closer to some kind of spinlock-sync'ed operation, * which means they are only efficient if collisions are highly unlikely (i.e. if probability of two threads * working on the same pointer at the same time is very low). */ diff --git a/intern/atomic/intern/atomic_ops_ext.h b/intern/atomic/intern/atomic_ops_ext.h index b72c94563fc..34158a0b45e 100644 --- a/intern/atomic/intern/atomic_ops_ext.h +++ b/intern/atomic/intern/atomic_ops_ext.h @@ -111,6 +111,17 @@ ATOMIC_INLINE size_t atomic_cas_z(size_t *v, size_t old, size_t _new) #endif } +ATOMIC_INLINE size_t atomic_fetch_and_update_max_z(size_t *p, size_t x) +{ + size_t prev_value; + while((prev_value = *p) < x) { + if(atomic_cas_z(p, prev_value, x) == prev_value) { + break; + } + } + return prev_value; +} + /******************************************************************************/ /* unsigned operations. */ ATOMIC_INLINE unsigned int atomic_add_and_fetch_u(unsigned int *p, unsigned int x) @@ -169,6 +180,18 @@ ATOMIC_INLINE unsigned int atomic_cas_u(unsigned int *v, unsigned int old, unsig } /******************************************************************************/ +/* Pointer operations. */ + +ATOMIC_INLINE void *atomic_cas_ptr(void **v, void *old, void *_new) +{ +#if (LG_SIZEOF_PTR == 8) + return (void *)atomic_cas_uint64((uint64_t *)v, *(uint64_t *)&old, *(uint64_t *)&_new); +#elif (LG_SIZEOF_PTR == 4) + return (void *)atomic_cas_uint32((uint32_t *)v, *(uint32_t *)&old, *(uint32_t *)&_new); +#endif +} + +/******************************************************************************/ /* float operations. */ ATOMIC_INLINE float atomic_add_and_fetch_fl(float *p, const float x) diff --git a/intern/atomic/intern/atomic_ops_utils.h b/intern/atomic/intern/atomic_ops_utils.h index bfec9918c16..c190b655e0a 100644 --- a/intern/atomic/intern/atomic_ops_utils.h +++ b/intern/atomic/intern/atomic_ops_utils.h @@ -52,8 +52,8 @@ #ifndef __ATOMIC_OPS_UTILS_H__ #define __ATOMIC_OPS_UTILS_H__ -/* needed for int types */ -#include "../../../source/blender/blenlib/BLI_sys_types.h" +#include <stdint.h> +#include <stddef.h> #include <stdlib.h> #include <limits.h> @@ -63,12 +63,7 @@ #if defined(_MSC_VER) # define ATOMIC_INLINE static __forceinline #else -# if (defined(__APPLE__) && defined(__ppc__)) -/* static inline __attribute__ here breaks osx ppc gcc42 build */ -# define ATOMIC_INLINE static __attribute__((always_inline)) -# else -# define ATOMIC_INLINE static inline __attribute__((always_inline)) -# endif +# define ATOMIC_INLINE static inline __attribute__((always_inline)) #endif #ifndef LIKELY |