# Add atomic operations for ARM. diff --git a/nsprpub/pr/include/md/_linux.h b/nsprpub/pr/include/md/_linux.h index 5b794c5..cb8d58e 100644 --- a/nsprpub/pr/include/md/_linux.h +++ b/nsprpub/pr/include/md/_linux.h @@ -194,6 +194,42 @@ extern PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval); }) #endif +#if defined(__arm__) +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() + +typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr); +#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) + +#define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1) +#define _MD_ATOMIC_DECREMENT(ptr) _MD_ATOMIC_ADD(ptr, -1) +#define _MD_ATOMIC_ADD(ptr, n) \ + ({ \ + PRInt32 ov, nv; \ + volatile PRInt32 *vp = (ptr); \ + \ + do { \ + ov = *vp; \ + nv = ov + (n); \ + } \ + while (__kernel_cmpxchg(ov, nv, vp)); \ + \ + nv; \ + }) +#define _MD_ATOMIC_SET(ptr, nv) \ + ({ \ + PRInt32 ov; \ + volatile PRInt32 *vp = (ptr); \ + \ + do { \ + ov = *vp; \ + } \ + while (__kernel_cmpxchg(ov, (nv), vp)); \ + \ + ov; \ + }) +#endif + #define USE_SETJMP #if defined(__GLIBC__) && __GLIBC__ >= 2 #define _PR_POLL_AVAILABLE