Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5270 serge 1
/* Atomic operations usable in machine independent code */
2
#ifndef _LINUX_ATOMIC_H
3
#define _LINUX_ATOMIC_H
4
#include 
5
 
6
/**
7
 * atomic_add_unless - add unless the number is already a given value
8
 * @v: pointer of type atomic_t
9
 * @a: the amount to add to v...
10
 * @u: ...unless v is equal to u.
11
 *
12
 * Atomically adds @a to @v, so long as @v was not already @u.
13
 * Returns non-zero if @v was not @u, and zero otherwise.
14
 */
15
static inline int atomic_add_unless(atomic_t *v, int a, int u)
16
{
17
	return __atomic_add_unless(v, a, u) != u;
18
}
19
 
20
/**
21
 * atomic_inc_not_zero - increment unless the number is zero
22
 * @v: pointer of type atomic_t
23
 *
24
 * Atomically increments @v by 1, so long as @v is non-zero.
25
 * Returns non-zero if @v was non-zero, and zero otherwise.
26
 */
27
#ifndef atomic_inc_not_zero
28
#define atomic_inc_not_zero(v)		atomic_add_unless((v), 1, 0)
29
#endif
30
 
31
/**
32
 * atomic_inc_not_zero_hint - increment if not null
33
 * @v: pointer of type atomic_t
34
 * @hint: probable value of the atomic before the increment
35
 *
36
 * This version of atomic_inc_not_zero() gives a hint of probable
37
 * value of the atomic. This helps processor to not read the memory
38
 * before doing the atomic read/modify/write cycle, lowering
39
 * number of bus transactions on some arches.
40
 *
41
 * Returns: 0 if increment was not done, 1 otherwise.
42
 */
43
#ifndef atomic_inc_not_zero_hint
44
static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint)
45
{
46
	int val, c = hint;
47
 
48
	/* sanity test, should be removed by compiler if hint is a constant */
49
	if (!hint)
50
		return atomic_inc_not_zero(v);
51
 
52
	do {
53
		val = atomic_cmpxchg(v, c, c + 1);
54
		if (val == c)
55
			return 1;
56
		c = val;
57
	} while (c);
58
 
59
	return 0;
60
}
61
#endif
62
 
63
#ifndef atomic_inc_unless_negative
64
static inline int atomic_inc_unless_negative(atomic_t *p)
65
{
66
	int v, v1;
67
	for (v = 0; v >= 0; v = v1) {
68
		v1 = atomic_cmpxchg(p, v, v + 1);
69
		if (likely(v1 == v))
70
			return 1;
71
	}
72
	return 0;
73
}
74
#endif
75
 
76
#ifndef atomic_dec_unless_positive
77
static inline int atomic_dec_unless_positive(atomic_t *p)
78
{
79
	int v, v1;
80
	for (v = 0; v <= 0; v = v1) {
81
		v1 = atomic_cmpxchg(p, v, v - 1);
82
		if (likely(v1 == v))
83
			return 1;
84
	}
85
	return 0;
86
}
87
#endif
88
 
89
/*
90
 * atomic_dec_if_positive - decrement by 1 if old value positive
91
 * @v: pointer of type atomic_t
92
 *
93
 * The function returns the old value of *v minus 1, even if
94
 * the atomic variable, v, was not decremented.
95
 */
96
#ifndef atomic_dec_if_positive
97
static inline int atomic_dec_if_positive(atomic_t *v)
98
{
99
	int c, old, dec;
100
	c = atomic_read(v);
101
	for (;;) {
102
		dec = c - 1;
103
		if (unlikely(dec < 0))
104
			break;
105
		old = atomic_cmpxchg((v), c, dec);
106
		if (likely(old == c))
107
			break;
108
		c = old;
109
	}
110
	return dec;
111
}
112
#endif
113
 
114
#ifndef CONFIG_ARCH_HAS_ATOMIC_OR
115
static inline void atomic_or(int i, atomic_t *v)
116
{
117
	int old;
118
	int new;
119
 
120
	do {
121
		old = atomic_read(v);
122
		new = old | i;
123
	} while (atomic_cmpxchg(v, old, new) != old);
124
}
125
#endif /* #ifndef CONFIG_ARCH_HAS_ATOMIC_OR */
126
 
127
#include 
128
#ifdef CONFIG_GENERIC_ATOMIC64
129
#include 
130
#endif
131
#endif /* _LINUX_ATOMIC_H */