关闭

lk 之dpc

382人阅读 评论(0) 收藏 举报
分类:
lk 中实现了让一组函数串行执行,但不需要新建thread的方式,如果用thread的方式就要用mutex 来同步
这种机制就是dpc,dpc的code都在dpc.c中
我们先看看dpc的init
void dpc_init(void)
{
event_init(&dpc_event, false, 0);


thread_resume(thread_create("dpc", &dpc_thread_routine, NULL, DPC_PRIORITY, DEFAULT_STACK_SIZE));
}
初始化一个dpc_event event,然后new一个dpc thread,并立刻运行,其回调函数是dpc_thread_routine。
static int dpc_thread_routine(void *arg)
{
for (;;) {
event_wait(&dpc_event);


enter_critical_section();
struct dpc *dpc = list_remove_head_type(&dpc_list, struct dpc, node);
if (!dpc)
event_unsignal(&dpc_event);
exit_critical_section();


if (dpc) {
// dprintf("dpc calling %p, arg %p\n", dpc->cb, dpc->arg);
dpc->cb(dpc->arg);


free(dpc);
}
}


return 0;
}
这是个死循环,一直在等dpc_event event。如果等到了就懂dpc_list中哪一个dpc下来执行dpc的cb函数
可见关键是在哪里signal dpc_event 
status_t dpc_queue(dpc_callback cb, void *arg, uint flags)
{
struct dpc *dpc;


dpc = malloc(sizeof(struct dpc));


dpc->cb = cb;
dpc->arg = arg;
enter_critical_section();
list_add_tail(&dpc_list, &dpc->node);
event_signal(&dpc_event, (flags & DPC_FLAG_NORESCHED) ? false : true);
exit_critical_section();


return NO_ERROR;
}
原来是在调用dpc_queue的时候,首先new一个dpc,然后设置cb,再将其加到dpc_list中,发送dpc_event
这样这个cb就会在dpc_thread_routine 中执行.
如果是顺序调用dpc_queue,那cb函数就是顺序执行的,少去了为每个cb new thread并加锁的机制,提供performance.

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:182664次
    • 积分:10038
    • 等级:
    • 排名:第1903名
    • 原创:883篇
    • 转载:0篇
    • 译文:0篇
    • 评论:8条
    最新评论