Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #ifndef _ARCH_I386_LOCAL_H |
2 | #define _ARCH_I386_LOCAL_H | |
3 | ||
4 | #include <linux/percpu.h> | |
5 | ||
6 | typedef struct | |
7 | { | |
2cf8d82d | 8 | volatile long counter; |
1da177e4 LT |
9 | } local_t; |
10 | ||
11 | #define LOCAL_INIT(i) { (i) } | |
12 | ||
13 | #define local_read(v) ((v)->counter) | |
14 | #define local_set(v,i) (((v)->counter) = (i)) | |
15 | ||
16 | static __inline__ void local_inc(local_t *v) | |
17 | { | |
18 | __asm__ __volatile__( | |
19 | "incl %0" | |
b862f3b0 | 20 | :"+m" (v->counter)); |
1da177e4 LT |
21 | } |
22 | ||
23 | static __inline__ void local_dec(local_t *v) | |
24 | { | |
25 | __asm__ __volatile__( | |
26 | "decl %0" | |
b862f3b0 | 27 | :"+m" (v->counter)); |
1da177e4 LT |
28 | } |
29 | ||
2cf8d82d | 30 | static __inline__ void local_add(long i, local_t *v) |
1da177e4 LT |
31 | { |
32 | __asm__ __volatile__( | |
33 | "addl %1,%0" | |
b862f3b0 LT |
34 | :"+m" (v->counter) |
35 | :"ir" (i)); | |
1da177e4 LT |
36 | } |
37 | ||
2cf8d82d | 38 | static __inline__ void local_sub(long i, local_t *v) |
1da177e4 LT |
39 | { |
40 | __asm__ __volatile__( | |
41 | "subl %1,%0" | |
b862f3b0 LT |
42 | :"+m" (v->counter) |
43 | :"ir" (i)); | |
1da177e4 LT |
44 | } |
45 | ||
46 | /* On x86, these are no better than the atomic variants. */ | |
47 | #define __local_inc(l) local_inc(l) | |
48 | #define __local_dec(l) local_dec(l) | |
49 | #define __local_add(i,l) local_add((i),(l)) | |
50 | #define __local_sub(i,l) local_sub((i),(l)) | |
51 | ||
52 | /* Use these for per-cpu local_t variables: on some archs they are | |
53 | * much more efficient than these naive implementations. Note they take | |
54 | * a variable, not an address. | |
55 | */ | |
da531125 AK |
56 | |
57 | /* Need to disable preemption for the cpu local counters otherwise we could | |
58 | still access a variable of a previous CPU in a non atomic way. */ | |
59 | #define cpu_local_wrap_v(v) \ | |
60 | ({ local_t res__; \ | |
61 | preempt_disable(); \ | |
62 | res__ = (v); \ | |
63 | preempt_enable(); \ | |
64 | res__; }) | |
65 | #define cpu_local_wrap(v) \ | |
66 | ({ preempt_disable(); \ | |
67 | v; \ | |
68 | preempt_enable(); }) \ | |
69 | ||
70 | #define cpu_local_read(v) cpu_local_wrap_v(local_read(&__get_cpu_var(v))) | |
71 | #define cpu_local_set(v, i) cpu_local_wrap(local_set(&__get_cpu_var(v), (i))) | |
72 | #define cpu_local_inc(v) cpu_local_wrap(local_inc(&__get_cpu_var(v))) | |
73 | #define cpu_local_dec(v) cpu_local_wrap(local_dec(&__get_cpu_var(v))) | |
74 | #define cpu_local_add(i, v) cpu_local_wrap(local_add((i), &__get_cpu_var(v))) | |
75 | #define cpu_local_sub(i, v) cpu_local_wrap(local_sub((i), &__get_cpu_var(v))) | |
1da177e4 LT |
76 | |
77 | #define __cpu_local_inc(v) cpu_local_inc(v) | |
78 | #define __cpu_local_dec(v) cpu_local_dec(v) | |
79 | #define __cpu_local_add(i, v) cpu_local_add((i), (v)) | |
80 | #define __cpu_local_sub(i, v) cpu_local_sub((i), (v)) | |
81 | ||
82 | #endif /* _ARCH_I386_LOCAL_H */ |