|
|
@ -1,6 +1,8 @@
|
|
|
|
#ifndef _CAS_H
|
|
|
|
#ifndef _CAS_H
|
|
|
|
#define _CAS_H
|
|
|
|
#define _CAS_H
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
|
|
|
|
|
|
|
/* Atomic operations for lock-free data structures.
|
|
|
|
/* Atomic operations for lock-free data structures.
|
|
|
|
* We operate on machine words and use size_t as a type.
|
|
|
|
* We operate on machine words and use size_t as a type.
|
|
|
|
* CAS stands for Compare And Swap, the most common operation. */
|
|
|
|
* CAS stands for Compare And Swap, the most common operation. */
|
|
|
@ -11,6 +13,23 @@
|
|
|
|
#define USE_BUILTINS
|
|
|
|
#define USE_BUILTINS
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* if (*x == oldval) { *x=newval; return 1; } else return 0; */
|
|
|
|
|
|
|
|
static inline int compare_and_swap(volatile size_t* x,size_t oldval,size_t newval) {
|
|
|
|
|
|
|
|
#ifdef USE_BUILTINS
|
|
|
|
|
|
|
|
__sync_bool_compare_and_swap(x,oldval,newval);
|
|
|
|
|
|
|
|
#elif defined(__i386__)
|
|
|
|
|
|
|
|
char result;
|
|
|
|
|
|
|
|
asm volatile ("lock; cmpxchgl %3, %0; setz %1" : "=m"(*x), "=q" (result) : "m" (*x), "r" (newval), "a" (oldval) : "memory");
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
#elif defined(__x86_64__)
|
|
|
|
|
|
|
|
char result;
|
|
|
|
|
|
|
|
asm volatile ("lock; cmpxchgq %3, %0; setz %1" : "=m"(*x), "=q" (result) : "m" (*x), "r" (newval), "a" (oldval) : "memory");
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#error architecture not supported and gcc too old, edit CAS.h
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* *x += val; */
|
|
|
|
/* *x += val; */
|
|
|
|
static inline void atomic_add(size_t* x,size_t val) {
|
|
|
|
static inline void atomic_add(size_t* x,size_t val) {
|
|
|
|
#ifdef USE_BUILTINS
|
|
|
|
#ifdef USE_BUILTINS
|
|
|
@ -95,23 +114,6 @@ static inline void atomic_and(volatile size_t* x,size_t val) {
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* if (*x == oldval) { *x=newval; return 1; } else return 0; */
|
|
|
|
|
|
|
|
static inline int compare_and_swap(volatile size_t* x,size_t oldval,size_t newval) {
|
|
|
|
|
|
|
|
#ifdef USE_BUILTINS
|
|
|
|
|
|
|
|
__sync_bool_compare_and_swap(x,oldval,newval);
|
|
|
|
|
|
|
|
#elif defined(__i386__)
|
|
|
|
|
|
|
|
char result;
|
|
|
|
|
|
|
|
asm volatile ("lock; cmpxchgl %3, %0; setz %1" : "=m"(*x), "=q" (result) : "m" (*x), "r" (newval), "a" (oldval) : "memory");
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
#elif defined(__x86_64__)
|
|
|
|
|
|
|
|
char result;
|
|
|
|
|
|
|
|
asm volatile ("lock; cmpxchgq %3, %0; setz %1" : "=m"(*x), "=q" (result) : "m" (*x), "r" (newval), "a" (oldval) : "memory");
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#error architecture not supported and gcc too old, edit CAS.h
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Optimization barrier */
|
|
|
|
/* Optimization barrier */
|
|
|
|
/* The "volatile" is due to gcc bugs */
|
|
|
|
/* The "volatile" is due to gcc bugs */
|
|
|
|
#define barrier() __asm__ __volatile__("": : :"memory")
|
|
|
|
#define barrier() __asm__ __volatile__("": : :"memory")
|
|
|
|