linux/lib/kref.c
<<
>>
Prefs
   1/*
   2 * kref.c - library routines for handling generic reference counted objects
   3 *
   4 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
   5 * Copyright (C) 2004 IBM Corp.
   6 *
   7 * based on lib/kobject.c which was:
   8 * Copyright (C) 2002-2003 Patrick Mochel <mochel@osdl.org>
   9 *
  10 * This file is released under the GPLv2.
  11 *
  12 */
  13
  14#include <linux/kref.h>
  15#include <linux/module.h>
  16#include <linux/slab.h>
  17
  18/**
  19 * kref_init - initialize object.
  20 * @kref: object in question.
  21 */
  22void kref_init(struct kref *kref)
  23{
  24        atomic_set(&kref->refcount, 1);
  25        smp_mb();
  26}
  27
  28/**
  29 * kref_get - increment refcount for object.
  30 * @kref: object.
  31 */
  32void kref_get(struct kref *kref)
  33{
  34        WARN_ON(!atomic_read(&kref->refcount));
  35        atomic_inc(&kref->refcount);
  36        smp_mb__after_atomic_inc();
  37}
  38
  39/**
  40 * kref_put - decrement refcount for object.
  41 * @kref: object.
  42 * @release: pointer to the function that will clean up the object when the
  43 *           last reference to the object is released.
  44 *           This pointer is required, and it is not acceptable to pass kfree
  45 *           in as this function.
  46 *
  47 * Decrement the refcount, and if 0, call release().
  48 * Return 1 if the object was removed, otherwise return 0.  Beware, if this
  49 * function returns 0, you still can not count on the kref from remaining in
  50 * memory.  Only use the return value if you want to see if the kref is now
  51 * gone, not present.
  52 */
  53int kref_put(struct kref *kref, void (*release)(struct kref *kref))
  54{
  55        WARN_ON(release == NULL);
  56        WARN_ON(release == (void (*)(struct kref *))kfree);
  57
  58        if (atomic_dec_and_test(&kref->refcount)) {
  59                release(kref);
  60                return 1;
  61        }
  62        return 0;
  63}
  64
  65
  66/**
  67 * kref_sub - subtract a number of refcounts for object.
  68 * @kref: object.
  69 * @count: Number of recounts to subtract.
  70 * @release: pointer to the function that will clean up the object when the
  71 *           last reference to the object is released.
  72 *           This pointer is required, and it is not acceptable to pass kfree
  73 *           in as this function.
  74 *
  75 * Subtract @count from the refcount, and if 0, call release().
  76 * Return 1 if the object was removed, otherwise return 0.  Beware, if this
  77 * function returns 0, you still can not count on the kref from remaining in
  78 * memory.  Only use the return value if you want to see if the kref is now
  79 * gone, not present.
  80 */
  81int kref_sub(struct kref *kref, unsigned int count,
  82             void (*release)(struct kref *kref))
  83{
  84        WARN_ON(release == NULL);
  85        WARN_ON(release == (void (*)(struct kref *))kfree);
  86
  87        if (atomic_sub_and_test((int) count, &kref->refcount)) {
  88                release(kref);
  89                return 1;
  90        }
  91        return 0;
  92}
  93
  94EXPORT_SYMBOL(kref_init);
  95EXPORT_SYMBOL(kref_get);
  96EXPORT_SYMBOL(kref_put);
  97EXPORT_SYMBOL(kref_sub);
  98