atomic_impl.h
来自「MPI stands for the Message Passing Inter」· C头文件 代码 · 共 371 行
H
371 行
/* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2006 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ *//* Inline C implementation of the functions defined in atomic.h *//********************************************************************** * * Atomic math operations * * All the architectures provide a compare_and_set atomic operations. If * they dont provide atomic additions and/or substractions then we can * define these operations using the atomic compare_and_set. * * Some architectures does not provide support for the 64 bits * atomic operations. Until we find a better solution let's just * undefine all those functions if there is no 64 bit cmpset * *********************************************************************/#if OPAL_HAVE_ATOMIC_CMPSET_32#if !defined(OPAL_HAVE_ATOMIC_ADD_32)#define OPAL_HAVE_ATOMIC_ADD_32 1static inline int32_topal_atomic_add_32(volatile int32_t *addr, int delta){ int32_t oldval; do { oldval = *addr; } while (0 == opal_atomic_cmpset_32(addr, oldval, oldval + delta)); return (oldval + delta);}#endif /* OPAL_HAVE_ATOMIC_CMPSET_32 */#if !defined(OPAL_HAVE_ATOMIC_SUB_32)#define OPAL_HAVE_ATOMIC_SUB_32 1static inline int32_topal_atomic_sub_32(volatile int32_t *addr, int delta){ int32_t oldval; do { oldval = *addr; } while (0 == opal_atomic_cmpset_32(addr, oldval, oldval - delta)); return (oldval - delta);}#endif /* OPAL_HAVE_ATOMIC_SUB_32 */#endif /* OPAL_HAVE_ATOMIC_CMPSET_32 */#if OPAL_HAVE_ATOMIC_CMPSET_64#if !defined(OPAL_HAVE_ATOMIC_ADD_64)#define OPAL_HAVE_ATOMIC_ADD_64 1static inline int64_topal_atomic_add_64(volatile int64_t *addr, int64_t delta){ int64_t oldval; do { oldval = *addr; } while (0 == opal_atomic_cmpset_64(addr, oldval, oldval + delta)); return (oldval + delta);}#endif /* OPAL_HAVE_ATOMIC_ADD_64 */#if !defined(OPAL_HAVE_ATOMIC_SUB_64)#define OPAL_HAVE_ATOMIC_SUB_64 1static inline int64_topal_atomic_sub_64(volatile int64_t *addr, int64_t delta){ int64_t oldval; do { oldval = *addr; } while (0 == opal_atomic_cmpset_64(addr, oldval, oldval - delta)); return (oldval - delta);}#endif /* OPAL_HAVE_ATOMIC_SUB_64 */#endif /* OPAL_HAVE_ATOMIC_CMPSET_64 */#if (OPAL_HAVE_ATOMIC_CMPSET_32 || OPAL_HAVE_ATOMIC_CMPSET_64)static inline intopal_atomic_cmpset_xx(volatile void* addr, int64_t oldval, int64_t newval, size_t length){ switch( length ) {#if OPAL_HAVE_ATOMIC_CMPSET_32 case 4: return opal_atomic_cmpset_32( (volatile int32_t*)addr, (int32_t)oldval, (int32_t)newval );#endif /* OPAL_HAVE_ATOMIC_CMPSET_32 */#if OPAL_HAVE_ATOMIC_CMPSET_64 case 8: return opal_atomic_cmpset_64( (volatile int64_t*)addr, (int64_t)oldval, (int64_t)newval );#endif /* OPAL_HAVE_ATOMIC_CMPSET_64 */ default: /* This should never happen, so deliberately cause a seg fault for corefile analysis */ *(int*)(0) = 0; } return 0; /* always fail */}static inline intopal_atomic_cmpset_acq_xx(volatile void* addr, int64_t oldval, int64_t newval, size_t length){ switch( length ) {#if OPAL_HAVE_ATOMIC_CMPSET_32 case 4: return opal_atomic_cmpset_acq_32( (volatile int32_t*)addr, (int32_t)oldval, (int32_t)newval );#endif /* OPAL_HAVE_ATOMIC_CMPSET_32 */#if OPAL_HAVE_ATOMIC_CMPSET_64 case 8: return opal_atomic_cmpset_acq_64( (volatile int64_t*)addr, (int64_t)oldval, (int64_t)newval );#endif /* OPAL_HAVE_ATOMIC_CMPSET_64 */ default: /* This should never happen, so deliberately cause a seg fault for corefile analysis */ *(int*)(0) = 0; } return 0; /* always fail */}static inline intopal_atomic_cmpset_rel_xx(volatile void* addr, int64_t oldval, int64_t newval, size_t length){ switch( length ) {#if OPAL_HAVE_ATOMIC_CMPSET_32 case 4: return opal_atomic_cmpset_rel_32( (volatile int32_t*)addr, (int32_t)oldval, (int32_t)newval );#endif /* OPAL_HAVE_ATOMIC_CMPSET_32 */#if OPAL_HAVE_ATOMIC_CMPSET_64 case 8: return opal_atomic_cmpset_rel_64( (volatile int64_t*)addr, (int64_t)oldval, (int64_t)newval );#endif /* OPAL_HAVE_ATOMIC_CMPSET_64 */ default: /* This should never happen, so deliberately cause a seg fault for corefile analysis */ *(int*)(0) = 0; } return 0; /* always fail */}static inline intopal_atomic_cmpset_ptr(volatile void* addr, void* oldval, void* newval){#if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_CMPSET_32 return opal_atomic_cmpset_32((int32_t*) addr, (unsigned long) oldval, (unsigned long) newval);#elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_CMPSET_64 return opal_atomic_cmpset_64((int64_t*) addr, (unsigned long) oldval, (unsigned long) newval);#else abort(); return 0;#endif}static inline intopal_atomic_cmpset_acq_ptr(volatile void* addr, void* oldval, void* newval){#if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_CMPSET_32 return opal_atomic_cmpset_acq_32((int32_t*) addr, (unsigned long) oldval, (unsigned long) newval);#elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_CMPSET_64 return opal_atomic_cmpset_acq_64((int64_t*) addr, (unsigned long) oldval, (unsigned long) newval);#else abort(); return 0;#endif}static inline int opal_atomic_cmpset_rel_ptr(volatile void* addr, void* oldval, void* newval){#if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_CMPSET_32 return opal_atomic_cmpset_rel_32((int32_t*) addr, (unsigned long) oldval, (unsigned long) newval);#elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_CMPSET_64 return opal_atomic_cmpset_rel_64((int64_t*) addr, (unsigned long) oldval, (unsigned long) newval);#else abort(); return 0;#endif}#endif /* (OPAL_HAVE_ATOMIC_CMPSET_32 || OPAL_HAVE_ATOMIC_CMPSET_64) */#if OPAL_HAVE_ATOMIC_MATH_32 || OPAL_HAVE_ATOMIC_MATH_64static inline voidopal_atomic_add_xx(volatile void* addr, int32_t value, size_t length){ switch( length ) {#if OPAL_HAVE_ATOMIC_CMPSET_32 case 4: opal_atomic_add_32( (volatile int32_t*)addr, (int32_t)value ); break;#endif /* OPAL_HAVE_ATOMIC_CMPSET_32 */#if OPAL_HAVE_ATOMIC_CMPSET_64 case 8: opal_atomic_add_64( (volatile int64_t*)addr, (int64_t)value ); break;#endif /* OPAL_HAVE_ATOMIC_CMPSET_64 */ default: /* This should never happen, so deliberately cause a seg fault for corefile analysis */ *(int*)(0) = 0; }}static inline voidopal_atomic_sub_xx(volatile void* addr, int32_t value, size_t length){ switch( length ) {#if OPAL_HAVE_ATOMIC_CMPSET_32 case 4: opal_atomic_sub_32( (volatile int32_t*)addr, (int32_t)value ); break;#endif /* OPAL_HAVE_ATOMIC_CMPSET_32 */#if OPAL_HAVE_ATOMIC_CMPSET_64 case 8: opal_atomic_sub_64( (volatile int64_t*)addr, (int64_t)value ); break;#endif /* OPAL_HAVE_ATOMIC_CMPSET_64 */ default: /* This should never happen, so deliberately cause a seg fault for corefile analysis */ *(int*)(0) = 0; }}#if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_CMPSET_32static inline int32_t opal_atomic_add_ptr( volatile void* addr, void* delta ){ return opal_atomic_add_32((int32_t*) addr, (unsigned long) delta);}#elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_CMPSET_64static inline int64_t opal_atomic_add_ptr( volatile void* addr, void* delta ){ return opal_atomic_add_64((int64_t*) addr, (unsigned long) delta);}#elsestatic inline int32_t opal_atomic_add_ptr( volatile void* addr, void* delta ){ abort(); return 0;}#endif#if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_CMPSET_32static inline int32_t opal_atomic_sub_ptr( volatile void* addr, void* delta ){ return opal_atomic_sub_32((int32_t*) addr, (unsigned long) delta);}#elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_CMPSET_64static inline int64_t opal_atomic_sub_ptr( volatile void* addr, void* delta ){ return opal_atomic_sub_64((int64_t*) addr, (unsigned long) delta);}#elsestatic inline int32_t opal_atomic_sub_ptr( volatile void* addr, void* delta ){ abort(); return 0;}#endif#endif /* OPAL_HAVE_ATOMIC_MATH_32 || OPAL_HAVE_ATOMIC_MATH_64 *//********************************************************************** * * Atomic spinlocks * *********************************************************************/#ifdef OPAL_NEED_INLINE_ATOMIC_SPINLOCKS/* * Lock initialization function. It set the lock to UNLOCKED. */static inline voidopal_atomic_init( opal_atomic_lock_t* lock, int32_t value ){ lock->u.lock = value;}static inline intopal_atomic_trylock(opal_atomic_lock_t *lock){ return opal_atomic_cmpset_acq_32( &(lock->u.lock), OPAL_ATOMIC_UNLOCKED, OPAL_ATOMIC_LOCKED);}static inline voidopal_atomic_lock(opal_atomic_lock_t *lock){ while( !opal_atomic_cmpset_acq_32( &(lock->u.lock), OPAL_ATOMIC_UNLOCKED, OPAL_ATOMIC_LOCKED) ) { while (lock->u.lock == OPAL_ATOMIC_LOCKED) { /* spin */ ; } }}static inline voidopal_atomic_unlock(opal_atomic_lock_t *lock){ opal_atomic_wmb(); lock->u.lock=OPAL_ATOMIC_UNLOCKED;}#endif /* OPAL_HAVE_ATOMIC_SPINLOCKS */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?