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;
};