Android中使用ioctl方式操作fence

    Android的hwc可以通过ioctl,把buffer data信息送入fb driver,由fb控制acquireFence和retireFence,以达到buffer的producer和consumer互相同步的机制,但是假如我们的hwc没有现成的ioctl可以用,又没有办法改到driver的code,我们还有一个选择:hwc可以打开/dev/sw_sync设备,通过一系列的ioctl来监控和控制fence.

    代码下载地址: https://android.googlesource.com/kernel/exynos.git
    文章中用到的code:
    exynos/include/linux/sync.h
    exynos/drivers/base/sync.c
    exynos/include/linux/sw_sync.h
    exynos/drivers/base/sw_sync.c

    在切入正文之前,我们先来了解下sync_timeline和sync_fence中出现的kref成员.在Android fb driver中的fence机制一文中,由于篇幅所限,没有对kref做过多的解释,在这一篇中我们来了解下kref的实现和工作原理.
关于kref

    sync_timeline和sync_fence中都有一个struct kref kref的成员,这东西是干什么用的呢?
sync_pt中有直接指向sync_timeline和sync_fence的指针,当sync_pt通过这些指针对sync_timeline或sync_fence做一些操作的时候,如果不能保证指向sync_time和sync_fence的指针仍然有效,我们就有大麻烦了.
    kref作为一个引用计数器可以我们帮助管理sync_timeline和sync_fence的生命周期,每当一个新的指针指向sync_time或者sync_fence时,通过kref_get增加计数;当指针不再需要的时候,通过kref_put减小计数;当kref引用为0时,自动调用对应struct的清理函数并释放资源.
那么kref是如何实现呢?其实非常简单,全部code都在单独的一个.h之中:include/linux/kref.h

struct kref {
    atomic_t refcount;
};
kref只有一个原子类型的refcount成员.所有对于refcount的操作都是原子的,不需要加锁.

static inline void kref_init(struct kref *kref)
{
    atomic_set(&kref->refcount, 1); 
}
kref_init初始化refcount的值为1.
static inline void kref_get(struct kref *kref)
{
    WARN_ON(!atomic_read(&kref->refcount));
    atomic_inc(&kref->refcount);
}
kref_get增加refcount的计数.
static inline int kref_sub(struct kref *kref, unsigned int count,
         void (*release)(struct kref *kref))
{
    WARN_ON(release == NULL);

    if (atomic_sub_and_test((int) count, &kref->refcount)) {
        release(kref);
        return 1;
    }
    return 0;
}
kref_sub减小count个refcount的计数,如果recount归零,则调用传进来的release函数指针.
static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref))
{
    return kref_sub(kref, 1, release);
}

kref_put是count为1的kref_sub特例.

我们来看下kref在sync_time,sync_pt之间是如何运用的.

struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
					   int size, const char *name)
{
	struct sync_timeline *obj;
	obj = kzalloc(size, GFP_KERNEL);
	...
	kref_init(&obj->kref);
	...
	return obj;
}
sync_timeline_create的时候,对sync_timeline的kref成员做了初始化,kref->refcount == 1;
static void sync_timeline_free(struct kref *kref)
{
	struct sync_timeline *obj =
		container_of(kref, struct sync_timeline, kref);
	unsigned long flags;

	if (obj->ops->release_obj)
		obj->ops->
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值