1,5 → 1,5 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
30,33 → 30,98 |
* @{ |
*/ |
/** @file |
* @brief Atomic operations. |
*/ |
|
#ifndef KERN_arm32_ATOMIC_H_ |
#define KERN_arm32_ATOMIC_H_ |
|
#define atomic_inc(x) ((void) atomic_add(x, 1)) |
#define atomic_dec(x) ((void) atomic_add(x, -1)) |
/** Atomic addition. |
* |
* @param val Where to add. |
* @param i Value to be added. |
* |
* @return Value after addition. |
*/ |
static inline long atomic_add(atomic_t *val, int i) |
{ |
int ret; |
volatile long *mem = &(val->count); |
|
#define atomic_postinc(x) (atomic_add(x, 1) - 1) |
#define atomic_postdec(x) (atomic_add(x, -1) + 1) |
asm volatile ( |
"1:\n" |
"ldr r2, [%1] \n" |
"add r3, r2, %2 \n" |
"str r3, %0 \n" |
"swp r3, r3, [%1] \n" |
"cmp r3, r2 \n" |
"bne 1b \n" |
|
#define atomic_preinc(x) atomic_add(x, 1) |
#define atomic_predec(x) atomic_add(x, -1) |
: "=m" (ret) |
: "r" (mem), "r" (i) |
: "r3", "r2" |
); |
|
/* Atomic addition of immediate value. |
return ret; |
} |
|
/** Atomic increment. |
* |
* @param val Memory location to which will be the immediate value added. |
* @param i Signed immediate that will be added to *val. |
* @param val Variable to be incremented. |
*/ |
static inline void atomic_inc(atomic_t *val) |
{ |
atomic_add(val, 1); |
} |
|
/** Atomic decrement. |
* |
* @return Value after addition. |
* @param val Variable to be decremented. |
*/ |
static inline long atomic_add(atomic_t *val, int i) |
static inline void atomic_dec(atomic_t *val) { |
atomic_add(val, -1); |
} |
|
/** Atomic pre-increment. |
* |
* @param val Variable to be incremented. |
* @return Value after incrementation. |
*/ |
static inline long atomic_preinc(atomic_t *val) |
{ |
/* TODO */ |
return (val->count += i); |
return atomic_add(val, 1); |
} |
|
/** Atomic pre-decrement. |
* |
* @param val Variable to be decremented. |
* @return Value after decrementation. |
*/ |
static inline long atomic_predec(atomic_t *val) |
{ |
return atomic_add(val, -1); |
} |
|
/** Atomic post-increment. |
* |
* @param val Variable to be incremented. |
* @return Value before incrementation. |
*/ |
static inline long atomic_postinc(atomic_t *val) |
{ |
return atomic_add(val, 1) - 1; |
} |
|
/** Atomic post-decrement. |
* |
* @param val Variable to be decremented. |
* @return Value before decrementation. |
*/ |
static inline long atomic_postdec(atomic_t *val) |
{ |
return atomic_add(val, -1) + 1; |
} |
|
#endif |
|
/** @} |