voron

experimental ARM OS
git clone git://git.2f30.org/voron.git
Log | Files | Refs | LICENSE

commit e1a0a69fb646f748b55c07cec9b2839c52b242ec
parent 3a86ba96296bead08c90a338524dd3bf504e8942
Author: oblique <psyberbits@gmail.com>
Date:   Sun Oct 28 02:00:13 +0300

add some atomic operations

Diffstat:
include/atomic.h | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+), 0 deletions(-)
diff --git a/include/atomic.h b/include/atomic.h @@ -0,0 +1,64 @@ +#ifndef __ATOMIC_H +#define __ATOMIC_H + +#include <inttypes.h> + +typedef struct { + u32 counter; +} uatomic_t; + +#define UATOMIC_INIT(i) { (i) } +#define uatomic_read(v) (__uatomic_read(v).counter) + +static inline uatomic_t +__uatomic_read(uatomic_t *v) +{ + uatomic_t r; + asm volatile ( + "1: \n\t" + "ldrex %0, [%1] \n\t" + "strex v1, %0, [%1] \n\t" + "teq v1, #0 \n\t" + "bne 1b \n\t" + /* '&' guarantees that 'r' variable will have its own + * register so GCC will not produce assembly code + * like this one: ldrex r5, [r5] */ + : "=&r" (r) + : "r" (v) + : "v1", "memory" + ); + return r; +} + +static inline void +uatomic_set(uatomic_t *v, u32 i) +{ + asm volatile ( + "1: \n\t" + "ldrex v1, [%1] \n\t" + "strex v1, %0, [%1] \n\t" + "teq v1, #0 \n\t" + "bne 1b \n\t" + : + : "r" (i), "r" (v) + : "v1", "memory" + ); +} + +static inline void +uatomic_add(u32 i, uatomic_t *v) +{ + asm volatile ( + "1: \n\t" + "ldrex v1, [%1] \n\t" + "add v1, v1, %0 \n\t" + "strex v2, v1, [%1] \n\t" + "teq v2, #0 \n\t" + "bne 1b \n\t" + : + : "r" (i), "r" (v) + : "v1", "v2", "memory" + ); +} + +#endif /* __ATOMIC_H */