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