11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2932fb06b0898f5883200f1da2e00075f0d70ba9cRobert P. J. Day * kref.h - library routines for handling generic reference counted objects 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2004 IBM Corp. 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * based on kobject.h which was: 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2002-2003 Patrick Mochel <mochel@osdl.org> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2002-2003 Open Source Development Labs 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is released under the GPLv2. 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef _KREF_H_ 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _KREF_H_ 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 186261ddee70174372d6a75601f40719b7a5392f3fGreg Kroah-Hartman#include <linux/bug.h> 196261ddee70174372d6a75601f40719b7a5392f3fGreg Kroah-Hartman#include <linux/atomic.h> 2067175b855bfd6ed95ffeff95532173c07de6432dJames Bottomley#include <linux/kernel.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct kref { 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_t refcount; 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 264af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra/** 274af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * kref_init - initialize object. 284af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * @kref: object in question. 294af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra */ 304af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstrastatic inline void kref_init(struct kref *kref) 314af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra{ 324af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra atomic_set(&kref->refcount, 1); 334af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra} 344af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra 354af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra/** 364af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * kref_get - increment refcount for object. 374af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * @kref: object. 384af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra */ 394af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstrastatic inline void kref_get(struct kref *kref) 404af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra{ 414af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra WARN_ON(!atomic_read(&kref->refcount)); 424af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra atomic_inc(&kref->refcount); 434af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra} 444af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra 454af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra/** 4647dbd7d90ad80edb67822f327241edcab8f3f46fPeter Zijlstra * kref_sub - subtract a number of refcounts for object. 474af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * @kref: object. 4847dbd7d90ad80edb67822f327241edcab8f3f46fPeter Zijlstra * @count: Number of recounts to subtract. 494af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * @release: pointer to the function that will clean up the object when the 504af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * last reference to the object is released. 514af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * This pointer is required, and it is not acceptable to pass kfree 526261ddee70174372d6a75601f40719b7a5392f3fGreg Kroah-Hartman * in as this function. If the caller does pass kfree to this 536261ddee70174372d6a75601f40719b7a5392f3fGreg Kroah-Hartman * function, you will be publicly mocked mercilessly by the kref 546261ddee70174372d6a75601f40719b7a5392f3fGreg Kroah-Hartman * maintainer, and anyone else who happens to notice it. You have 556261ddee70174372d6a75601f40719b7a5392f3fGreg Kroah-Hartman * been warned. 564af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * 5747dbd7d90ad80edb67822f327241edcab8f3f46fPeter Zijlstra * Subtract @count from the refcount, and if 0, call release(). 584af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * Return 1 if the object was removed, otherwise return 0. Beware, if this 594af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * function returns 0, you still can not count on the kref from remaining in 604af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * memory. Only use the return value if you want to see if the kref is now 614af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * gone, not present. 624af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra */ 6347dbd7d90ad80edb67822f327241edcab8f3f46fPeter Zijlstrastatic inline int kref_sub(struct kref *kref, unsigned int count, 6447dbd7d90ad80edb67822f327241edcab8f3f46fPeter Zijlstra void (*release)(struct kref *kref)) 654af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra{ 664af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra WARN_ON(release == NULL); 674af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra 6847dbd7d90ad80edb67822f327241edcab8f3f46fPeter Zijlstra if (atomic_sub_and_test((int) count, &kref->refcount)) { 694af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra release(kref); 704af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra return 1; 714af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra } 724af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra return 0; 734af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra} 744af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra 754af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra/** 7647dbd7d90ad80edb67822f327241edcab8f3f46fPeter Zijlstra * kref_put - decrement refcount for object. 774af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * @kref: object. 784af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * @release: pointer to the function that will clean up the object when the 794af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * last reference to the object is released. 804af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * This pointer is required, and it is not acceptable to pass kfree 816261ddee70174372d6a75601f40719b7a5392f3fGreg Kroah-Hartman * in as this function. If the caller does pass kfree to this 826261ddee70174372d6a75601f40719b7a5392f3fGreg Kroah-Hartman * function, you will be publicly mocked mercilessly by the kref 836261ddee70174372d6a75601f40719b7a5392f3fGreg Kroah-Hartman * maintainer, and anyone else who happens to notice it. You have 846261ddee70174372d6a75601f40719b7a5392f3fGreg Kroah-Hartman * been warned. 854af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * 8647dbd7d90ad80edb67822f327241edcab8f3f46fPeter Zijlstra * Decrement the refcount, and if 0, call release(). 874af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * Return 1 if the object was removed, otherwise return 0. Beware, if this 884af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * function returns 0, you still can not count on the kref from remaining in 894af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * memory. Only use the return value if you want to see if the kref is now 904af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra * gone, not present. 914af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra */ 9247dbd7d90ad80edb67822f327241edcab8f3f46fPeter Zijlstrastatic inline int kref_put(struct kref *kref, void (*release)(struct kref *kref)) 934af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra{ 9447dbd7d90ad80edb67822f327241edcab8f3f46fPeter Zijlstra return kref_sub(kref, 1, release); 954af679cd7cbb0a0d8774b5cdb34bffcaa4e86e52Peter Zijlstra} 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* _KREF_H_ */ 97