atomic.h 3.2 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>
8
#include <asm/cmpxchg.h>
9
#include <arch/atomic.h>
P
Peter Zijlstra 已提交
10 11
#include <arch/system.h>
#include <asm/barrier.h>
L
Linus Torvalds 已提交
12 13 14 15 16 17 18 19

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

#define ATOMIC_INIT(i)  { (i) }

20
#define atomic_read(v) ACCESS_ONCE((v)->counter)
L
Linus Torvalds 已提交
21 22 23 24
#define atomic_set(v,i) (((v)->counter) = (i))

/* These should be written in asm but we do it in C for now. */

25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
#define ATOMIC_OP(op, c_op)						\
static inline void atomic_##op(int i, volatile atomic_t *v)		\
{									\
	unsigned long flags;						\
	cris_atomic_save(v, flags);					\
	v->counter c_op i;						\
	cris_atomic_restore(v, flags);					\
}									\

#define ATOMIC_OP_RETURN(op, c_op)					\
static inline int atomic_##op##_return(int i, volatile atomic_t *v)	\
{									\
	unsigned long flags;						\
	int retval;							\
	cris_atomic_save(v, flags);					\
	retval = (v->counter c_op i);					\
	cris_atomic_restore(v, flags);					\
	return retval;							\
L
Linus Torvalds 已提交
43 44
}

45
#define ATOMIC_OPS(op, c_op) ATOMIC_OP(op, c_op) ATOMIC_OP_RETURN(op, c_op)
L
Linus Torvalds 已提交
46

47 48
ATOMIC_OPS(add, +=)
ATOMIC_OPS(sub, -=)
L
Linus Torvalds 已提交
49

50 51 52
#undef ATOMIC_OPS
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
L
Linus Torvalds 已提交
53

54
#define atomic_add_negative(a, v)	(atomic_add_return((a), (v)) < 0)
L
Linus Torvalds 已提交
55

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

66
static inline void atomic_inc(volatile atomic_t *v)
L
Linus Torvalds 已提交
67 68
{
	unsigned long flags;
M
Mikael Starvik 已提交
69
	cris_atomic_save(v, flags);
L
Linus Torvalds 已提交
70
	(v->counter)++;
M
Mikael Starvik 已提交
71
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
72 73
}

74
static inline void atomic_dec(volatile atomic_t *v)
L
Linus Torvalds 已提交
75 76
{
	unsigned long flags;
M
Mikael Starvik 已提交
77
	cris_atomic_save(v, flags);
L
Linus Torvalds 已提交
78
	(v->counter)--;
M
Mikael Starvik 已提交
79
	cris_atomic_restore(v, flags);
L
Linus Torvalds 已提交
80 81
}

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

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

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

N
Nick Piggin 已提交
121 122 123 124 125 126 127 128 129 130 131 132 133
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;
}

134 135
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))

136
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
N
Nick Piggin 已提交
137 138 139 140 141 142 143 144 145
{
	int ret;
	unsigned long flags;

	cris_atomic_save(v, flags);
	ret = v->counter;
	if (ret != u)
		v->counter += a;
	cris_atomic_restore(v, flags);
146
	return ret;
N
Nick Piggin 已提交
147 148
}

L
Linus Torvalds 已提交
149
#endif