Some useful atomic operations in assembly
namespace E_LIB_NS
{
__inline bool cmpxchg8(volatile u_int8_t *dest, u_int8_t oldv, u_int8_t newv)
{
register bool ret;
__asm__ __volatile__ (CPU_LOCK "cmpxchgb %2, %1; sete %0"
: "=r" (ret), "=m" (*dest)
: "r" (newv), "a" (oldv)
: "memory");
return ret;
}
__inline bool cmpxchg32(volatile u_int32_t *dest, u_int32_t oldv, u_int32_t newv)
{
register bool ret;
__asm__ __volatile__ (CPU_LOCK "cmpxchgl %2, %1; sete %0"
: "=r" (ret), "=m" (*dest)
: "r" (newv), "a" (oldv)
: "memory");
return ret;
}
__inline void increment32(volatile int32_t *p)
{
__asm__ __volatile__ (CPU_LOCK "incl %0"
: "=m" (*p)
: "m" (*p)
: "memory");
}
__inline void decrement32(volatile int32_t *p)
{
__asm__ __volatile__ (CPU_LOCK "decl %0"
: "=m" (*p)
: "m" (*p)
: "memory");
}
__inline void add32(volatile int32_t *p, int32_t incr)
{
__asm__ __volatile__ (CPU_LOCK "addl %1, %0"
: "=m" (*p)
: "r" (incr), "0" (*p)
: "memory");
}
__inline void move8(volatile u_int8_t *p, u_int8_t val)
{
__asm__ __volatile__ (
"movb %1, %0"
: "=m" (*p)
: "r" (val)
: "memory");
}
__inline void move32(volatile u_int32_t *p, u_int32_t val)
{
__asm__ __volatile__ (CPU_LOCK "movl %1, %0"
: "=m" (*p)
: "r" (val)
: "memory");
}
} // namespace E_LIB_NS