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