zoukankan      html  css  js  c++  java
  • 内核延时函数【转】

    转自:http://www.mamicode.com/info-detail-514261.html

    1) msleep:实现毫秒级的延时,该延时保证至少延时所设置的延时时间,不会提前超时返回,会让出CPU

    void msleep(unsigned int msecs)
    {
    	unsigned long timeout = msecs_to_jiffies(msecs) + 1;
    
    	while (timeout)
    		timeout = schedule_timeout_uninterruptible(timeout);
    }

    为什么在转换成jiffies时要+1呢?前边我们讲到,该延时要至少保证延时转换的jiffies时间,一个jiffies为10毫秒,比如我们可以查10个数表示一个jiffies,在数到5时调用了msleep,那么显然我们不能在此jiffies到时时返回,违反了至少延时设置的jiffies的原则,因此转换成jiffies+1是比较合适的,内核中也特意做了解释。

    unsigned long msecs_to_jiffies(const unsigned int m)
    {
    	/*
    	 * Negative value, means infinite timeout:
    	 */
    	if ((int)m < 0)
    		return MAX_JIFFY_OFFSET;
    。
    。
    。
    }
    /*
     * Change timeval to jiffies, trying to avoid the
     * most obvious overflows..
     *
     * And some not so obvious.
     *
     * Note that we don't want to return LONG_MAX, because
     * for various timeout reasons we often end up having
     * to wait "jiffies+1" in order to guarantee that we wait
     * at _least_ "jiffies" - so "jiffies+1" had better still
     * be positive.
     */
    #define MAX_JIFFY_OFFSET ((LONG_MAX >> 1)-1)


    2)msleep_interruptible:毫秒级延时,该延时函数有可能被信号打断提前超时,返回剩余的时间,会让出CPU

    unsigned long msleep_interruptible(unsigned int msecs)
    {
    	unsigned long timeout = msecs_to_jiffies(msecs) + 1;
    
    	while (timeout && !signal_pending(current))
    		timeout = schedule_timeout_interruptible(timeout);
    	return jiffies_to_msecs(timeout);
    }
    

    3)ssleep:秒级延时,通过调用msleep实现,会让出CPU

    static inline void ssleep(unsigned int seconds)
    {
    	msleep(seconds * 1000);
    }

    4)usleep_range:该延时函数实现微秒级延时,特别之处在于其可以设定一个超时范围,通过看源代码可以发现此函数设置任务状态为ASK_UNINTERRUPTIBLE,即该延时至少可以保证延时min微秒而不被打断。会让出CPU

    /**
     * usleep_range - Drop in replacement for udelay where wakeup is flexible
     * @min: Minimum time in usecs to sleep
     * @max: Maximum time in usecs to sleep
     */
    void usleep_range(unsigned long min, unsigned long max)
    {
    	__set_current_state(TASK_UNINTERRUPTIBLE);
    	do_usleep_range(min, max);
    }


    5)ndelay:纳秒级延时,不会让出CPU

    static inline void ndelay(unsigned long x)
    {
    	udelay(DIV_ROUND_UP(x, 1000));
    }


    6)udelay:微秒延时,不会让出CPU

    7)mdelay:毫秒级延时,不会让出CPU

    关于延时函数会不会让出CPU,使用时需要注意,一般对延时要求特别精确,使用不让出CPU的延时函数;对延时要求不是特别精确的,可以使用让出CPU的延时函数,为了保证延时时系统不会进入睡眠,通常延时前要加上wakelock锁来组织睡眠。

  • 相关阅读:
    阿里Canal中间件的初步搭建和使用
    深入理解Java String类
    深入理解Java中的String
    Docker 容器数据卷(挂载)
    在docker容器下利用数据卷实现在删除了mysql容器或者镜像的情况下恢复数据
    EFK(Elasticsearch+Filebeat+Kibana)收集容器日志
    Docker 容器日志占用空间过大解决办法
    四种软件架构,看看你属于哪个层次
    Kubernetes 如何只授予某一 Namespace 的访问权限
    Docker实验Docker的网络配置
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/6040372.html
Copyright © 2011-2022 走看看