| 1 |
|
| 2 | #ifndef _ASM_GENERIC_LOCAL_H
|
| 3 | #define _ASM_GENERIC_LOCAL_H
|
| 4 |
|
| 5 | #include <linux/percpu.h>
|
| 6 | #include <linux/atomic.h>
|
| 7 | #include <asm/types.h>
|
| 8 |
|
| 9 | |
| 10 | * A signed long type for operations which are atomic for a single CPU.
|
| 11 | * Usually used in combination with per-cpu variables.
|
| 12 | *
|
| 13 | * This is the default implementation, which uses atomic_long_t. Which is
|
| 14 | * rather pointless. The whole point behind local_t is that some processors
|
| 15 | * can perform atomic adds and subtracts in a manner which is atomic wrt IRQs
|
| 16 | * running on this CPU. local_t allows exploitation of such capabilities.
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 | typedef struct
|
| 23 | {
|
| 24 | atomic_long_t a;
|
| 25 | } local_t;
|
| 26 |
|
| 27 | #define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
|
| 28 |
|
| 29 | #define local_read(l) atomic_long_read(&(l)->a)
|
| 30 | #define local_set(l,i) atomic_long_set((&(l)->a),(i))
|
| 31 | #define local_inc(l) atomic_long_inc(&(l)->a)
|
| 32 | #define local_dec(l) atomic_long_dec(&(l)->a)
|
| 33 | #define local_add(i,l) atomic_long_add((i),(&(l)->a))
|
| 34 | #define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
|
| 35 |
|
| 36 | #define local_sub_and_test(i, l) atomic_long_sub_and_test((i), (&(l)->a))
|
| 37 | #define local_dec_and_test(l) atomic_long_dec_and_test(&(l)->a)
|
| 38 | #define local_inc_and_test(l) atomic_long_inc_and_test(&(l)->a)
|
| 39 | #define local_add_negative(i, l) atomic_long_add_negative((i), (&(l)->a))
|
| 40 | #define local_add_return(i, l) atomic_long_add_return((i), (&(l)->a))
|
| 41 | #define local_sub_return(i, l) atomic_long_sub_return((i), (&(l)->a))
|
| 42 | #define local_inc_return(l) atomic_long_inc_return(&(l)->a)
|
| 43 |
|
| 44 | #define local_cmpxchg(l, o, n) atomic_long_cmpxchg((&(l)->a), (o), (n))
|
| 45 | #define local_try_cmpxchg(l, po, n) atomic_long_try_cmpxchg((&(l)->a), (po), (n))
|
| 46 | #define local_xchg(l, n) atomic_long_xchg((&(l)->a), (n))
|
| 47 | #define local_add_unless(l, _a, u) atomic_long_add_unless((&(l)->a), (_a), (u))
|
| 48 | #define local_inc_not_zero(l) atomic_long_inc_not_zero(&(l)->a)
|
| 49 |
|
| 50 | |
| 51 | * in interrupt, etc. Some archs can optimize this case well.
|
| 52 | #define __local_inc(l) local_set((l), local_read(l) + 1)
|
| 53 | #define __local_dec(l) local_set((l), local_read(l) - 1)
|
| 54 | #define __local_add(i,l) local_set((l), local_read(l) + (i))
|
| 55 | #define __local_sub(i,l) local_set((l), local_read(l) - (i))
|
| 56 |
|
| 57 | #endif
|