typedef signed long rint64;
typedef unsigned long ruint64;
typedef unsigned long rword;
+typedef unsigned int ratomic;
/*
* Atomic operations (Architecture Dependent)
*/
-#define R_COMPARE_AND_EXCHANGE(ptr, oldval, newval, res) \
+#define R_ATOMIC_CMPXCHG(ptr, oldval, newval, resptr) \
do { __asm__ __volatile__ ("lock; cmpxchgl %2, %1" \
- : "=a" (res), "=m" (*ptr) \
+ : "=a" (*(resptr)), "=m" (*ptr) \
: "r" (newval), "m" (*ptr), "0" (oldval)); } while (0)
+#define R_ATOMIC_XCHG(ptr, val) \
+ do { __asm__ __volatile__("xchgl %0,%1" \
+ :"=r" ((ruint32) val) \
+ :"m" (*(volatile ruint32 *)ptr), "0" (val) \
+ :"memory"); } while (0)
+
+#define R_ATOMIC_ADD(ptr, val) \
+ do { __asm__ __volatile__ ("addl %1,%0" \
+ : "=m" (*ptr) \
+ : "ir" (val), "m" (*ptr)); } while (0)
+
+#define R_ATOMIC_SUB(ptr, val) \
+ do { __asm__ __volatile__ ("subl %1,%0" \
+ : "=m" (*ptr) \
+ : "ir" (val), "m" (*ptr)); } while (0)
+
+
#ifndef NULL
#ifdef __cplusplus
CFLAGS += -fprofile-arcs -ftest-coverage
endif
+CFLAGS += -DRPA_DEBUG_MEM
+
CFLAGS += $(MACH) $(INCLUDE)
LDFLAGS := $(MACH)
#include "rtypes.h"
-rboolean r_atomic_compare_and_exchange(volatile rint *ptr, rint oldval, rint newval)
+rboolean r_atomic_compare_and_exchange(volatile ratomic *ptr, ratomic oldval, ratomic newval)
{
- rint result;
+ ratomic result;
- R_COMPARE_AND_EXCHANGE(ptr, oldval, newval, result);
+ R_ATOMIC_CMPXCHG(ptr, oldval, newval, &result);
return (result == oldval);
}
+
+
+ratomic r_atomic_exchange(volatile ratomic *ptr, ratomic val)
+{
+ R_ATOMIC_XCHG(ptr, val);
+ return val;
+}
+
+
+void r_atomic_add(volatile ratomic *ptr, ratomic val)
+{
+ R_ATOMIC_ADD(ptr, val);
+}
+
+
+void r_atomic_sub(volatile ratomic *ptr, ratomic val)
+{
+ R_ATOMIC_SUB(ptr, val);
+}
#endif
-rboolean r_atomic_compare_and_exchange(volatile rint *ptr, rint oldval, rint newval);
-
+rboolean r_atomic_compare_and_exchange(volatile ratomic *ptr, ratomic oldval, ratomic newval);
+ratomic r_atomic_exchange(volatile ratomic *ptr, ratomic val);
+ratomic r_atomic_add(volatile ratomic *ptr, ratomic val);
+ratomic r_atomic_sub(volatile ratomic *ptr, ratomic val);
#ifdef __cplusplus
}
{
return memcpy(dest, src, (size_t)n);
}
+
+
+rboolean r_atomic_int_compare_and_exchange (volatile rint *atomic, rint oldval, rint newval)
+{
+ rint result;
+
+ __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+ : "=a" (result), "=m" (*atomic)
+ : "r" (newval), "m" (*atomic), "0" (oldval));
+
+ return result == oldval;
+}