Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9779
  • 博文数量: 5
  • 博客积分: 230
  • 博客等级: 二等列兵
  • 技术积分: 60
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-25 14:12
文章分类

全部博文(5)

文章存档

2011年(1)

2010年(3)

2009年(1)

我的朋友
最近访客

分类: LINUX

2010-11-08 17:09:05

引用计数是编程里面常用的资源管理技巧,linux内核也不例外。所谓引用计数就是记录下某个资源使用者的个数,每个使用者释放该资源时,计数减一,当计数变为0时,表示所有使用者都不需要该资源了,所以资源就释放了。

linux内核里面实现了一个通用的引用计数例程(include/linux/kref.h,  lib/kref.c).

struct kref {
        /* 使用一个原子变量表示引用技术 */
atomic_t refcount;
};

/**
 * kref_set - initialize object and set refcount to requested number.
 * @kref: object in question.
 * @num: initial reference counter
 */
void kref_set(struct kref *kref, int num)
{
        /* 将原子变量refcount 置成num */
atomic_set(&kref->refcount, num);
smp_mb();
}

/**
 * kref_init - initialize object.
 * @kref: object in question.
 */
void kref_init(struct kref *kref)
{
        /* 初始值是 1 而不是 0 */
kref_set(kref, 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);
smp_mb__after_atomic_inc();
}

/**
 * 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().
 * Return 1 if the object was removed, otherwise return 0.  Beware, if this
 * function returns 0, you still can not count on the kref from remaining in
 * memory.  Only use the return value if you want to see if the kref is now
 * gone, not present.
 */
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;
}

这里用了很多membar, 这是为了保证内存访问顺序。

阅读(305) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~