11da177e4SLinus Torvalds #ifndef _ASM_GENERIC_LOCAL_H 21da177e4SLinus Torvalds #define _ASM_GENERIC_LOCAL_H 31da177e4SLinus Torvalds 41da177e4SLinus Torvalds #include <linux/config.h> 51da177e4SLinus Torvalds #include <linux/percpu.h> 61da177e4SLinus Torvalds #include <linux/hardirq.h> 7*f5f5370dSKyle McMartin #include <asm/atomic.h> 81da177e4SLinus Torvalds #include <asm/types.h> 91da177e4SLinus Torvalds 101da177e4SLinus Torvalds /* An unsigned long type for operations which are atomic for a single 111da177e4SLinus Torvalds * CPU. Usually used in combination with per-cpu variables. */ 121da177e4SLinus Torvalds 131da177e4SLinus Torvalds /* Implement in terms of atomics. */ 141da177e4SLinus Torvalds 151da177e4SLinus Torvalds /* Don't use typedef: don't want them to be mixed with atomic_t's. */ 161da177e4SLinus Torvalds typedef struct 171da177e4SLinus Torvalds { 18*f5f5370dSKyle McMartin atomic_long_t a; 191da177e4SLinus Torvalds } local_t; 201da177e4SLinus Torvalds 21*f5f5370dSKyle McMartin #define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } 221da177e4SLinus Torvalds 23*f5f5370dSKyle McMartin #define local_read(l) ((unsigned long)atomic_long_read(&(l)->a)) 24*f5f5370dSKyle McMartin #define local_set(l,i) atomic_long_set((&(l)->a),(i)) 25*f5f5370dSKyle McMartin #define local_inc(l) atomic_long_inc(&(l)->a) 26*f5f5370dSKyle McMartin #define local_dec(l) atomic_long_dec(&(l)->a) 27*f5f5370dSKyle McMartin #define local_add(i,l) atomic_long_add((i),(&(l)->a)) 28*f5f5370dSKyle McMartin #define local_sub(i,l) atomic_long_sub((i),(&(l)->a)) 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds /* Non-atomic variants, ie. preemption disabled and won't be touched 311da177e4SLinus Torvalds * in interrupt, etc. Some archs can optimize this case well. */ 321da177e4SLinus Torvalds #define __local_inc(l) local_set((l), local_read(l) + 1) 331da177e4SLinus Torvalds #define __local_dec(l) local_set((l), local_read(l) - 1) 341da177e4SLinus Torvalds #define __local_add(i,l) local_set((l), local_read(l) + (i)) 351da177e4SLinus Torvalds #define __local_sub(i,l) local_set((l), local_read(l) - (i)) 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds /* Use these for per-cpu local_t variables: on some archs they are 381da177e4SLinus Torvalds * much more efficient than these naive implementations. Note they take 391da177e4SLinus Torvalds * a variable (eg. mystruct.foo), not an address. 401da177e4SLinus Torvalds */ 411da177e4SLinus Torvalds #define cpu_local_read(v) local_read(&__get_cpu_var(v)) 421da177e4SLinus Torvalds #define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i)) 431da177e4SLinus Torvalds #define cpu_local_inc(v) local_inc(&__get_cpu_var(v)) 441da177e4SLinus Torvalds #define cpu_local_dec(v) local_dec(&__get_cpu_var(v)) 451da177e4SLinus Torvalds #define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v)) 461da177e4SLinus Torvalds #define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v)) 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds /* Non-atomic increments, ie. preemption disabled and won't be touched 491da177e4SLinus Torvalds * in interrupt, etc. Some archs can optimize this case well. 501da177e4SLinus Torvalds */ 511da177e4SLinus Torvalds #define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v)) 521da177e4SLinus Torvalds #define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v)) 531da177e4SLinus Torvalds #define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v)) 541da177e4SLinus Torvalds #define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v)) 551da177e4SLinus Torvalds 561da177e4SLinus Torvalds #endif /* _ASM_GENERIC_LOCAL_H */ 57