at v4.15 2.7 kB view raw
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 * 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 */ 18typedef 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 */ 29static 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 */ 40static inline unsigned int refcount_read(const refcount_t *r) 41{ 42 return atomic_read(&r->refs); 43} 44 45#ifdef CONFIG_REFCOUNT_FULL 46extern __must_check bool refcount_add_not_zero(unsigned int i, refcount_t *r); 47extern void refcount_add(unsigned int i, refcount_t *r); 48 49extern __must_check bool refcount_inc_not_zero(refcount_t *r); 50extern void refcount_inc(refcount_t *r); 51 52extern __must_check bool refcount_sub_and_test(unsigned int i, refcount_t *r); 53 54extern __must_check bool refcount_dec_and_test(refcount_t *r); 55extern void refcount_dec(refcount_t *r); 56#else 57# ifdef CONFIG_ARCH_HAS_REFCOUNT 58# include <asm/refcount.h> 59# else 60static 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 65static inline void refcount_add(unsigned int i, refcount_t *r) 66{ 67 atomic_add(i, &r->refs); 68} 69 70static inline __must_check bool refcount_inc_not_zero(refcount_t *r) 71{ 72 return atomic_add_unless(&r->refs, 1, 0); 73} 74 75static inline void refcount_inc(refcount_t *r) 76{ 77 atomic_inc(&r->refs); 78} 79 80static 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 85static inline __must_check bool refcount_dec_and_test(refcount_t *r) 86{ 87 return atomic_dec_and_test(&r->refs); 88} 89 90static 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 97extern __must_check bool refcount_dec_if_one(refcount_t *r); 98extern __must_check bool refcount_dec_not_one(refcount_t *r); 99extern __must_check bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock); 100extern __must_check bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock); 101 102#endif /* _LINUX_REFCOUNT_H */