Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3364742
  • 博文数量: 530
  • 博客积分: 13360
  • 博客等级: 上将
  • 技术积分: 5473
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-13 13:32
文章分类

全部博文(530)

文章存档

2017年(1)

2015年(2)

2013年(24)

2012年(20)

2011年(97)

2010年(240)

2009年(117)

2008年(12)

2007年(8)

2006年(9)

分类: C/C++

2011-06-10 10:19:05

1.概述
1.1引用计数的目的
      检测内核中哦多少地方使用了某个对象。每当内核的一个部分需要某个对象所包含的信息时,该对象的引用计数加1。如果不再需要相应的信息,该对象的引用计数减1。
      增加引用计数称为获得(getting)对象的引用,减少引用计数称为释放(putting)对象的引用。
      如果计数为0时,内核知道不再需要该对象,所以此时从内存中释放该对象。
      它提供了原子引用计数。"原子"表示对该对象的加1和减1在多处理器系统上是安全的,多处理器可能会有多少代码路径访问同一对象。

      开发者现在不必在内核代码中利用atmoic_t类型来实现其自己的引用计数。对开发者而言,在内核代码中最好的方法是利用kref类型和它相应的辅助函数,为自己提供一个通用的、正确的引用计数机制。

1.2 代码简述
      该结构体定义在头文件>
核心代码
  1. #include <linux/types.h>

  2. struct kref {
  3.         atomic_t refcount;
  4. };
  5.  
  6. void kref_init(struct kref *kref);
  7. void kref_get(struct kref *kref);
  8. int kref_put(struct kref *kref, void (*release) (struct kref *kref));
  9. int kref_sub(struct kref *kref, unsigned int count,
  10. void (*release) (struct kref *kref));
atomic_t的代码如下
  1. Linux/include/linux/types.h
  2. typedef struct {
  3.          int counter;
  4. } atomic_t;
kref_init:初始化,计数器的值为1
kref_get:计数器的值加1
kref_put:计数器的值减1

在\lib\kref.c中实现了以上操作
  1. /**
  2.  * kref_set - 初始化对象,并赋初值
  3.  * @kref: 初始化的对象.
  4.  * @num: 初值r
  5.  */
  6. void kref_set(struct kref *kref, int num){
  7.         /* 将原子变量refcount 置成num */
  8.        atomic_set(&kref->refcount, num);
  9.        smp_mb();//确保读出fifo->out 后,再向fifo->buffer写入当前请求的内容
  10. }

  11. /**
  12.  * kref_set - 初始化对象,并赋初值为1
  13.  * @kref: 初始化的对象.
  14.  */
  15. void kref_init(struct kref *kref){
  16.         kref_set(kref, 1);
  17. }

  18. /**
  19.  * kref_get - 将对象中的refcount值加1
  20.  * @kref: object.
  21.  */
  22. void kref_get(struct kref *kref){
  23.         /* 增加引用计数 */
  24.         WARN_ON(!atomic_read(&kref->refcount));
  25.         atomic_inc(&kref->refcount);
  26.         smp_mb__after_atomic_inc();
  27. }

  28. /**
  29.  * kref_put - 将对象中的refcount值减1
  30.  * @kref: object.
  31.  * 如果refcount=0,则调用release().
  32.  * 当对象被释放了,返回1,否则 返回0
  33.  */
  34. int kref_put(struct kref *kref, void (*release)(struct kref *kref)){
  35.        WARN_ON(release == NULL);
  36.        WARN_ON(release == (void (*)(struct kref *))kfree);

  37.          /* 引用计数减1, 如果为0, 则执行释放函数release */
  38.         if (atomic_dec_and_test(&kref->refcount)) {
  39.               release(kref);
  40.               return 1;
  41.         }
  42.         return 0;
  43. }



2.程序举例


参考文献
1.kref.h
2.
3.
4.http://www.cnblogs.com/wwang/archive/2010/12/02/1894847.html
阅读(3299) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~