2005-04-17 02:20:36 +04:00
/* $Id: atomic.h,v 1.3 2001/07/25 16:15:19 bjornw Exp $ */
# ifndef __ASM_CRIS_ATOMIC__
# define __ASM_CRIS_ATOMIC__
2007-11-15 04:00:51 +03:00
# include <linux/compiler.h>
2005-04-17 02:20:36 +04:00
# include <asm/system.h>
2005-07-27 22:44:42 +04:00
# include <asm/arch/atomic.h>
2005-04-17 02:20:36 +04:00
/*
* Atomic operations that C can ' t guarantee us . Useful for
* resource counting etc . .
*/
2005-07-27 22:44:42 +04:00
typedef struct { volatile int counter ; } atomic_t ;
2005-04-17 02:20:36 +04:00
# define ATOMIC_INIT(i) { (i) }
# define atomic_read(v) ((v)->counter)
# define atomic_set(v,i) (((v)->counter) = (i))
/* These should be written in asm but we do it in C for now. */
2005-11-07 11:58:44 +03:00
static inline void atomic_add ( int i , volatile atomic_t * v )
2005-04-17 02:20:36 +04:00
{
unsigned long flags ;
2005-07-27 22:44:42 +04:00
cris_atomic_save ( v , flags ) ;
2005-04-17 02:20:36 +04:00
v - > counter + = i ;
2005-07-27 22:44:42 +04:00
cris_atomic_restore ( v , flags ) ;
2005-04-17 02:20:36 +04:00
}
2005-11-07 11:58:44 +03:00
static inline void atomic_sub ( int i , volatile atomic_t * v )
2005-04-17 02:20:36 +04:00
{
unsigned long flags ;
2005-07-27 22:44:42 +04:00
cris_atomic_save ( v , flags ) ;
2005-04-17 02:20:36 +04:00
v - > counter - = i ;
2005-07-27 22:44:42 +04:00
cris_atomic_restore ( v , flags ) ;
2005-04-17 02:20:36 +04:00
}
2005-11-07 11:58:44 +03:00
static inline int atomic_add_return ( int i , volatile atomic_t * v )
2005-04-17 02:20:36 +04:00
{
unsigned long flags ;
int retval ;
2005-07-27 22:44:42 +04:00
cris_atomic_save ( v , flags ) ;
2005-04-17 02:20:36 +04:00
retval = ( v - > counter + = i ) ;
2005-07-27 22:44:42 +04:00
cris_atomic_restore ( v , flags ) ;
2005-04-17 02:20:36 +04:00
return retval ;
}
# define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
2005-11-07 11:58:44 +03:00
static inline int atomic_sub_return ( int i , volatile atomic_t * v )
2005-04-17 02:20:36 +04:00
{
unsigned long flags ;
int retval ;
2005-07-27 22:44:42 +04:00
cris_atomic_save ( v , flags ) ;
2005-04-17 02:20:36 +04:00
retval = ( v - > counter - = i ) ;
2005-07-27 22:44:42 +04:00
cris_atomic_restore ( v , flags ) ;
2005-04-17 02:20:36 +04:00
return retval ;
}
2005-11-07 11:58:44 +03:00
static inline int atomic_sub_and_test ( int i , volatile atomic_t * v )
2005-04-17 02:20:36 +04:00
{
int retval ;
unsigned long flags ;
2005-07-27 22:44:42 +04:00
cris_atomic_save ( v , flags ) ;
2005-04-17 02:20:36 +04:00
retval = ( v - > counter - = i ) = = 0 ;
2005-07-27 22:44:42 +04:00
cris_atomic_restore ( v , flags ) ;
2005-04-17 02:20:36 +04:00
return retval ;
}
2005-11-07 11:58:44 +03:00
static inline void atomic_inc ( volatile atomic_t * v )
2005-04-17 02:20:36 +04:00
{
unsigned long flags ;
2005-07-27 22:44:42 +04:00
cris_atomic_save ( v , flags ) ;
2005-04-17 02:20:36 +04:00
( v - > counter ) + + ;
2005-07-27 22:44:42 +04:00
cris_atomic_restore ( v , flags ) ;
2005-04-17 02:20:36 +04:00
}
2005-11-07 11:58:44 +03:00
static inline void atomic_dec ( volatile atomic_t * v )
2005-04-17 02:20:36 +04:00
{
unsigned long flags ;
2005-07-27 22:44:42 +04:00
cris_atomic_save ( v , flags ) ;
2005-04-17 02:20:36 +04:00
( v - > counter ) - - ;
2005-07-27 22:44:42 +04:00
cris_atomic_restore ( v , flags ) ;
2005-04-17 02:20:36 +04:00
}
2005-11-07 11:58:44 +03:00
static inline int atomic_inc_return ( volatile atomic_t * v )
2005-04-17 02:20:36 +04:00
{
unsigned long flags ;
int retval ;
2005-07-27 22:44:42 +04:00
cris_atomic_save ( v , flags ) ;
2005-04-17 02:20:36 +04:00
retval = ( v - > counter ) + + ;
2005-07-27 22:44:42 +04:00
cris_atomic_restore ( v , flags ) ;
2005-04-17 02:20:36 +04:00
return retval ;
}
2005-11-07 11:58:44 +03:00
static inline int atomic_dec_return ( volatile atomic_t * v )
2005-04-17 02:20:36 +04:00
{
unsigned long flags ;
int retval ;
2005-07-27 22:44:42 +04:00
cris_atomic_save ( v , flags ) ;
2005-04-17 02:20:36 +04:00
retval = ( v - > counter ) - - ;
2005-07-27 22:44:42 +04:00
cris_atomic_restore ( v , flags ) ;
2005-04-17 02:20:36 +04:00
return retval ;
}
2005-11-07 11:58:44 +03:00
static inline int atomic_dec_and_test ( volatile atomic_t * v )
2005-04-17 02:20:36 +04:00
{
int retval ;
unsigned long flags ;
2005-07-27 22:44:42 +04:00
cris_atomic_save ( v , flags ) ;
2005-04-17 02:20:36 +04:00
retval = - - ( v - > counter ) = = 0 ;
2005-07-27 22:44:42 +04:00
cris_atomic_restore ( v , flags ) ;
2005-04-17 02:20:36 +04:00
return retval ;
}
2005-11-07 11:58:44 +03:00
static inline int atomic_inc_and_test ( volatile atomic_t * v )
2005-04-17 02:20:36 +04:00
{
int retval ;
unsigned long flags ;
2005-07-27 22:44:42 +04:00
cris_atomic_save ( v , flags ) ;
2005-04-17 02:20:36 +04:00
retval = + + ( v - > counter ) = = 0 ;
2005-07-27 22:44:42 +04:00
cris_atomic_restore ( v , flags ) ;
2005-04-17 02:20:36 +04:00
return retval ;
}
2005-11-14 03:07:24 +03:00
static inline int atomic_cmpxchg ( atomic_t * v , int old , int new )
{
int ret ;
unsigned long flags ;
cris_atomic_save ( v , flags ) ;
ret = v - > counter ;
if ( likely ( ret = = old ) )
v - > counter = new ;
cris_atomic_restore ( v , flags ) ;
return ret ;
}
2006-01-10 02:59:17 +03:00
# define atomic_xchg(v, new) (xchg(&((v)->counter), new))
2005-11-14 03:07:25 +03:00
static inline int atomic_add_unless ( atomic_t * v , int a , int u )
{
int ret ;
unsigned long flags ;
cris_atomic_save ( v , flags ) ;
ret = v - > counter ;
if ( ret ! = u )
v - > counter + = a ;
cris_atomic_restore ( v , flags ) ;
return ret ! = u ;
}
# define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
2005-04-17 02:20:36 +04:00
/* Atomic operations are already serializing */
# define smp_mb__before_atomic_dec() barrier()
# define smp_mb__after_atomic_dec() barrier()
# define smp_mb__before_atomic_inc() barrier()
# define smp_mb__after_atomic_inc() barrier()
2006-01-06 11:11:20 +03:00
# include <asm-generic/atomic.h>
2005-04-17 02:20:36 +04:00
# endif