atomic.h 3.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5
/* $Id: atomic.h,v 1.3 2001/07/25 16:15:19 bjornw Exp $ */

#ifndef __ASM_CRIS_ATOMIC__
#define __ASM_CRIS_ATOMIC__

6
#include <linux/compiler.h>
7
#include <linux/types.h>
L
Linus Torvalds 已提交
8
#include <asm/system.h>
9
#include <arch/atomic.h>
L
Linus Torvalds 已提交
10 11 12 13 14 15 16 17 18 19 20 21 22

/*
 * Atomic operations that C can't guarantee us.  Useful for
 * resource counting etc..
 */

#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. */

23
static inline void atomic_add(int i, volatile atomic_t *v)
L
Linus Torvalds 已提交
24 25
{
	unsigned long flags;
M
Mikael Starvik 已提交
26
	cris_atomic_save(v, flags);
L
Linus Torvalds 已提交
27
	v->counter += i;
M
Mikael Starvik 已提交
28
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
29 30
}

31
static inline void atomic_sub(int i, volatile atomic_t *v)
L
Linus Torvalds 已提交
32 33
{
	unsigned long flags;
M
Mikael Starvik 已提交
34
	cris_atomic_save(v, flags);
L
Linus Torvalds 已提交
35
	v->counter -= i;
M
Mikael Starvik 已提交
36
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
37 38
}

39
static inline int atomic_add_return(int i, volatile atomic_t *v)
L
Linus Torvalds 已提交
40 41 42
{
	unsigned long flags;
	int retval;
M
Mikael Starvik 已提交
43
	cris_atomic_save(v, flags);
L
Linus Torvalds 已提交
44
	retval = (v->counter += i);
M
Mikael Starvik 已提交
45
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
46 47 48 49 50
	return retval;
}

#define atomic_add_negative(a, v)	(atomic_add_return((a), (v)) < 0)

51
static inline int atomic_sub_return(int i, volatile atomic_t *v)
L
Linus Torvalds 已提交
52 53 54
{
	unsigned long flags;
	int retval;
M
Mikael Starvik 已提交
55
	cris_atomic_save(v, flags);
L
Linus Torvalds 已提交
56
	retval = (v->counter -= i);
M
Mikael Starvik 已提交
57
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
58 59 60
	return retval;
}

61
static inline int atomic_sub_and_test(int i, volatile atomic_t *v)
L
Linus Torvalds 已提交
62 63 64
{
	int retval;
	unsigned long flags;
M
Mikael Starvik 已提交
65
	cris_atomic_save(v, flags);
L
Linus Torvalds 已提交
66
	retval = (v->counter -= i) == 0;
M
Mikael Starvik 已提交
67
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
68 69 70
	return retval;
}

71
static inline void atomic_inc(volatile atomic_t *v)
L
Linus Torvalds 已提交
72 73
{
	unsigned long flags;
M
Mikael Starvik 已提交
74
	cris_atomic_save(v, flags);
L
Linus Torvalds 已提交
75
	(v->counter)++;
M
Mikael Starvik 已提交
76
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
77 78
}

79
static inline void atomic_dec(volatile atomic_t *v)
L
Linus Torvalds 已提交
80 81
{
	unsigned long flags;
M
Mikael Starvik 已提交
82
	cris_atomic_save(v, flags);
L
Linus Torvalds 已提交
83
	(v->counter)--;
M
Mikael Starvik 已提交
84
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
85 86
}

87
static inline int atomic_inc_return(volatile atomic_t *v)
L
Linus Torvalds 已提交
88 89 90
{
	unsigned long flags;
	int retval;
M
Mikael Starvik 已提交
91
	cris_atomic_save(v, flags);
92
	retval = ++(v->counter);
M
Mikael Starvik 已提交
93
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
94 95 96
	return retval;
}

97
static inline int atomic_dec_return(volatile atomic_t *v)
L
Linus Torvalds 已提交
98 99 100
{
	unsigned long flags;
	int retval;
M
Mikael Starvik 已提交
101
	cris_atomic_save(v, flags);
102
	retval = --(v->counter);
M
Mikael Starvik 已提交
103
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
104 105
	return retval;
}
106
static inline int atomic_dec_and_test(volatile atomic_t *v)
L
Linus Torvalds 已提交
107 108 109
{
	int retval;
	unsigned long flags;
M
Mikael Starvik 已提交
110
	cris_atomic_save(v, flags);
L
Linus Torvalds 已提交
111
	retval = --(v->counter) == 0;
M
Mikael Starvik 已提交
112
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
113 114 115
	return retval;
}

116
static inline int atomic_inc_and_test(volatile atomic_t *v)
L
Linus Torvalds 已提交
117 118 119
{
	int retval;
	unsigned long flags;
M
Mikael Starvik 已提交
120
	cris_atomic_save(v, flags);
L
Linus Torvalds 已提交
121
	retval = ++(v->counter) == 0;
M
Mikael Starvik 已提交
122
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
123 124 125
	return retval;
}

N
Nick Piggin 已提交
126 127 128 129 130 131 132 133 134 135 136 137 138
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;
}

139 140
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))

N
Nick Piggin 已提交
141 142 143 144 145 146 147 148 149 150 151 152 153 154
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)

L
Linus Torvalds 已提交
155 156 157 158 159 160
/* 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()

161
#include <asm-generic/atomic-long.h>
L
Linus Torvalds 已提交
162
#endif