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