Blame view

include/asm-alpha/local.h 3.31 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
  #ifndef _ALPHA_LOCAL_H
  #define _ALPHA_LOCAL_H
  
  #include <linux/percpu.h>
  #include <asm/atomic.h>
f43f7b46e   Mathieu Desnoyers   local_t: alpha ex...
6
7
8
9
  typedef struct
  {
  	atomic_long_t a;
  } local_t;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10

f43f7b46e   Mathieu Desnoyers   local_t: alpha ex...
11
12
13
14
15
16
17
  #define LOCAL_INIT(i)	{ ATOMIC_LONG_INIT(i) }
  #define local_read(l)	atomic_long_read(&(l)->a)
  #define local_set(l,i)	atomic_long_set(&(l)->a, (i))
  #define local_inc(l)	atomic_long_inc(&(l)->a)
  #define local_dec(l)	atomic_long_dec(&(l)->a)
  #define local_add(i,l)	atomic_long_add((i),(&(l)->a))
  #define local_sub(i,l)	atomic_long_sub((i),(&(l)->a))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18

f43f7b46e   Mathieu Desnoyers   local_t: alpha ex...
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  static __inline__ long local_add_return(long i, local_t * l)
  {
  	long temp, result;
  	__asm__ __volatile__(
  	"1:	ldq_l %0,%1
  "
  	"	addq %0,%3,%2
  "
  	"	addq %0,%3,%0
  "
  	"	stq_c %0,%1
  "
  	"	beq %0,2f
  "
  	".subsection 2
  "
  	"2:	br 1b
  "
  	".previous"
  	:"=&r" (temp), "=m" (l->a.counter), "=&r" (result)
  	:"Ir" (i), "m" (l->a.counter) : "memory");
  	return result;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42

f43f7b46e   Mathieu Desnoyers   local_t: alpha ex...
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
  static __inline__ long local_sub_return(long i, local_t * l)
  {
  	long temp, result;
  	__asm__ __volatile__(
  	"1:	ldq_l %0,%1
  "
  	"	subq %0,%3,%2
  "
  	"	subq %0,%3,%0
  "
  	"	stq_c %0,%1
  "
  	"	beq %0,2f
  "
  	".subsection 2
  "
  	"2:	br 1b
  "
  	".previous"
  	:"=&r" (temp), "=m" (l->a.counter), "=&r" (result)
  	:"Ir" (i), "m" (l->a.counter) : "memory");
  	return result;
  }
  
  #define local_cmpxchg(l, o, n) \
  	(cmpxchg_local(&((l)->a.counter), (o), (n)))
  #define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
  
  /**
   * local_add_unless - add unless the number is a given value
   * @l: pointer of type local_t
   * @a: the amount to add to l...
   * @u: ...unless l is equal to u.
   *
   * Atomically adds @a to @l, so long as it was not @u.
   * Returns non-zero if @l was not @u, and zero otherwise.
   */
  #define local_add_unless(l, a, u)				\
  ({								\
  	long c, old;						\
  	c = local_read(l);					\
  	for (;;) {						\
  		if (unlikely(c == (u)))				\
  			break;					\
  		old = local_cmpxchg((l), c, c + (a));	\
  		if (likely(old == c))				\
  			break;					\
  		c = old;					\
  	}							\
  	c != (u);						\
  })
  #define local_inc_not_zero(l) local_add_unless((l), 1, 0)
  
  #define local_add_negative(a, l) (local_add_return((a), (l)) < 0)
  
  #define local_dec_return(l) local_sub_return(1,(l))
  
  #define local_inc_return(l) local_add_return(1,(l))
  
  #define local_sub_and_test(i,l) (local_sub_return((i), (l)) == 0)
  
  #define local_inc_and_test(l) (local_add_return(1, (l)) == 0)
  
  #define local_dec_and_test(l) (local_sub_return(1, (l)) == 0)
  
  /* Verify if faster than atomic ops */
  #define __local_inc(l)		((l)->a.counter++)
  #define __local_dec(l)		((l)->a.counter++)
  #define __local_add(i,l)	((l)->a.counter+=(i))
  #define __local_sub(i,l)	((l)->a.counter-=(i))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
116
117
  
  /* Use these for per-cpu local_t variables: on some archs they are
   * much more efficient than these naive implementations.  Note they take
   * a variable, not an address.
   */
f43f7b46e   Mathieu Desnoyers   local_t: alpha ex...
118
119
120
121
122
123
124
125
126
127
128
129
  #define cpu_local_read(l)	local_read(&__get_cpu_var(l))
  #define cpu_local_set(l, i)	local_set(&__get_cpu_var(l), (i))
  
  #define cpu_local_inc(l)	local_inc(&__get_cpu_var(l))
  #define cpu_local_dec(l)	local_dec(&__get_cpu_var(l))
  #define cpu_local_add(i, l)	local_add((i), &__get_cpu_var(l))
  #define cpu_local_sub(i, l)	local_sub((i), &__get_cpu_var(l))
  
  #define __cpu_local_inc(l)	__local_inc(&__get_cpu_var(l))
  #define __cpu_local_dec(l)	__local_dec(&__get_cpu_var(l))
  #define __cpu_local_add(i, l)	__local_add((i), &__get_cpu_var(l))
  #define __cpu_local_sub(i, l)	__local_sub((i), &__get_cpu_var(l))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
131
  
  #endif /* _ALPHA_LOCAL_H */