android (3)

本文深入解析了Android系统中BINDER机制中的flush方法及其内部实现,包括binder_defer_work函数如何延迟工作,并通过红黑树遍历和唤醒等待队列来优化系统性能。此外,文章详细阐述了binder_ioctl命令处理过程中的引用计数检查和错误处理机制,旨在提高开发者对BINDER机制的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

android (3)

2011-7-15 18:55:01

看看这个flush方法

static int binder_flush(struct file *filp, fl_owner_t id)
{
 struct binder_proc *proc = filp->private_data;

 binder_defer_work(proc, BINDER_DEFERRED_FLUSH);

 return 0;
}

直接调用 binder_defer_work

static void
binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer)
{
 mutex_lock(&binder_deferred_lock);
 proc->deferred_work |= defer;
 if (hlist_unhashed(&proc->deferred_work_node)) {
  hlist_add_head(&proc->deferred_work_node,
    &binder_deferred_list);
  queue_work(binder_deferred_workqueue, &binder_deferred_work);
 }
 mutex_unlock(&binder_deferred_lock);
}


static DECLARE_WORK(binder_deferred_work, binder_deferred_func);

 

struct binder_thread {
 struct binder_proc *proc;
 struct rb_node rb_node;
 int pid;
 int looper;
 struct binder_transaction *transaction_stack;
 struct list_head todo;
 uint32_t return_error; /* Write failed, return error code in read buf */
 uint32_t return_error2; /* Write failed, return error code in read */
  /* buffer. Used when sending a reply to a dead process that */
  /* we are also waiting on */
 wait_queue_head_t wait;
 struct binder_stats stats;
};


这个结构体中有一个 struct rb_node rb_node; 字段

这个字段被红黑树串起来

binder_proc 的threads 字段就是根节点

binder_deferred_flush

延迟刷  逐一变量红黑树上的所有节点,唤醒所有的等待队列

唤醒 binder_proc 上的等待队列

binder_get_thread

获取当前线程使用的binder_thread 结构

如果当前线程没有binder_thread ,就创建一个 并且插入到rb树中


binder_ioctl

读写命令

struct binder_write_read {
 signed long write_size; /* bytes to write */
 signed long write_consumed; /* bytes consumed by driver */
 unsigned long write_buffer;
 signed long read_size; /* bytes to read */
 signed long read_consumed; /* bytes consumed by driver */
 unsigned long read_buffer;
};


struct binder_stats {
 int br[_IOC_NR(BR_FAILED_REPLY) + 1];
 int bc[_IOC_NR(BC_DEAD_BINDER_DONE) + 1];
 int obj_created[BINDER_STAT_COUNT];
 int obj_deleted[BINDER_STAT_COUNT];
};

static struct binder_stats binder_stats;

binder的所有状态

  if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) {
   binder_stats.bc[_IOC_NR(cmd)]++;
   proc->stats.bc[_IOC_NR(cmd)]++;
   thread->stats.bc[_IOC_NR(cmd)]++;
  }

所有的命令计数加1

命令结构

前4个字节表示命令
后4个字节表示目标


   if (target == 0 && binder_context_mgr_node &&
       (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) {
      
  如果目标为 0 且   binder_context_mgr_node 不为NULL
  命令为增加引用和查询
 
    ref = binder_get_ref_for_node(proc,
            binder_context_mgr_node);
    if (ref->desc != target) {
     binder_user_error("binder: %d:"
      "%d tried to acquire "
      "reference to desc 0, "
      "got %d instead\n",
      proc->pid, thread->pid,
      ref->desc);
    }
   } else
    ref = binder_get_ref(proc, target);
    
    
 
 
 binder_get_ref_for_node
      
   成员refs_by_node 是 binder_node 地址组成的红黑树的跟节点
   
  现在遍历这一棵树,如果找不到binder_node
  
  就创建一个bind_ref
  
  struct binder_ref {
 /* Lookups needed: */
 /*   node + proc => ref (transaction) */
 /*   desc + proc => ref (transaction, inc/dec ref) */
 /*   node => refs + procs (proc exit) */
 int debug_id;
 struct rb_node rb_node_desc;
 struct rb_node rb_node_node;
 struct hlist_node node_entry;
 struct binder_proc *proc;
 struct binder_node *node;
 uint32_t desc;
 int strong;
 int weak;
 struct binder_ref_death *death;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值