ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / asm-cris / atomic.h
1 /* $Id: atomic.h,v 1.3 2001/07/25 16:15:19 bjornw 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
21 typedef 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
30 extern __inline__ void atomic_add(int i, volatile atomic_t *v)
31 {
32         unsigned long flags;
33         local_save_flags(flags);
34         local_irq_disable();
35         v->counter += i;
36         local_irq_restore(flags);
37 }
38
39 extern __inline__ void atomic_sub(int i, volatile atomic_t *v)
40 {
41         unsigned long flags;
42         local_save_flags(flags);
43         local_irq_disable();
44         v->counter -= i;
45         local_irq_restore(flags);
46 }
47
48 extern __inline__ int atomic_add_return(int i, volatile atomic_t *v)
49 {
50         unsigned long flags;
51         int retval;
52         local_save_flags(flags);
53         local_irq_disable();
54         retval = (v->counter += i);
55         local_irq_restore(flags);
56         return retval;
57 }
58
59 extern __inline__ int atomic_sub_return(int i, volatile atomic_t *v)
60 {
61         unsigned long flags;
62         int retval;
63         local_save_flags(flags);
64         local_irq_disable();
65         retval = (v->counter -= i);
66         local_irq_restore(flags);
67         return retval;
68 }
69
70 extern __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v)
71 {
72         int retval;
73         unsigned long flags;
74         local_save_flags(flags);
75         local_irq_disable();
76         retval = (v->counter -= i) == 0;
77         local_irq_restore(flags);
78         return retval;
79 }
80
81 extern __inline__ void atomic_inc(volatile atomic_t *v)
82 {
83         unsigned long flags;
84         local_save_flags(flags);
85         local_irq_disable();
86         (v->counter)++;
87         local_irq_restore(flags);
88 }
89
90 extern __inline__ void atomic_dec(volatile atomic_t *v)
91 {
92         unsigned long flags;
93         local_save_flags(flags);
94         local_irq_disable();
95         (v->counter)--;
96         local_irq_restore(flags);
97 }
98
99 extern __inline__ int atomic_inc_return(volatile atomic_t *v)
100 {
101         unsigned long flags;
102         int retval;
103         local_save_flags(flags);
104         local_irq_disable();
105         retval = (v->counter)++;
106         local_irq_restore(flags);
107         return retval;
108 }
109
110 extern __inline__ int atomic_dec_return(volatile atomic_t *v)
111 {
112         unsigned long flags;
113         int retval;
114         local_save_flags(flags);
115         local_irq_disable();
116         retval = (v->counter)--;
117         local_irq_restore(flags);
118         return retval;
119 }
120 extern __inline__ int atomic_dec_and_test(volatile atomic_t *v)
121 {
122         int retval;
123         unsigned long flags;
124         local_save_flags(flags);
125         local_irq_disable();
126         retval = --(v->counter) == 0;
127         local_irq_restore(flags);
128         return retval;
129 }
130
131 extern __inline__ int atomic_inc_and_test(volatile atomic_t *v)
132 {
133         int retval;
134         unsigned long flags;
135         local_save_flags(flags);
136         local_irq_disable();
137         retval = ++(v->counter) == 0;
138         local_irq_restore(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