.h**
/*
引用计数的实现结构体
*/
#ifndef _KREF_H_
#define _KREF_H_
#ifdef __KERNEL__
#include <linux/types.h>
#include <asm/atomic.h>
/* 引用计数的原理很简单,使用时加1,不用时减1,如果减为0
则调用释放函数。
*/
struct kref {
/* Linux 使用原子变量来计数,这样可以防止多CPU,多进程时的竞态现象发生 */
atomic_t refcount;
};
void kref_init(struct kref *kref);/* 初始化一个引用计数结构体 */
void kref_get(struct kref *kref);/* 增加一个引用计数 */
void kref_put(struct kref *kref, void (*release) (struct kref *kref));/* 减少一个引用计数 */
#endif /* __KERNEL__ */
#endif /* _KREF_H_ */
.11.c
#include <linux/kref.h>
#include <linux/module.h>
/**
* kref_init - initialize object.
* @kref: object in question.
*/
/* 初始化一个引用计数,这里可以看到引用计数初始化为1 */
void kref_init(struct kref *kref)
{
atomic_set(&kref->refcount,1);
}
/**
* kref_get - increment refcount for object.
* @kref: object.
*/
/* 增加一个引用计数,可以发现这里是原子操作 */
void kref_get(struct kref *kref)
{
WARN_ON(!atomic_read(&kref->refcount));
atomic_inc(&kref->refcount);
}
/**
* kref_put - decrement refcount for object.
* @kref: object.
* @release: pointer to the function that will clean up the object when the
* last reference to the object is released.
* This pointer is required, and it is not acceptable to pass kfree
* in as this function.
*
* Decrement the refcount, and if 0, call release().
*/
;/* 减少一个引用计数 */
void kref_put(struct kref *kref, void (*release) (struct kref *kref))
{
WARN_ON(release == NULL);
WARN_ON(release == (void (*)(struct kref *))kfree);
if (atomic_dec_and_test(&kref->refcount))
release(kref);/* 如果引用计数为0,就调用释放函数 */
}