1/* $Id: atomic.h,v 1.1.1.1 2008/10/15 03:27:16 james26_jang Exp $ */ 2 3#ifndef __ASM_CRIS_ATOMIC__ 4#define __ASM_CRIS_ATOMIC__ 5 6#include <asm/system.h> 7 8/* 9 * Atomic operations that C can't guarantee us. Useful for 10 * resource counting etc.. 11 */ 12 13/* 14 * Make sure gcc doesn't try to be clever and move things around 15 * on us. We need to use _exactly_ the address the user gave us, 16 * not some alias that contains the same information. 17 */ 18 19#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x) 20 21typedef struct { int counter; } atomic_t; 22 23#define ATOMIC_INIT(i) { (i) } 24 25#define atomic_read(v) ((v)->counter) 26#define atomic_set(v,i) (((v)->counter) = (i)) 27 28/* These should be written in asm but we do it in C for now. */ 29 30static __inline__ void atomic_add(int i, volatile atomic_t *v) 31{ 32 unsigned long flags; 33 save_flags(flags); 34 cli(); 35 v->counter += i; 36 restore_flags(flags); 37} 38 39static __inline__ void atomic_sub(int i, volatile atomic_t *v) 40{ 41 unsigned long flags; 42 save_flags(flags); 43 cli(); 44 v->counter -= i; 45 restore_flags(flags); 46} 47 48static __inline__ int atomic_add_return(int i, volatile atomic_t *v) 49{ 50 unsigned long flags; 51 int retval; 52 save_flags(flags); 53 cli(); 54 retval = (v->counter += i); 55 restore_flags(flags); 56 return retval; 57} 58 59static __inline__ int atomic_sub_return(int i, volatile atomic_t *v) 60{ 61 unsigned long flags; 62 int retval; 63 save_flags(flags); 64 cli(); 65 retval = (v->counter -= i); 66 restore_flags(flags); 67 return retval; 68} 69 70static __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v) 71{ 72 int retval; 73 unsigned long flags; 74 save_flags(flags); 75 cli(); 76 retval = (v->counter -= i) == 0; 77 restore_flags(flags); 78 return retval; 79} 80 81static __inline__ void atomic_inc(volatile atomic_t *v) 82{ 83 unsigned long flags; 84 save_flags(flags); 85 cli(); 86 (v->counter)++; 87 restore_flags(flags); 88} 89 90static __inline__ void atomic_dec(volatile atomic_t *v) 91{ 92 unsigned long flags; 93 save_flags(flags); 94 cli(); 95 (v->counter)--; 96 restore_flags(flags); 97} 98 99static __inline__ int atomic_inc_return(volatile atomic_t *v) 100{ 101 unsigned long flags; 102 int retval; 103 save_flags(flags); 104 cli(); 105 retval = (v->counter)++; 106 restore_flags(flags); 107 return retval; 108} 109 110static __inline__ int atomic_dec_return(volatile atomic_t *v) 111{ 112 unsigned long flags; 113 int retval; 114 save_flags(flags); 115 cli(); 116 retval = (v->counter)--; 117 restore_flags(flags); 118 return retval; 119} 120static __inline__ int atomic_dec_and_test(volatile atomic_t *v) 121{ 122 int retval; 123 unsigned long flags; 124 save_flags(flags); 125 cli(); 126 retval = --(v->counter) == 0; 127 restore_flags(flags); 128 return retval; 129} 130 131static __inline__ int atomic_inc_and_test(volatile atomic_t *v) 132{ 133 int retval; 134 unsigned long flags; 135 save_flags(flags); 136 cli(); 137 retval = ++(v->counter) == 0; 138 restore_flags(flags); 139 return retval; 140} 141 142/* Atomic operations are already serializing */ 143#define smp_mb__before_atomic_dec() barrier() 144#define smp_mb__after_atomic_dec() barrier() 145#define smp_mb__before_atomic_inc() barrier() 146#define smp_mb__after_atomic_inc() barrier() 147 148#endif 149