1.概述1.1引用计数的目的 检测内核中哦多少地方使用了某个对象。每当内核的一个部分需要某个对象所包含的信息时,该对象的引用计数加1。如果不再需要相应的信息,该对象的引用计数减1。
增加引用计数称为获得(getting)对象的引用,减少引用计数称为释放(putting)对象的引用。 如果计数为0时,内核知道不再需要该对象,所以此时从内存中释放该对象。
它提供了
原子引用计数。"原子"表示对该对象的加1和减1在
多处理器系统上是安全的,多处理器可能会有多少代码路径访问同一对象。
开发者现在不必在内核代码中利用atmoic_t类型来实现其自己的引用计数。对开发者而言,在内核代码中最好的方法是利用kref类型和它相应的辅助函数,为自己提供一个通用的、正确的引用计数机制。
1.2 代码简述 该结构体定义在头文件>
核心代码
- #include <linux/types.h>
-
-
struct kref {
-
atomic_t refcount;
-
};
-
-
void kref_init(struct kref *kref);
-
void kref_get(struct kref *kref);
-
int kref_put(struct kref *kref, void (*release) (struct kref *kref));
-
int kref_sub(struct kref *kref, unsigned int count,
-
void (*release) (struct kref *kref));
atomic_t的代码如下
- Linux/include/linux/types.h
-
typedef struct {
-
int counter;
-
} atomic_t;
kref_init:初始化,计数器的值为1
kref_get:计数器的值加1
kref_put:计数器的值减1
在\lib\kref.c中实现了以上操作
- /**
-
* kref_set - 初始化对象,并赋初值
-
* @kref: 初始化的对象.
-
* @num: 初值r
-
*/
-
void kref_set(struct kref *kref, int num){
-
/* 将原子变量refcount 置成num */
-
atomic_set(&kref->refcount, num);
- smp_mb();//确保读出fifo->out 后,再向fifo->buffer写入当前请求的内容
-
}
-
-
/**
-
* kref_set - 初始化对象,并赋初值为1
-
* @kref: 初始化的对象.
-
*/
-
void kref_init(struct kref *kref){
-
kref_set(kref, 1);
-
}
-
-
/**
-
* kref_get - 将对象中的refcount值加1
-
* @kref: object.
-
*/
-
void kref_get(struct kref *kref){
-
/* 增加引用计数 */
-
WARN_ON(!atomic_read(&kref->refcount));
-
atomic_inc(&kref->refcount);
- smp_mb__after_atomic_inc();
-
}
-
-
/**
-
* kref_put - 将对象中的refcount值减1
-
* @kref: object.
-
* 如果refcount=0,则调用release().
-
* 当对象被释放了,返回1,否则 返回0
-
*/
-
int kref_put(struct kref *kref, void (*release)(struct kref *kref)){
-
WARN_ON(release == NULL);
-
WARN_ON(release == (void (*)(struct kref *))kfree);
-
-
/* 引用计数减1, 如果为0, 则执行释放函数release */
-
if (atomic_dec_and_test(&kref->refcount)) {
-
release(kref);
-
return 1;
-
}
-
return 0;
-
}
2.程序举例
参考文献
1.kref.h
2.
3.
4.http://www.cnblogs.com/wwang/archive/2010/12/02/1894847.html
阅读(3299) | 评论(0) | 转发(0) |