The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/lib/kref.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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  */
   22 void 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  */
   32 void 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  */
   53 int 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  */
   81 int 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 
   94 EXPORT_SYMBOL(kref_init);
   95 EXPORT_SYMBOL(kref_get);
   96 EXPORT_SYMBOL(kref_put);
   97 EXPORT_SYMBOL(kref_sub);

Cache object: 11d228e3fd0ff2b2f283355e745398be


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.