1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _LINUX_REFCOUNT_H 3 #define _LINUX_REFCOUNT_H 4 5 #include <linux/atomic.h> 6 #include <linux/mutex.h> 7 #include <linux/spinlock.h> 8 #include <linux/kernel.h> 9 10 /** 11 * struct refcount_t - variant of atomic_t specialized for reference counts 12 * @refs: atomic_t counter field 13 * 14 * The counter saturates at UINT_MAX and will not move once 15 * there. This avoids wrapping the counter and causing 'spurious' 16 * use-after-free bugs. 17 */ 18 typedef struct refcount_struct { 19 atomic_t refs; 20 } refcount_t; 21 22 #define REFCOUNT_INIT(n) { .refs = ATOMIC_INIT(n), } 23 24 /** 25 * refcount_set - set a refcount's value 26 * @r: the refcount 27 * @n: value to which the refcount will be set 28 */ 29 static inline void refcount_set(refcount_t *r, unsigned int n) 30 { 31 atomic_set(&r->refs, n); 32 } 33 34 /** 35 * refcount_read - get a refcount's value 36 * @r: the refcount 37 * 38 * Return: the refcount's value 39 */ 40 static inline unsigned int refcount_read(const refcount_t *r) 41 { 42 return atomic_read(&r->refs); 43 } 44 45 #ifdef CONFIG_REFCOUNT_FULL 46 extern __must_check bool refcount_add_not_zero(unsigned int i, refcount_t *r); 47 extern void refcount_add(unsigned int i, refcount_t *r); 48 49 extern __must_check bool refcount_inc_not_zero(refcount_t *r); 50 extern void refcount_inc(refcount_t *r); 51 52 extern __must_check bool refcount_sub_and_test(unsigned int i, refcount_t *r); 53 54 extern __must_check bool refcount_dec_and_test(refcount_t *r); 55 extern void refcount_dec(refcount_t *r); 56 #else 57 # ifdef CONFIG_ARCH_HAS_REFCOUNT 58 # include <asm/refcount.h> 59 # else 60 static inline __must_check bool refcount_add_not_zero(unsigned int i, refcount_t *r) 61 { 62 return atomic_add_unless(&r->refs, i, 0); 63 } 64 65 static inline void refcount_add(unsigned int i, refcount_t *r) 66 { 67 atomic_add(i, &r->refs); 68 } 69 70 static inline __must_check bool refcount_inc_not_zero(refcount_t *r) 71 { 72 return atomic_add_unless(&r->refs, 1, 0); 73 } 74 75 static inline void refcount_inc(refcount_t *r) 76 { 77 atomic_inc(&r->refs); 78 } 79 80 static inline __must_check bool refcount_sub_and_test(unsigned int i, refcount_t *r) 81 { 82 return atomic_sub_and_test(i, &r->refs); 83 } 84 85 static inline __must_check bool refcount_dec_and_test(refcount_t *r) 86 { 87 return atomic_dec_and_test(&r->refs); 88 } 89 90 static inline void refcount_dec(refcount_t *r) 91 { 92 atomic_dec(&r->refs); 93 } 94 # endif /* !CONFIG_ARCH_HAS_REFCOUNT */ 95 #endif /* CONFIG_REFCOUNT_FULL */ 96 97 extern __must_check bool refcount_dec_if_one(refcount_t *r); 98 extern __must_check bool refcount_dec_not_one(refcount_t *r); 99 extern __must_check bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock); 100 extern __must_check bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock); 101 extern __must_check bool refcount_dec_and_lock_irqsave(refcount_t *r, 102 spinlock_t *lock, 103 unsigned long *flags); 104 #endif /* _LINUX_REFCOUNT_H */ 105