USB的内核线程 与 完成量之间的关系 赏析

本文深入解析Linux内核中完成量的概念,包括其通过等待队列和原子变量实现的方式,并详细介绍了与之相关的函数和状态管理过程。通过实验验证,清晰展示了这些核心组件在系统级任务协调中的作用。
先看完成量
usb重要的内核线程
睡眠与唤醒
 /**
    看,完成量是由 等待队列 + 原子变量 来实现的。 
    那么,问题是  : 
                他们是怎么样来实现完成量的呢?

    他的初始化函数会将done 设置为0
    再complete()加1,wait_for_completion(以及他衍生出来的函数)减 1 

    再初始化函数中会初始化等待队列,
    这里简单的说一下,具体的请往下看。有实验验证。
 */
struct completion {
    unsigned int done;
    wait_queue_head_t wait;
};

/**
    这个函数 不会 timeout,哈哈。不像wait_for_completion_timeout()函数。
    他们两个再内核中都会调用 schedule_timeout(timeout);只是传入的参数不同罢了。

    那么wait_for_completion()传入的就是这个第二个参数 MAX_SCHEDULE_TIMEOUT。
    而wait_for_completion_timeout()需要你传入一个时间,具体的欣赏再下面。

    看他第三个参数,TASK_UNINTERRUPTIBLE,
    这两个函数底层都会调用__set_current_state(state)函数,
    都会将进程状态设置为 TASK_UNINTERRUPTIBLE。
*/
void __sched wait_for_completion(struct completion *x)
{
    wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);
}

static long __sched wait_for_common(struct completion *x, long timeout, int state)
{
    might_sleep();
    /**
        这里有一个疑问。
        再自旋锁保护的临界区 不能 调用有可能会睡眠的函数的。
        但是 do_wait_for_common() 这个函数 最终可能会调用到 schedule();
        这个又怎么解释?
    */
    spin_lock_irq(&x->wait.lock);
    /**
        真正干活的是这个函数
    */
    timeout = do_wait_for_common(x, timeout, state);
    spin_unlock_irq(&x->wait.lock);
    return timeout;
}

这里写图片描述
下面这幅图是我改动了内核源码打印出来的log

看内核线程

这里写图片描述
这里写图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值