Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2464 → Rev 2465

/trunk/kernel/arch/arm32/include/atomic.h
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
29,34 → 29,99
/** @addtogroup arm32
* @{
*/
/** @file
/** @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
 
/** @}