![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0-only */ 0002 /* 0003 * kref.h - library routines for handling generic reference counted objects 0004 * 0005 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> 0006 * Copyright (C) 2004 IBM Corp. 0007 * 0008 * based on kobject.h which was: 0009 * Copyright (C) 2002-2003 Patrick Mochel <mochel@osdl.org> 0010 * Copyright (C) 2002-2003 Open Source Development Labs 0011 */ 0012 0013 #ifndef _KREF_H_ 0014 #define _KREF_H_ 0015 0016 #include <linux/spinlock.h> 0017 #include <linux/refcount.h> 0018 0019 struct kref { 0020 refcount_t refcount; 0021 }; 0022 0023 #define KREF_INIT(n) { .refcount = REFCOUNT_INIT(n), } 0024 0025 /** 0026 * kref_init - initialize object. 0027 * @kref: object in question. 0028 */ 0029 static inline void kref_init(struct kref *kref) 0030 { 0031 refcount_set(&kref->refcount, 1); 0032 } 0033 0034 static inline unsigned int kref_read(const struct kref *kref) 0035 { 0036 return refcount_read(&kref->refcount); 0037 } 0038 0039 /** 0040 * kref_get - increment refcount for object. 0041 * @kref: object. 0042 */ 0043 static inline void kref_get(struct kref *kref) 0044 { 0045 refcount_inc(&kref->refcount); 0046 } 0047 0048 /** 0049 * kref_put - decrement refcount for object. 0050 * @kref: object. 0051 * @release: pointer to the function that will clean up the object when the 0052 * last reference to the object is released. 0053 * This pointer is required, and it is not acceptable to pass kfree 0054 * in as this function. 0055 * 0056 * Decrement the refcount, and if 0, call release(). 0057 * Return 1 if the object was removed, otherwise return 0. Beware, if this 0058 * function returns 0, you still can not count on the kref from remaining in 0059 * memory. Only use the return value if you want to see if the kref is now 0060 * gone, not present. 0061 */ 0062 static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref)) 0063 { 0064 if (refcount_dec_and_test(&kref->refcount)) { 0065 release(kref); 0066 return 1; 0067 } 0068 return 0; 0069 } 0070 0071 static inline int kref_put_mutex(struct kref *kref, 0072 void (*release)(struct kref *kref), 0073 struct mutex *lock) 0074 { 0075 if (refcount_dec_and_mutex_lock(&kref->refcount, lock)) { 0076 release(kref); 0077 return 1; 0078 } 0079 return 0; 0080 } 0081 0082 static inline int kref_put_lock(struct kref *kref, 0083 void (*release)(struct kref *kref), 0084 spinlock_t *lock) 0085 { 0086 if (refcount_dec_and_lock(&kref->refcount, lock)) { 0087 release(kref); 0088 return 1; 0089 } 0090 return 0; 0091 } 0092 0093 /** 0094 * kref_get_unless_zero - Increment refcount for object unless it is zero. 0095 * @kref: object. 0096 * 0097 * Return non-zero if the increment succeeded. Otherwise return 0. 0098 * 0099 * This function is intended to simplify locking around refcounting for 0100 * objects that can be looked up from a lookup structure, and which are 0101 * removed from that lookup structure in the object destructor. 0102 * Operations on such objects require at least a read lock around 0103 * lookup + kref_get, and a write lock around kref_put + remove from lookup 0104 * structure. Furthermore, RCU implementations become extremely tricky. 0105 * With a lookup followed by a kref_get_unless_zero *with return value check* 0106 * locking in the kref_put path can be deferred to the actual removal from 0107 * the lookup structure and RCU lookups become trivial. 0108 */ 0109 static inline int __must_check kref_get_unless_zero(struct kref *kref) 0110 { 0111 return refcount_inc_not_zero(&kref->refcount); 0112 } 0113 #endif /* _KREF_H_ */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |