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

#ifndef __ASM_CRIS_ATOMIC__
#define __ASM_CRIS_ATOMIC__

#include <asm/system.h>
M
Mikael Starvik 已提交
7
#include <asm/arch/atomic.h>
L
Linus Torvalds 已提交
8 9 10 11 12 13

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

M
Mikael Starvik 已提交
14
typedef struct { volatile int counter; } atomic_t;
L
Linus Torvalds 已提交
15 16 17 18 19 20 21 22

#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);
L
Linus Torvalds 已提交
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);
L
Linus Torvalds 已提交
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 126 127 128 129 130 131 132
	return retval;
}

/* 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()

#endif