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__
# 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 ;
}
/* 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()
# endif