1 /* 2 * kref.h - library routines for handling generic reference counted objects 3 * 4 * Copyright (C) 2004 Greg Kroah-Hartman <[email protected]> 5 * Copyright (C) 2004 IBM Corp. 6 * 7 * based on kobject.h which was: 8 * Copyright (C) 2002-2003 Patrick Mochel <[email protected]> 9 * Copyright (C) 2002-2003 Open Source Development Labs 10 * 11 * This file is released under the GPLv2. 12 * 13 */ 14 15 #ifndef _KREF_H_ 16 #define _KREF_H_ 17 18 #include <linux/bug.h> 19 #include <linux/atomic.h> 20 #include <linux/kernel.h> 21 #include <linux/mutex.h> 22 23 struct kref { 24 atomic_t refcount; 25 }; 26 27 /** 28 * kref_init - initialize object. 29 * @kref: object in question. 30 */ 31 static inline void kref_init(struct kref *kref) 32 { 33 atomic_set(&kref->refcount, 1); 34 } 35 36 /** 37 * kref_get - increment refcount for object. 38 * @kref: object. 39 */ 40 static inline void kref_get(struct kref *kref) 41 { 42 WARN_ON(!atomic_read(&kref->refcount)); 43 atomic_inc(&kref->refcount); 44 } 45 46 /** 47 * kref_sub - subtract a number of refcounts for object. 48 * @kref: object. 49 * @count: Number of recounts to subtract. 50 * @release: pointer to the function that will clean up the object when the 51 * last reference to the object is released. 52 * This pointer is required, and it is not acceptable to pass kfree 53 * in as this function. If the caller does pass kfree to this 54 * function, you will be publicly mocked mercilessly by the kref 55 * maintainer, and anyone else who happens to notice it. You have 56 * been warned. 57 * 58 * Subtract @count from the refcount, and if 0, call release(). 59 * Return 1 if the object was removed, otherwise return 0. Beware, if this 60 * function returns 0, you still can not count on the kref from remaining in 61 * memory. Only use the return value if you want to see if the kref is now 62 * gone, not present. 63 */ 64 static inline int kref_sub(struct kref *kref, unsigned int count, 65 void (*release)(struct kref *kref)) 66 { 67 WARN_ON(release == NULL); 68 69 if (atomic_sub_and_test((int) count, &kref->refcount)) { 70 release(kref); 71 return 1; 72 } 73 return 0; 74 } 75 76 /** 77 * kref_put - decrement refcount for object. 78 * @kref: object. 79 * @release: pointer to the function that will clean up the object when the 80 * last reference to the object is released. 81 * This pointer is required, and it is not acceptable to pass kfree 82 * in as this function. If the caller does pass kfree to this 83 * function, you will be publicly mocked mercilessly by the kref 84 * maintainer, and anyone else who happens to notice it. You have 85 * been warned. 86 * 87 * Decrement the refcount, and if 0, call release(). 88 * Return 1 if the object was removed, otherwise return 0. Beware, if this 89 * function returns 0, you still can not count on the kref from remaining in 90 * memory. Only use the return value if you want to see if the kref is now 91 * gone, not present. 92 */ 93 static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref)) 94 { 95 return kref_sub(kref, 1, release); 96 } 97 98 static inline int kref_put_mutex(struct kref *kref, 99 void (*release)(struct kref *kref), 100 struct mutex *lock) 101 { 102 WARN_ON(release == NULL); 103 if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) { 104 mutex_lock(lock); 105 if (unlikely(!atomic_dec_and_test(&kref->refcount))) { 106 mutex_unlock(lock); 107 return 0; 108 } 109 release(kref); 110 return 1; 111 } 112 return 0; 113 } 114 #endif /* _KREF_H_ */ 115