zircon的dpc机制

zircon中的dpc 机制由于减少系统中的线程,用户可以将要执行函数发给dpc
dpc的入口函数如下:
static void dpc_init(unsigned int level) {
    // initialize dpc for the main CPU
    dpc_init_for_cpu();
}
dpc_init_for_cpu 会为当前cpu 创建一个dpc thread

void dpc_init_for_cpu(void) {
#获得当前cpu 对应的percpu 变量
    struct percpu* cpu = get_local_percpu();
#获得当前cpu id
    uint cpu_num = arch_curr_cpu_num();
#初始化这个cpu 用到的event
    // the cpu's dpc state was initialized on a previous hotplug event
    if (event_initialized(&cpu->dpc_event)) {
        return;
    }
#初始化用于接收任务的list
    list_initialize(&cpu->dpc_list);
    event_init(&cpu->dpc_event, false, 0);
    cpu->dpc_stop = false;

    char name[10];
#每个cpu 都有一个dpc thread,用于接收任务
    snprintf(name, sizeof(name), "dpc-%u", cpu_num);
#创建dpc线程
    cpu->dpc_thread = thread_create(name, &dpc_thread, NULL, DPC_THREAD_PRIORITY);
    DEBUG_ASSERT(cpu->dpc_thread != nullptr);
#设置dpc 线程的亲和性,即这个线程只能运行在这个cpu上
    thread_set_cpu_affinity(cpu->dpc_thread, cpu_num_to_mask(cpu_num));
#dpc线程开始工作,也就是说通过thread_create创建的线程还不能立刻投入运行,直到调用
#thread_resume 后才可以工作
    thread_resume(cpu->dpc_thread);
}
下来看看dpc的工作线程
static int dpc_thread(void* arg) {
 
    arch_interrupt_restore(state, SPIN_LOCK_FLAG_INTERRUPTS);

    for (;;) {
        // wait for a dpc to fire
        __UNUSED zx_status_t err = event_wait(event);
        DEBUG_ASSERT(err == ZX_OK);

        spin_lock_irqsave(&dpc_lock, state);

        if (cpu->dpc_stop) {
            spin_unlock_irqrestore(&dpc_lock, state);
            return 0;
        }
#可以看到从dpc的list上拿到要工作的task
        // pop a dpc off the list, make a local copy.
        dpc_t* dpc = list_remove_head_type(list, dpc_t, node);

        // if the list is now empty, unsignal the event so we block until it is
        if (!dpc) {
            event_unsignal(event);
            dpc_local.func = NULL;
        } else {
            dpc_local = *dpc;
        }

        spin_unlock_irqrestore(&dpc_lock, state);
#开始执行要执行的函数
        // call the dpc
        if (dpc_local.func) {
            dpc_local.func(&dpc_local);
        }
    }

    return 0;
}

通过dpc_queue 可以向dpc的工作线程提交任务
zx_status_t dpc_queue(dpc_t* dpc, bool reschedule) {
    DEBUG_ASSERT(dpc);
    DEBUG_ASSERT(dpc->func);

    // disable interrupts before finding lock
    spin_lock_saved_state_t state;
    spin_lock_irqsave(&dpc_lock, state);

    if (list_in_list(&dpc->node)) {
        spin_unlock_irqrestore(&dpc_lock, state);
        return ZX_ERR_ALREADY_EXISTS;
    }
#只能向当前cpu的dpc 提交
    struct percpu* cpu = get_local_percpu();
#加入到当前dpc 的全局list中
    // put the dpc at the tail of the list and signal the worker
    list_add_tail(&cpu->dpc_list, &dpc->node);

    spin_unlock_irqrestore(&dpc_lock, state);
#发送event 来让dpc工作线程开始工作
    event_signal(&cpu->dpc_event, reschedule);

    return ZX_OK;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值